From 98187b2f624696a9677b3357760148ac856d48ba Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Thu, 29 Apr 2021 21:54:54 +0200 Subject: [PATCH] down --volume to remove volume Signed-off-by: Nicolas De Loof --- local/compose/down.go | 29 +++++++++++++++++++++++++++++ local/compose/down_test.go | 25 +++++++++++++++++++++++-- local/e2e/compose/volumes_test.go | 6 ++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/local/compose/down.go b/local/compose/down.go index 98184733c..b3929b030 100644 --- a/local/compose/down.go +++ b/local/compose/down.go @@ -98,6 +98,20 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c } } + if options.Volumes { + networks, err := s.apiClient.VolumeList(ctx, filters.NewArgs(projectFilter(projectName))) + if err != nil { + return err + } + for _, vol := range networks.Volumes { + id := vol.Name + eg.Go(func() error { + resourceToRemove = true + return s.removeVolume(ctx, id, w) + }) + } + } + if !resourceToRemove { w.Event(progress.NewEvent(projectName, progress.Done, "Warning: No resource found to remove")) } @@ -134,6 +148,21 @@ func (s *composeService) removeImage(ctx context.Context, image string, w progre return err } +func (s *composeService) removeVolume(ctx context.Context, id string, w progress.Writer) error { + resource := fmt.Sprintf("Volume %s", id) + w.Event(progress.NewEvent(resource, progress.Working, "Removing")) + err := s.apiClient.VolumeRemove(ctx, id, true) + if err == nil { + w.Event(progress.NewEvent(resource, progress.Done, "Removed")) + return nil + } + if errdefs.IsNotFound(err) { + w.Event(progress.NewEvent(resource, progress.Done, "Warning: No resource found to remove")) + return nil + } + return err +} + func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, containers []moby.Container, timeout *time.Duration) error { for _, container := range containers { toStop := container diff --git a/local/compose/down_test.go b/local/compose/down_test.go index 00282b023..b4bc37b01 100644 --- a/local/compose/down_test.go +++ b/local/compose/down_test.go @@ -20,12 +20,12 @@ import ( "context" "testing" - "github.com/docker/docker/api/types/filters" - "github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/local/mocks" apitypes "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/volume" "github.com/golang/mock/gomock" "gotest.tools/v3/assert" ) @@ -79,3 +79,24 @@ func TestDownRemoveOrphans(t *testing.T) { err := tested.Down(context.Background(), testProject, compose.DownOptions{RemoveOrphans: true}) assert.NilError(t, err) } + +func TestDownRemoveVolumes(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + api := mocks.NewMockAPIClient(mockCtrl) + tested.apiClient = api + + api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt()).Return( + []apitypes.Container{testContainer("service1", "123")}, nil) + + api.EXPECT().ContainerStop(gomock.Any(), "123", nil).Return(nil) + api.EXPECT().ContainerRemove(gomock.Any(), "123", apitypes.ContainerRemoveOptions{Force: true}).Return(nil) + + api.EXPECT().NetworkList(gomock.Any(), apitypes.NetworkListOptions{Filters: filters.NewArgs(projectFilter(testProject))}).Return(nil, nil) + + api.EXPECT().VolumeList(gomock.Any(), filters.NewArgs(projectFilter(testProject))).Return(volume.VolumeListOKBody{Volumes: []*apitypes.Volume{{Name: "myProject_volume"}}}, nil) + api.EXPECT().VolumeRemove(gomock.Any(), "myProject_volume", true).Return(nil) + + err := tested.Down(context.Background(), testProject, compose.DownOptions{Volumes: true}) + assert.NilError(t, err) +} diff --git a/local/e2e/compose/volumes_test.go b/local/e2e/compose/volumes_test.go index ecf0bfd81..935577361 100644 --- a/local/e2e/compose/volumes_test.go +++ b/local/e2e/compose/volumes_test.go @@ -72,7 +72,9 @@ func TestLocalComposeVolume(t *testing.T) { }) t.Run("cleanup volume project", func(t *testing.T) { - c.RunDockerCmd("compose", "--project-name", projectName, "down") - c.RunDockerCmd("volume", "rm", projectName+"_staticVol") + c.RunDockerCmd("compose", "--project-name", projectName, "down", "--volumes") + res := c.RunDockerCmd("volume", "ls") + assert.Assert(t, !strings.Contains(res.Stdout(), projectName+"_staticVol")) + assert.Assert(t, !strings.Contains(res.Stdout(), "myvolume")) }) }