diff --git a/benchmark_test.go b/benchmark_test.go index 451c482e8f98..c3aca91ec7f7 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -31,7 +31,7 @@ func BenchmarkContainerCreate(b *testing.B) { var containers []Container defer func() { for _, c := range containers { - if err := c.Delete(ctx); err != nil { + if err := c.Delete(ctx, WithRootFSDeletion); err != nil { b.Error(err) } } @@ -77,7 +77,7 @@ func BenchmarkContainerStart(b *testing.B) { var containers []Container defer func() { for _, c := range containers { - if err := c.Delete(ctx); err != nil { + if err := c.Delete(ctx, WithRootFSDeletion); err != nil { b.Error(err) } } diff --git a/checkpoint_test.go b/checkpoint_test.go index e9451a6632b3..5222fd72e637 100644 --- a/checkpoint_test.go +++ b/checkpoint_test.go @@ -39,7 +39,7 @@ func TestCheckpointRestore(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, empty()) if err != nil { @@ -132,7 +132,7 @@ func TestCheckpointRestoreNewContainer(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, empty()) if err != nil { @@ -167,7 +167,7 @@ func TestCheckpointRestoreNewContainer(t *testing.T) { t.Error(err) return } - if err := container.Delete(ctx); err != nil { + if err := container.Delete(ctx, WithRootFSDeletion); err != nil { t.Error(err) return } diff --git a/container.go b/container.go index dc542975e877..73e487fcd8ec 100644 --- a/container.go +++ b/container.go @@ -23,10 +23,12 @@ var ( ErrProcessExited = errors.New("process already exited") ) +type DeleteOpts func(context.Context, *Client, containers.Container) error + type Container interface { ID() string Proto() containers.Container - Delete(context.Context) error + Delete(context.Context, ...DeleteOpts) error NewTask(context.Context, IOCreation, ...NewTaskOpts) (Task, error) Spec() (*specs.Spec, error) Task(context.Context, IOAttach) (Task, error) @@ -67,16 +69,24 @@ func (c *container) Spec() (*specs.Spec, error) { return &s, nil } +// WithRootFSDeletion deletes the rootfs allocated for the container +func WithRootFSDeletion(ctx context.Context, client *Client, c containers.Container) error { + if c.RootFS != "" { + return client.SnapshotService().Remove(ctx, c.RootFS) + } + return nil +} + // Delete deletes an existing container // an error is returned if the container has running tasks -func (c *container) Delete(ctx context.Context) (err error) { +func (c *container) Delete(ctx context.Context, opts ...DeleteOpts) (err error) { if _, err := c.Task(ctx, nil); err == nil { return ErrDeleteRunningTask } - // TODO: should the client be the one removing resources attached - // to the container at the moment before we have GC? - if c.c.RootFS != "" { - err = c.client.SnapshotService().Remove(ctx, c.c.RootFS) + for _, o := range opts { + if err := o(ctx, c.client, c.c); err != nil { + return err + } } if _, cerr := c.client.ContainerService().Delete(ctx, &containers.DeleteContainerRequest{ ID: c.c.ID, diff --git a/container_test.go b/container_test.go index bcbb35a7763a..ccf8150997e5 100644 --- a/container_test.go +++ b/container_test.go @@ -109,7 +109,7 @@ func TestContainerStart(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, Stdio) if err != nil { @@ -180,7 +180,7 @@ func TestContainerOutput(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) stdout := bytes.NewBuffer(nil) task, err := container.NewTask(ctx, NewIO(bytes.NewBuffer(nil), stdout, bytes.NewBuffer(nil))) @@ -252,7 +252,7 @@ func TestContainerExec(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, empty()) if err != nil { @@ -347,7 +347,7 @@ func TestContainerProcesses(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, empty()) if err != nil { @@ -420,7 +420,7 @@ func TestContainerCloseIO(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) const expected = "hello\n" stdout := bytes.NewBuffer(nil) @@ -504,7 +504,7 @@ func TestContainerAttach(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) expected := "hello\n" stdout := bytes.NewBuffer(nil) @@ -629,7 +629,7 @@ func TestDeleteRunningContainer(t *testing.T) { t.Error(err) return } - defer container.Delete(ctx) + defer container.Delete(ctx, WithRootFSDeletion) task, err := container.NewTask(ctx, empty()) if err != nil { @@ -652,7 +652,7 @@ func TestDeleteRunningContainer(t *testing.T) { return } - err = container.Delete(ctx) + err = container.Delete(ctx, WithRootFSDeletion) if err == nil { t.Error("delete did not error with running task") }