diff --git a/checkpoint_test.go b/checkpoint_test.go index fd0a7143c..4e853bb41 100644 --- a/checkpoint_test.go +++ b/checkpoint_test.go @@ -3,8 +3,6 @@ package containerd import ( "syscall" "testing" - - "github.com/containerd/containerd/linux/runcopts" ) func TestCheckpointRestore(t *testing.T) { @@ -61,7 +59,7 @@ func TestCheckpointRestore(t *testing.T) { return } - checkpoint, err := task.Checkpoint(ctx, runcopts.WithExit) + checkpoint, err := task.Checkpoint(ctx, WithExit) if err != nil { t.Error(err) return @@ -151,7 +149,7 @@ func TestCheckpointRestoreNewContainer(t *testing.T) { return } - checkpoint, err := task.Checkpoint(ctx, runcopts.WithExit) + checkpoint, err := task.Checkpoint(ctx, WithExit) if err != nil { t.Error(err) return diff --git a/cmd/ctr/checkpoint.go b/cmd/ctr/checkpoint.go index fbed63b44..2bea3169a 100644 --- a/cmd/ctr/checkpoint.go +++ b/cmd/ctr/checkpoint.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/containerd/containerd" - "github.com/containerd/containerd/linux/runcopts" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -41,9 +40,9 @@ var checkpointCommand = cli.Command{ if err != nil { return err } - var opts []containerd.CheckpointOpts + var opts []containerd.CheckpointTaskOpts if context.Bool("exit") { - opts = append(opts, runcopts.WithExit) + opts = append(opts, containerd.WithExit) } checkpoint, err := task.Checkpoint(ctx, opts...) if err != nil { diff --git a/container.go b/container.go index 44e291822..c98039f4d 100644 --- a/container.go +++ b/container.go @@ -13,6 +13,7 @@ import ( "github.com/containerd/containerd/api/services/containers/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/typeurl" ptypes "github.com/gogo/protobuf/types" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -167,7 +168,7 @@ func (c *container) Image(ctx context.Context) (Image, error) { }, nil } -type NewTaskOpts func(context.Context, *Client, *tasks.CreateTaskRequest) error +type NewTaskOpts func(context.Context, *Client, *TaskInfo) error func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...NewTaskOpts) (Task, error) { c.mu.Lock() @@ -197,18 +198,26 @@ func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...Ne }) } } + var info TaskInfo for _, o := range opts { - if err := o(ctx, c.client, request); err != nil { + if err := o(ctx, c.client, &info); err != nil { return nil, err } } + if info.Options != nil { + any, err := typeurl.MarshalAny(info.Options) + if err != nil { + return nil, err + } + request.Options = any + } t := &task{ client: c.client, io: i, id: c.ID(), } - - if request.Checkpoint != nil { + if info.Checkpoint != nil { + request.Checkpoint = info.Checkpoint // we need to defer the create call to start t.deferred = request } else { diff --git a/container_unix.go b/container_unix.go index 30f999aa2..c19aa4955 100644 --- a/container_unix.go +++ b/container_unix.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "github.com/containerd/containerd/api/services/containers/v1" - "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" @@ -84,7 +83,7 @@ func WithCheckpoint(desc v1.Descriptor, rootfsID string) NewContainerOpts { } func WithTaskCheckpoint(desc v1.Descriptor) NewTaskOpts { - return func(ctx context.Context, c *Client, r *tasks.CreateTaskRequest) error { + return func(ctx context.Context, c *Client, info *TaskInfo) error { id := desc.Digest index, err := decodeIndex(ctx, c.ContentStore(), id) if err != nil { @@ -92,7 +91,7 @@ func WithTaskCheckpoint(desc v1.Descriptor) NewTaskOpts { } for _, m := range index.Manifests { if m.MediaType == images.MediaTypeContainerd1Checkpoint { - r.Checkpoint = &types.Descriptor{ + info.Checkpoint = &types.Descriptor{ MediaType: m.MediaType, Size_: m.Size, Digest: m.Digest, diff --git a/linux/runcopts/options.go b/linux/runcopts/options.go deleted file mode 100644 index b45be84cc..000000000 --- a/linux/runcopts/options.go +++ /dev/null @@ -1,14 +0,0 @@ -package runcopts - -import ( - tasks "github.com/containerd/containerd/api/services/tasks/v1" - "github.com/containerd/containerd/typeurl" -) - -func WithExit(r *tasks.CheckpointTaskRequest) error { - a, err := typeurl.MarshalAny(&CheckpointOptions{ - Exit: true, - }) - r.Options = a - return err -} diff --git a/process.go b/process.go index bf5d023ca..caa332017 100644 --- a/process.go +++ b/process.go @@ -89,9 +89,11 @@ func (p *process) CloseIO(ctx context.Context, opts ...IOCloserOpts) error { ContainerID: p.task.id, ExecID: p.id, } + var i IOCloseInfo for _, o := range opts { - o(r) + o(&i) } + r.Stdin = i.Stdin _, err := p.task.client.TaskService().CloseIO(ctx, r) return err } diff --git a/spec_unix.go b/spec_unix.go index d8e07c9c4..e3109fdb0 100644 --- a/spec_unix.go +++ b/spec_unix.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/containerd/containerd/api/services/containers/v1" - "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/images" "github.com/containerd/containerd/typeurl" "github.com/opencontainers/image-spec/specs-go/v1" @@ -285,12 +284,8 @@ func WithSpec(spec *specs.Spec) NewContainerOpts { } func WithResources(resources *specs.LinuxResources) UpdateTaskOpts { - return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error { - any, err := typeurl.MarshalAny(resources) - if err != nil { - return err - } - r.Resources = any + return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error { + r.Resources = resources return nil } } diff --git a/spec_windows.go b/spec_windows.go index ff06fc3cc..709c504c6 100644 --- a/spec_windows.go +++ b/spec_windows.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/containerd/containerd/api/services/containers/v1" - tasks "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/images" "github.com/containerd/containerd/typeurl" "github.com/opencontainers/image-spec/specs-go/v1" @@ -87,12 +86,8 @@ func WithSpec(spec *specs.Spec) NewContainerOpts { } func WithResources(resources *specs.WindowsResources) UpdateTaskOpts { - return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error { - any, err := typeurl.MarshalAny(resources) - if err != nil { - return err - } - r.Resources = any + return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error { + r.Resources = resources return nil } } diff --git a/task.go b/task.go index 2015a6bfb..ff32c4af7 100644 --- a/task.go +++ b/task.go @@ -13,10 +13,13 @@ import ( "github.com/containerd/containerd/api/services/containers/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/api/services/tasks/v1" + "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/linux/runcopts" "github.com/containerd/containerd/rootfs" "github.com/containerd/containerd/runtime" "github.com/containerd/containerd/typeurl" + digest "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" "google.golang.org/grpc" @@ -34,13 +37,27 @@ const ( Pausing TaskStatus = "pausing" ) -type IOCloserOpts func(*tasks.CloseIORequest) +type IOCloseInfo struct { + Stdin bool +} -func WithStdinCloser(r *tasks.CloseIORequest) { +type IOCloserOpts func(*IOCloseInfo) + +func WithStdinCloser(r *IOCloseInfo) { r.Stdin = true } -type CheckpointOpts func(*tasks.CheckpointTaskRequest) error +type CheckpointTaskInfo struct { + ParentCheckpoint digest.Digest + Options interface{} +} + +type CheckpointTaskOpts func(*CheckpointTaskInfo) error + +type TaskInfo struct { + Checkpoint *types.Descriptor + Options interface{} +} type Task interface { Pid() uint32 @@ -56,7 +73,7 @@ type Task interface { CloseIO(context.Context, ...IOCloserOpts) error Resize(ctx context.Context, w, h uint32) error IO() *IO - Checkpoint(context.Context, ...CheckpointOpts) (v1.Descriptor, error) + Checkpoint(context.Context, ...CheckpointTaskOpts) (v1.Descriptor, error) Update(context.Context, ...UpdateTaskOpts) error } @@ -217,9 +234,11 @@ func (t *task) CloseIO(ctx context.Context, opts ...IOCloserOpts) error { r := &tasks.CloseIORequest{ ContainerID: t.id, } + var i IOCloseInfo for _, o := range opts { - o(r) + o(&i) } + r.Stdin = i.Stdin _, err := t.client.TaskService().CloseIO(ctx, r) return err } @@ -237,15 +256,24 @@ func (t *task) Resize(ctx context.Context, w, h uint32) error { return err } -func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointOpts) (d v1.Descriptor, err error) { +func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (d v1.Descriptor, err error) { request := &tasks.CheckpointTaskRequest{ ContainerID: t.id, } + var i CheckpointTaskInfo for _, o := range opts { - if err := o(request); err != nil { + if err := o(&i); err != nil { return d, err } } + request.ParentCheckpoint = i.ParentCheckpoint + if i.Options != nil { + any, err := typeurl.MarshalAny(i.Options) + if err != nil { + return d, err + } + request.Options = any + } // make sure we pause it and resume after all other filesystem operations are completed if err := t.Pause(ctx); err != nil { return d, err @@ -272,17 +300,29 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointOpts) (d v1.Des return t.writeIndex(ctx, &index) } -type UpdateTaskOpts func(context.Context, *Client, *tasks.UpdateTaskRequest) error +type UpdateTaskInfo struct { + Resources interface{} +} + +type UpdateTaskOpts func(context.Context, *Client, *UpdateTaskInfo) error func (t *task) Update(ctx context.Context, opts ...UpdateTaskOpts) error { request := &tasks.UpdateTaskRequest{ ContainerID: t.id, } + var i UpdateTaskInfo for _, o := range opts { - if err := o(ctx, t.client, request); err != nil { + if err := o(ctx, t.client, &i); err != nil { return err } } + if i.Resources != nil { + any, err := typeurl.MarshalAny(i.Resources) + if err != nil { + return err + } + request.Resources = any + } _, err := t.client.TaskService().Update(ctx, request) return err } @@ -359,3 +399,10 @@ func writeContent(ctx context.Context, store content.Store, mediaType, ref strin Size: size, }, nil } + +func WithExit(r *CheckpointTaskInfo) error { + r.Options = &runcopts.CheckpointOptions{ + Exit: true, + } + return nil +}