Runtime v2

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2018-07-09 13:27:52 -04:00
parent 6de11ab973
commit da1b5470cd
78 changed files with 9836 additions and 652 deletions

View File

@@ -231,3 +231,21 @@ func (p *process) Wait(ctx context.Context) (*runtime.Exit, error) {
Timestamp: ea,
}, nil
}
func (p *process) Delete(ctx context.Context) (*runtime.Exit, error) {
ec, ea, err := p.ExitCode()
if err != nil {
return nil, err
}
// If we never started the process close the pipes
if p.Status() == runtime.CreatedStatus {
p.io.Close()
ea = time.Now()
}
p.task.removeProcess(p.id)
return &runtime.Exit{
Pid: p.pid,
Status: ec,
Timestamp: ea,
}, nil
}

View File

@@ -79,9 +79,7 @@ func New(ic *plugin.InitContext) (interface{}, error) {
events: make(chan interface{}, 4096),
publisher: ic.Events,
// TODO(mlaventure): windows needs a stat monitor
monitor: nil,
tasks: runtime.NewTaskList(),
tasks: runtime.NewTaskList(),
}
// Load our existing containers and kill/delete them. We don't support
@@ -100,8 +98,7 @@ type windowsRuntime struct {
publisher events.Publisher
events chan interface{}
monitor runtime.TaskMonitor
tasks *runtime.TaskList
tasks *runtime.TaskList
}
func (r *windowsRuntime) ID() string {
@@ -121,8 +118,8 @@ func (r *windowsRuntime) Create(ctx context.Context, id string, opts runtime.Cre
spec := s.(*runtimespec.Spec)
var createOpts *hcsshimtypes.CreateOptions
if opts.Options != nil {
o, err := typeurl.UnmarshalAny(opts.Options)
if opts.TaskOptions != nil {
o, err := typeurl.UnmarshalAny(opts.TaskOptions)
if err != nil {
return nil, err
}
@@ -152,74 +149,8 @@ func (r *windowsRuntime) Get(ctx context.Context, id string) (runtime.Task, erro
return r.tasks.Get(ctx, id)
}
func (r *windowsRuntime) Tasks(ctx context.Context) ([]runtime.Task, error) {
return r.tasks.GetAll(ctx)
}
func (r *windowsRuntime) Delete(ctx context.Context, t runtime.Task) (*runtime.Exit, error) {
wt, ok := t.(*task)
if !ok {
return nil, errors.Wrap(errdefs.ErrInvalidArgument, "no a windows task")
}
// TODO(mlaventure): stop monitor on this task
var (
err error
state, _ = wt.State(ctx)
)
switch state.Status {
case runtime.StoppedStatus:
fallthrough
case runtime.CreatedStatus:
// if it's stopped or in created state, we need to shutdown the
// container before removing it
if err = wt.stop(ctx); err != nil {
return nil, err
}
default:
return nil, errors.Wrap(errdefs.ErrFailedPrecondition,
"cannot delete a non-stopped task")
}
var rtExit *runtime.Exit
if p := wt.getProcess(t.ID()); p != nil {
ec, ea, err := p.ExitCode()
if err != nil {
return nil, err
}
rtExit = &runtime.Exit{
Pid: wt.pid,
Status: ec,
Timestamp: ea,
}
} else {
rtExit = &runtime.Exit{
Pid: wt.pid,
Status: 255,
Timestamp: time.Now().UTC(),
}
}
wt.cleanup()
r.tasks.Delete(ctx, t.ID())
r.publisher.Publish(ctx,
runtime.TaskDeleteEventTopic,
&eventstypes.TaskDelete{
ContainerID: wt.id,
Pid: wt.pid,
ExitStatus: rtExit.Status,
ExitedAt: rtExit.Timestamp,
})
if err := mount.UnmountAll(wt.rootfs[0].Source, 0); err != nil {
log.G(ctx).WithError(err).WithField("path", wt.rootfs[0].Source).
Warn("failed to unmount rootfs on failure")
}
// We were never started, return failure
return rtExit, nil
func (r *windowsRuntime) Tasks(ctx context.Context, all bool) ([]runtime.Task, error) {
return r.tasks.GetAll(ctx, all)
}
func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, rootfs []mount.Mount, spec *runtimespec.Spec, io runtime.IO, createOpts *hcsshimtypes.CreateOptions) (*task, error) {
@@ -298,6 +229,7 @@ func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, root
pidPool: r.pidPool,
hcsContainer: ctr,
terminateDuration: createOpts.TerminateDuration,
tasks: r.tasks,
}
// Create the new process but don't start it
pconf := newWindowsProcessConfig(t.spec.Process, t.io)

View File

@@ -27,6 +27,7 @@ import (
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/windows/hcsshimtypes"
@@ -55,12 +56,17 @@ type task struct {
pidPool *pidPool
hcsContainer hcsshim.Container
terminateDuration time.Duration
tasks *runtime.TaskList
}
func (t *task) ID() string {
return t.id
}
func (t *task) Namespace() string {
return t.namespace
}
func (t *task) State(ctx context.Context) (runtime.State, error) {
var (
status runtime.Status
@@ -271,33 +277,6 @@ func (t *task) Checkpoint(_ context.Context, _ string, _ *types.Any) error {
return errors.Wrap(errdefs.ErrUnavailable, "not supported")
}
func (t *task) DeleteProcess(ctx context.Context, id string) (*runtime.Exit, error) {
if id == t.id {
return nil, errors.Wrapf(errdefs.ErrInvalidArgument,
"cannot delete init process")
}
if p := t.getProcess(id); p != nil {
ec, ea, err := p.ExitCode()
if err != nil {
return nil, err
}
// If we never started the process close the pipes
if p.Status() == runtime.CreatedStatus {
p.io.Close()
ea = time.Now()
}
t.removeProcess(id)
return &runtime.Exit{
Pid: p.pid,
Status: ec,
Timestamp: ea,
}, nil
}
return nil, errors.Wrapf(errdefs.ErrNotFound, "no such process %s", id)
}
func (t *task) Update(ctx context.Context, resources *types.Any) error {
return errors.Wrap(errdefs.ErrUnavailable, "not supported")
}
@@ -311,7 +290,7 @@ func (t *task) Process(ctx context.Context, id string) (p runtime.Process, err e
return p, err
}
func (t *task) Metrics(ctx context.Context) (interface{}, error) {
func (t *task) Stats(ctx context.Context) (*types.Any, error) {
return nil, errors.Wrap(errdefs.ErrUnavailable, "not supported")
}
@@ -323,6 +302,64 @@ func (t *task) Wait(ctx context.Context) (*runtime.Exit, error) {
return p.Wait(ctx)
}
func (t *task) Delete(ctx context.Context) (*runtime.Exit, error) {
var (
err error
state, _ = t.State(ctx)
)
switch state.Status {
case runtime.StoppedStatus:
fallthrough
case runtime.CreatedStatus:
// if it's stopped or in created state, we need to shutdown the
// container before removing it
if err = t.stop(ctx); err != nil {
return nil, err
}
default:
return nil, errors.Wrap(errdefs.ErrFailedPrecondition,
"cannot delete a non-stopped task")
}
var rtExit *runtime.Exit
if p := t.getProcess(t.ID()); p != nil {
ec, ea, err := p.ExitCode()
if err != nil {
return nil, err
}
rtExit = &runtime.Exit{
Pid: t.pid,
Status: ec,
Timestamp: ea,
}
} else {
rtExit = &runtime.Exit{
Pid: t.pid,
Status: 255,
Timestamp: time.Now().UTC(),
}
}
t.cleanup()
t.tasks.Delete(ctx, t.ID())
t.publisher.Publish(ctx,
runtime.TaskDeleteEventTopic,
&eventstypes.TaskDelete{
ContainerID: t.id,
Pid: t.pid,
ExitStatus: rtExit.Status,
ExitedAt: rtExit.Timestamp,
})
if err := mount.UnmountAll(t.rootfs[0].Source, 0); err != nil {
log.G(ctx).WithError(err).WithField("path", t.rootfs[0].Source).
Warn("failed to unmount rootfs on failure")
}
// We were never started, return failure
return rtExit, nil
}
func (t *task) newProcess(ctx context.Context, id string, conf *hcsshim.ProcessConfig, pset *pipeSet) (*process, error) {
var (
err error