2017-09-05 14:29:17 +00:00
|
|
|
package libpod
|
2017-08-11 16:42:25 +00:00
|
|
|
|
|
|
|
import (
|
2017-09-06 15:15:11 +00:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/docker/docker/pkg/stringid"
|
2017-09-11 15:27:40 +00:00
|
|
|
"github.com/pkg/errors"
|
2017-08-11 16:42:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Pod represents a group of containers that may share namespaces
|
|
|
|
type Pod struct {
|
2017-09-06 15:15:11 +00:00
|
|
|
id string
|
|
|
|
name string
|
|
|
|
|
|
|
|
containers map[string]*Container
|
|
|
|
|
|
|
|
valid bool
|
|
|
|
lock sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
// ID retrieves the pod's ID
|
|
|
|
func (p *Pod) ID() string {
|
|
|
|
return p.id
|
|
|
|
}
|
|
|
|
|
|
|
|
// Name retrieves the pod's name
|
|
|
|
func (p *Pod) Name() string {
|
|
|
|
return p.name
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates a new pod
|
|
|
|
func newPod() (*Pod, error) {
|
|
|
|
pod := new(Pod)
|
|
|
|
pod.id = stringid.GenerateNonCryptoID()
|
|
|
|
pod.name = pod.id // TODO generate human-readable name here
|
|
|
|
|
|
|
|
pod.containers = make(map[string]*Container)
|
|
|
|
|
|
|
|
return pod, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adds a container to the pod
|
|
|
|
// Does not check that container's pod ID is set correctly, or attempt to set
|
|
|
|
// pod ID after adding
|
|
|
|
func (p *Pod) addContainer(ctr *Container) error {
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
2017-10-25 15:47:00 +00:00
|
|
|
ctr.lock.Lock()
|
|
|
|
defer ctr.lock.Unlock()
|
2017-09-06 15:15:11 +00:00
|
|
|
|
|
|
|
if !p.valid {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrPodRemoved
|
2017-09-06 15:15:11 +00:00
|
|
|
}
|
|
|
|
|
2017-10-25 15:47:00 +00:00
|
|
|
if !ctr.valid {
|
|
|
|
return ErrCtrRemoved
|
|
|
|
}
|
|
|
|
|
2017-10-10 20:33:20 +00:00
|
|
|
if _, ok := p.containers[ctr.ID()]; ok {
|
|
|
|
return errors.Wrapf(ErrCtrExists, "container with ID %s already exists in pod %s", ctr.ID(), p.id)
|
2017-09-06 15:15:11 +00:00
|
|
|
}
|
|
|
|
|
2017-10-10 20:33:20 +00:00
|
|
|
p.containers[ctr.ID()] = ctr
|
2017-09-06 15:15:11 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Removes a container from the pod
|
|
|
|
// Does not perform any checks on the container
|
|
|
|
func (p *Pod) removeContainer(ctr *Container) error {
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
|
|
|
|
if !p.valid {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrPodRemoved
|
2017-09-06 15:15:11 +00:00
|
|
|
}
|
|
|
|
|
2017-10-10 20:33:20 +00:00
|
|
|
if _, ok := p.containers[ctr.ID()]; !ok {
|
|
|
|
return errors.Wrapf(ErrNoSuchCtr, "no container with id %s in pod %s", ctr.ID(), p.id)
|
2017-09-06 15:15:11 +00:00
|
|
|
}
|
|
|
|
|
2017-10-10 20:33:20 +00:00
|
|
|
delete(p.containers, ctr.ID())
|
2017-09-06 15:15:11 +00:00
|
|
|
|
|
|
|
return nil
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start starts all containers within a pod that are not already running
|
|
|
|
func (p *Pod) Start() error {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrNotImplemented
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Stop stops all containers within a pod that are not already stopped
|
|
|
|
func (p *Pod) Stop() error {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrNotImplemented
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Kill sends a signal to all running containers within a pod
|
|
|
|
func (p *Pod) Kill(signal uint) error {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrNotImplemented
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
2017-09-14 14:51:07 +00:00
|
|
|
// HasContainer checks if a container is present in the pod
|
|
|
|
func (p *Pod) HasContainer(id string) (bool, error) {
|
|
|
|
p.lock.RLock()
|
|
|
|
defer p.lock.RUnlock()
|
|
|
|
|
|
|
|
if !p.valid {
|
|
|
|
return false, ErrPodRemoved
|
|
|
|
}
|
|
|
|
|
|
|
|
_, ok := p.containers[id]
|
|
|
|
|
|
|
|
return ok, nil
|
|
|
|
}
|
|
|
|
|
2017-08-11 16:42:25 +00:00
|
|
|
// GetContainers retrieves the containers in the pod
|
2017-09-05 14:29:17 +00:00
|
|
|
func (p *Pod) GetContainers() ([]*Container, error) {
|
2017-09-06 15:15:11 +00:00
|
|
|
p.lock.RLock()
|
|
|
|
defer p.lock.RUnlock()
|
|
|
|
|
|
|
|
if !p.valid {
|
2017-09-11 15:27:40 +00:00
|
|
|
return nil, ErrPodRemoved
|
2017-09-06 15:15:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ctrs := make([]*Container, 0, len(p.containers))
|
|
|
|
for _, ctr := range p.containers {
|
|
|
|
ctrs = append(ctrs, ctr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctrs, nil
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Status gets the status of all containers in the pod
|
|
|
|
// TODO This should return a summary of the states of all containers in the pod
|
|
|
|
func (p *Pod) Status() error {
|
2017-09-11 15:27:40 +00:00
|
|
|
return ErrNotImplemented
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|