This removes the RuntimeEvent super proto with enums into separate runtime event protos to be inline with the other events that are output by containerd. This also renames the runtime events into Task* events. Fixes #1071 Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
		
			
				
	
	
		
			172 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build windows
 | 
						|
 | 
						|
package windows
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"sync"
 | 
						|
 | 
						|
	"github.com/containerd/containerd/log"
 | 
						|
	"github.com/containerd/containerd/plugin"
 | 
						|
	"github.com/containerd/containerd/runtime"
 | 
						|
	"github.com/containerd/containerd/typeurl"
 | 
						|
	"github.com/containerd/containerd/windows/hcs"
 | 
						|
	"github.com/containerd/containerd/windows/pid"
 | 
						|
	specs "github.com/opencontainers/runtime-spec/specs-go"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	runtimeName = "windows"
 | 
						|
	owner       = "containerd"
 | 
						|
)
 | 
						|
 | 
						|
var _ = (runtime.Runtime)(&Runtime{})
 | 
						|
 | 
						|
func init() {
 | 
						|
	plugin.Register(&plugin.Registration{
 | 
						|
		ID:   "windows",
 | 
						|
		Type: plugin.RuntimePlugin,
 | 
						|
		Init: New,
 | 
						|
	})
 | 
						|
	typeurl.Register(&RuntimeSpec{}, "windows/Spec")
 | 
						|
}
 | 
						|
 | 
						|
func New(ic *plugin.InitContext) (interface{}, error) {
 | 
						|
	rootDir := filepath.Join(ic.Root)
 | 
						|
	if err := os.MkdirAll(rootDir, 0755); err != nil {
 | 
						|
		return nil, errors.Wrapf(err, "could not create state directory at %s", rootDir)
 | 
						|
	}
 | 
						|
 | 
						|
	c, cancel := context.WithCancel(ic.Context)
 | 
						|
	r := &Runtime{
 | 
						|
		pidPool:       pid.NewPool(),
 | 
						|
		containers:    make(map[string]*container),
 | 
						|
		events:        make(chan interface{}, 2048),
 | 
						|
		eventsContext: c,
 | 
						|
		eventsCancel:  cancel,
 | 
						|
		rootDir:       rootDir,
 | 
						|
		hcs:           hcs.New(owner, rootDir),
 | 
						|
	}
 | 
						|
 | 
						|
	// Terminate all previous container that we may have started. We don't
 | 
						|
	// support restoring containers
 | 
						|
	ctrs, err := loadContainers(ic.Context, r.hcs)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	for _, c := range ctrs {
 | 
						|
		c.ctr.Delete(ic.Context)
 | 
						|
		//r.sendEvent(c.ctr.ID(), events.RuntimeEvent_EXIT, c.ctr.Pid(), 255, time.Time{})
 | 
						|
	}
 | 
						|
 | 
						|
	// Try to delete the old state dir and recreate it
 | 
						|
	stateDir := filepath.Join(ic.Root, "state")
 | 
						|
	if err := os.RemoveAll(stateDir); err != nil {
 | 
						|
		log.G(c).WithError(err).Warnf("failed to cleanup old state directory at %s", stateDir)
 | 
						|
	}
 | 
						|
	if err := os.MkdirAll(stateDir, 0755); err != nil {
 | 
						|
		return nil, errors.Wrapf(err, "could not create state directory at %s", stateDir)
 | 
						|
	}
 | 
						|
	r.stateDir = stateDir
 | 
						|
 | 
						|
	return r, nil
 | 
						|
}
 | 
						|
 | 
						|
type Runtime struct {
 | 
						|
	sync.Mutex
 | 
						|
 | 
						|
	rootDir  string
 | 
						|
	stateDir string
 | 
						|
	pidPool  *pid.Pool
 | 
						|
 | 
						|
	hcs *hcs.HCS
 | 
						|
 | 
						|
	containers map[string]*container
 | 
						|
 | 
						|
	events        chan interface{}
 | 
						|
	eventsContext context.Context
 | 
						|
	eventsCancel  func()
 | 
						|
}
 | 
						|
 | 
						|
type RuntimeSpec struct {
 | 
						|
	// Spec is the OCI spec
 | 
						|
	OCISpec specs.Spec
 | 
						|
 | 
						|
	// HCS specific options
 | 
						|
	hcs.Configuration
 | 
						|
}
 | 
						|
 | 
						|
func (r *Runtime) ID() string {
 | 
						|
	return fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtimeName)
 | 
						|
}
 | 
						|
 | 
						|
func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts) (runtime.Task, error) {
 | 
						|
	v, err := typeurl.UnmarshalAny(opts.Spec)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	rtSpec := v.(*RuntimeSpec)
 | 
						|
	ctr, err := newContainer(ctx, r.hcs, id, rtSpec, opts.IO)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	r.Lock()
 | 
						|
	r.containers[id] = ctr
 | 
						|
	r.Unlock()
 | 
						|
 | 
						|
	return ctr, nil
 | 
						|
}
 | 
						|
 | 
						|
func (r *Runtime) Delete(ctx context.Context, c runtime.Task) (*runtime.Exit, error) {
 | 
						|
	wc, ok := c.(*container)
 | 
						|
	if !ok {
 | 
						|
		return nil, fmt.Errorf("container cannot be cast as *windows.container")
 | 
						|
	}
 | 
						|
	ec, err := wc.ctr.ExitCode()
 | 
						|
	if err != nil {
 | 
						|
		log.G(ctx).WithError(err).Errorf("failed to retrieve exit code for container %s", wc.ctr.ID())
 | 
						|
	}
 | 
						|
 | 
						|
	wc.ctr.Delete(ctx)
 | 
						|
 | 
						|
	r.Lock()
 | 
						|
	delete(r.containers, wc.ctr.ID())
 | 
						|
	r.Unlock()
 | 
						|
 | 
						|
	return &runtime.Exit{
 | 
						|
		Status:    ec,
 | 
						|
		Timestamp: wc.ctr.Processes()[0].ExitedAt(),
 | 
						|
	}, nil
 | 
						|
}
 | 
						|
 | 
						|
func (r *Runtime) Tasks(ctx context.Context) ([]runtime.Task, error) {
 | 
						|
	r.Lock()
 | 
						|
	defer r.Unlock()
 | 
						|
	list := make([]runtime.Task, len(r.containers))
 | 
						|
	for _, c := range r.containers {
 | 
						|
		select {
 | 
						|
		case <-ctx.Done():
 | 
						|
			return nil, ctx.Err()
 | 
						|
		default:
 | 
						|
			list = append(list, c)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return list, nil
 | 
						|
}
 | 
						|
 | 
						|
func (r *Runtime) Get(ctx context.Context, id string) (runtime.Task, error) {
 | 
						|
	r.Lock()
 | 
						|
	defer r.Unlock()
 | 
						|
	c, ok := r.containers[id]
 | 
						|
	if !ok {
 | 
						|
		return nil, fmt.Errorf("container %s does not exit", id)
 | 
						|
	}
 | 
						|
	return c, nil
 | 
						|
}
 |