containerd/supervisor.go

101 lines
2.2 KiB
Go

package containerd
import (
"sync"
"golang.org/x/net/context"
)
func NewSupervisor(ctx context.Context, runtimes map[string]Runtime) (*Supervisor, error) {
c, err := newCollector(ctx, runtimes)
if err != nil {
return nil, err
}
s := &Supervisor{
containers: make(map[string]Container),
runtimes: runtimes,
collector: c,
}
for _, r := range runtimes {
containers, err := r.Containers()
if err != nil {
return nil, err
}
for _, c := range containers {
s.containers[c.Info().ID] = c
}
}
return s, nil
}
// Supervisor supervises containers and events from multiple runtimes
type Supervisor struct {
mu sync.Mutex
containers map[string]Container
runtimes map[string]Runtime
collector *collector
}
// ForwardEvents is a blocking method that will forward all events from the supervisor
// to the EventWriter provided by the caller
func (s *Supervisor) ForwardEvents(w EventWriter) error {
return s.collector.forward(w)
}
// Create creates a new container with the provided runtime
func (s *Supervisor) Create(ctx context.Context, id, runtime string, opts CreateOpts) (Container, error) {
r, ok := s.runtimes[runtime]
if !ok {
return nil, ErrUnknownRuntime
}
// check to make sure the container's id is unique across the entire system
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.containers[id]; ok {
return nil, ErrContainerExists
}
c, err := r.Create(ctx, id, opts)
if err != nil {
return nil, err
}
s.containers[c.Info().ID] = c
return c, nil
}
// Delete deletes the container
func (s *Supervisor) Delete(ctx context.Context, id string) error {
s.mu.Lock()
defer s.mu.Unlock()
c, ok := s.containers[id]
if !ok {
return ErrContainerNotExist
}
err := s.runtimes[c.Info().Runtime].Delete(ctx, c)
if err != nil {
return err
}
delete(s.containers, id)
return nil
}
// Containers returns all the containers for the supervisor
func (s *Supervisor) Containers() (o []Container) {
s.mu.Lock()
defer s.mu.Unlock()
for _, c := range s.containers {
o = append(o, c)
}
return o
}
func (s *Supervisor) Get(id string) (Container, error) {
s.mu.Lock()
c, ok := s.containers[id]
s.mu.Unlock()
if !ok {
return nil, ErrContainerNotExist
}
return c, nil
}