diff --git a/container_test.go b/container_test.go index d7254a2d0..00b9c43b0 100644 --- a/container_test.go +++ b/container_test.go @@ -289,3 +289,74 @@ func TestContainerExec(t *testing.T) { } <-finished } + +func TestContainerProcesses(t *testing.T) { + if testing.Short() { + t.Skip() + } + client, err := New(address) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + var ( + ctx = context.Background() + id = "ContainerProcesses" + ) + image, err := client.GetImage(ctx, testImage) + if err != nil { + t.Error(err) + return + } + spec, err := GenerateSpec(WithImageConfig(ctx, image), WithProcessArgs("sleep", "100")) + if err != nil { + t.Error(err) + return + } + container, err := client.NewContainer(ctx, id, spec, WithImage(image), WithNewRootFS(id, image)) + if err != nil { + t.Error(err) + return + } + defer container.Delete(ctx) + + task, err := container.NewTask(ctx, empty()) + if err != nil { + t.Error(err) + return + } + defer task.Delete(ctx) + + statusC := make(chan uint32, 1) + go func() { + status, err := task.Wait(ctx) + if err != nil { + t.Error(err) + } + statusC <- status + }() + + pid := task.Pid() + if pid <= 0 { + t.Errorf("invalid task pid %d", pid) + } + processes, err := task.Processes(ctx) + if err != nil { + t.Error(err) + return + } + if l := len(processes); l != 1 { + t.Errorf("expected 1 process but received %d", l) + } + if len(processes) > 0 { + actual := processes[0] + if pid != actual { + t.Errorf("expected pid %d but received %d", pid, actual) + } + } + if err := task.Kill(ctx, syscall.SIGKILL); err != nil { + t.Error(err) + } + <-statusC +} diff --git a/process.go b/process.go index 8aa31585e..6a1fb552c 100644 --- a/process.go +++ b/process.go @@ -26,10 +26,13 @@ type process struct { spec *specs.Process } +// Pid returns the pid of the process +// The pid is not set until start is called and returns func (p *process) Pid() uint32 { return p.pid } +// Start starts the exec process func (p *process) Start(ctx context.Context) error { data, err := json.Marshal(p.spec) if err != nil { diff --git a/task.go b/task.go index 5172da99d..ba5489a64 100644 --- a/task.go +++ b/task.go @@ -31,6 +31,7 @@ type Task interface { Status(context.Context) (TaskStatus, error) Wait(context.Context) (uint32, error) Exec(context.Context, *specs.Process, IOCreation) (Process, error) + Processes(context.Context) ([]uint32, error) } type Process interface { @@ -143,3 +144,17 @@ func (t *task) Exec(ctx context.Context, spec *specs.Process, ioCreate IOCreatio pidSync: make(chan struct{}), }, nil } + +func (t *task) Processes(ctx context.Context) ([]uint32, error) { + response, err := t.client.TaskService().Processes(ctx, &execution.ProcessesRequest{ + ContainerID: t.containerID, + }) + if err != nil { + return nil, err + } + var out []uint32 + for _, p := range response.Processes { + out = append(out, p.Pid) + } + return out, nil +}