diff --git a/container.go b/container.go index 88898cc174ae..2073d40b45d6 100644 --- a/container.go +++ b/container.go @@ -229,7 +229,9 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N }) } } - var info TaskInfo + info := TaskInfo{ + runtime: r.Runtime.Name, + } for _, o := range opts { if err := o(ctx, c.client, &info); err != nil { return nil, err diff --git a/container_checkpoint_test.go b/container_checkpoint_test.go index be66d0e15efa..68d3493f327e 100644 --- a/container_checkpoint_test.go +++ b/container_checkpoint_test.go @@ -461,7 +461,7 @@ func TestCRWithImagePath(t *testing.T) { defer os.RemoveAll(crDir) imagePath := filepath.Join(crDir, "cr") // checkpoint task - if _, err := task.Checkpoint(ctx, WithCheckpointImagePath(client.runtime, imagePath)); err != nil { + if _, err := task.Checkpoint(ctx, WithCheckpointImagePath(imagePath)); err != nil { t.Fatal(err) } @@ -485,7 +485,7 @@ func TestCRWithImagePath(t *testing.T) { } defer ncontainer.Delete(ctx, WithSnapshotCleanup) - ntask, err := ncontainer.NewTask(ctx, empty(), WithRestoreImagePath(client.runtime, imagePath)) + ntask, err := ncontainer.NewTask(ctx, empty(), WithRestoreImagePath(imagePath)) if err != nil { t.Fatal(err) } diff --git a/task.go b/task.go index 8d281dc1081b..c81aa37f7b7c 100644 --- a/task.go +++ b/task.go @@ -43,7 +43,7 @@ import ( google_protobuf "github.com/gogo/protobuf/types" digest "github.com/opencontainers/go-digest" is "github.com/opencontainers/image-spec/specs-go" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -117,6 +117,13 @@ type CheckpointTaskInfo struct { ParentCheckpoint digest.Digest // Options hold runtime specific settings for checkpointing a task Options interface{} + + runtime string +} + +// Runtime name for the container +func (i *CheckpointTaskInfo) Runtime() string { + return i.runtime } // CheckpointTaskOpts allows the caller to set checkpoint options @@ -131,6 +138,12 @@ type TaskInfo struct { RootFS []mount.Mount // Options hold runtime specific settings for task creation Options interface{} + runtime string +} + +// Runtime name for the container +func (i *TaskInfo) Runtime() string { + return i.runtime } // Task is the executable object within containerd @@ -401,11 +414,17 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag return nil, err } defer done(ctx) + cr, err := t.client.ContainerService().Get(ctx, t.id) + if err != nil { + return nil, err + } request := &tasks.CheckpointTaskRequest{ ContainerID: t.id, } - var i CheckpointTaskInfo + i := CheckpointTaskInfo{ + runtime: cr.Runtime.Name, + } for _, o := range opts { if err := o(&i); err != nil { return nil, err @@ -428,10 +447,6 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag return nil, err } defer t.Resume(ctx) - cr, err := t.client.ContainerService().Get(ctx, t.id) - if err != nil { - return nil, err - } index := v1.Index{ Versioned: is.Versioned{ SchemaVersion: 2, diff --git a/task_opts.go b/task_opts.go index 4619e2c0e40a..c0e98b30ba70 100644 --- a/task_opts.go +++ b/task_opts.go @@ -92,9 +92,9 @@ func WithCheckpointName(name string) CheckpointTaskOpts { } // WithCheckpointImagePath sets image path for checkpoint option -func WithCheckpointImagePath(rt, path string) CheckpointTaskOpts { +func WithCheckpointImagePath(path string) CheckpointTaskOpts { return func(r *CheckpointTaskInfo) error { - if CheckRuntime(rt, "io.containerd.runc") { + if CheckRuntime(r.Runtime(), "io.containerd.runc") { if r.Options == nil { r.Options = &options.CheckpointOptions{} } @@ -118,9 +118,9 @@ func WithCheckpointImagePath(rt, path string) CheckpointTaskOpts { } // WithRestoreImagePath sets image path for create option -func WithRestoreImagePath(rt, path string) NewTaskOpts { +func WithRestoreImagePath(path string) NewTaskOpts { return func(ctx context.Context, c *Client, ti *TaskInfo) error { - if CheckRuntime(rt, "io.containerd.runc") { + if CheckRuntime(ti.Runtime(), "io.containerd.runc") { if ti.Options == nil { ti.Options = &options.Options{} } diff --git a/task_opts_unix.go b/task_opts_unix.go index f8652be3bc69..d3b51a76d1de 100644 --- a/task_opts_unix.go +++ b/task_opts_unix.go @@ -22,36 +22,58 @@ import ( "context" "github.com/containerd/containerd/runtime/linux/runctypes" + "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/pkg/errors" ) // WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage. // There is an upper limit on the number of keyrings in a linux system func WithNoNewKeyring(ctx context.Context, c *Client, ti *TaskInfo) error { - if ti.Options == nil { - ti.Options = &runctypes.CreateOptions{} - } - opts, ok := ti.Options.(*runctypes.CreateOptions) - if !ok { - return errors.New("could not cast TaskInfo Options to CreateOptions") + if CheckRuntime(ti.Runtime(), "io.containerd.runc") { + if ti.Options == nil { + ti.Options = &options.Options{} + } + opts, ok := ti.Options.(*options.Options) + if !ok { + return errors.New("invalid v2 shim create options format") + } + opts.NoNewKeyring = true + } else { + if ti.Options == nil { + ti.Options = &runctypes.CreateOptions{} + } + opts, ok := ti.Options.(*runctypes.CreateOptions) + if !ok { + return errors.New("could not cast TaskInfo Options to CreateOptions") + } + opts.NoNewKeyring = true } - - opts.NoNewKeyring = true return nil } // WithNoPivotRoot instructs the runtime not to you pivot_root -func WithNoPivotRoot(_ context.Context, _ *Client, info *TaskInfo) error { - if info.Options == nil { - info.Options = &runctypes.CreateOptions{ - NoPivotRoot: true, +func WithNoPivotRoot(_ context.Context, _ *Client, ti *TaskInfo) error { + if CheckRuntime(ti.Runtime(), "io.containerd.runc") { + if ti.Options == nil { + ti.Options = &options.Options{} } - return nil - } - opts, ok := info.Options.(*runctypes.CreateOptions) - if !ok { - return errors.New("invalid options type, expected runctypes.CreateOptions") + opts, ok := ti.Options.(*options.Options) + if !ok { + return errors.New("invalid v2 shim create options format") + } + opts.NoPivotRoot = true + } else { + if ti.Options == nil { + ti.Options = &runctypes.CreateOptions{ + NoPivotRoot: true, + } + return nil + } + opts, ok := ti.Options.(*runctypes.CreateOptions) + if !ok { + return errors.New("invalid options type, expected runctypes.CreateOptions") + } + opts.NoPivotRoot = true } - opts.NoPivotRoot = true return nil }