diff --git a/container.go b/container.go index a893364c5..8384a481f 100644 --- a/container.go +++ b/container.go @@ -290,6 +290,7 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N client: c.client, io: i, id: c.id, + c: c, } if info.Checkpoint != nil { request.Checkpoint = info.Checkpoint @@ -407,6 +408,7 @@ func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, er io: i, id: response.Process.ID, pid: response.Process.Pid, + c: c, } return t, nil } diff --git a/container_linux_test.go b/container_linux_test.go index d9547f2c2..25e3199c2 100644 --- a/container_linux_test.go +++ b/container_linux_test.go @@ -1903,3 +1903,73 @@ func TestShimOOMScore(t *testing.T) { <-statusC } + +func TestTaskSpec(t *testing.T) { + t.Parallel() + + client, err := newClient(t, address) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + var ( + image Image + ctx, cancel = testContext(t) + id = t.Name() + ) + defer cancel() + + image, err = client.GetImage(ctx, testImage) + if err != nil { + t.Fatal(err) + } + + container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), longCommand)) + if err != nil { + t.Fatal(err) + } + defer container.Delete(ctx, WithSnapshotCleanup) + + task, err := container.NewTask(ctx, empty()) + if err != nil { + t.Fatal(err) + } + defer task.Delete(ctx) + + statusC, err := task.Wait(ctx) + if err != nil { + t.Fatal(err) + } + + spec, err := task.Spec(ctx) + if err != nil { + t.Fatal(err) + } + if spec == nil { + t.Fatal("spec from task is nil") + } + direct, err := newDirectIO(ctx, false) + if err != nil { + t.Fatal(err) + } + defer direct.Delete() + + lt, err := container.Task(ctx, direct.IOAttach) + if err != nil { + t.Fatal(err) + } + + spec, err = lt.Spec(ctx) + if err != nil { + t.Fatal(err) + } + if spec == nil { + t.Fatal("spec from loaded task is nil") + } + + if err := task.Kill(ctx, syscall.SIGKILL); err != nil { + t.Fatal(err) + } + <-statusC +} diff --git a/task.go b/task.go index a0c1dcd5b..ae966ffc4 100644 --- a/task.go +++ b/task.go @@ -35,6 +35,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/oci" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/rootfs" "github.com/containerd/containerd/runtime/linux/runctypes" @@ -175,18 +176,26 @@ type Task interface { // For the built in Linux runtime, github.com/containerd/cgroups.Metrics // are returned in protobuf format Metrics(context.Context) (*types.Metric, error) + // Spec returns the current OCI specification for the task + Spec(context.Context) (*oci.Spec, error) } var _ = (Task)(&task{}) type task struct { client *Client + c Container io cio.IO id string pid uint32 } +// Spec returns the current OCI specification for the task +func (t *task) Spec(ctx context.Context) (*oci.Spec, error) { + return t.c.Spec(ctx) +} + // ID of the task func (t *task) ID() string { return t.id