101 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			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
 | 
						|
}
 |