diff --git a/pkg/compose/down.go b/pkg/compose/down.go index 1046b764b..7c4def35a 100644 --- a/pkg/compose/down.go +++ b/pkg/compose/down.go @@ -181,29 +181,43 @@ func (s *composeService) removeNetwork(ctx context.Context, name string, w progr eventName := fmt.Sprintf("Network %s", name) w.Event(progress.RemovingEvent(eventName)) - var removed int + var found int for _, net := range networks { - if net.Name == name { - if err := s.apiClient().NetworkRemove(ctx, net.ID); err != nil { - if errdefs.IsNotFound(err) { - continue - } - w.Event(progress.ErrorEvent(eventName)) - return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", name)) - } - removed++ + if net.Name != name { + continue } + network, err := s.apiClient().NetworkInspect(ctx, net.ID, moby.NetworkInspectOptions{}) + if errdefs.IsNotFound(err) { + w.Event(progress.NewEvent(eventName, progress.Warning, "No resource found to remove")) + return nil + } + if err != nil { + return err + } + if len(network.Containers) > 0 { + w.Event(progress.NewEvent(eventName, progress.Warning, "Resource is still in use")) + found++ + continue + } + + if err := s.apiClient().NetworkRemove(ctx, net.ID); err != nil { + if errdefs.IsNotFound(err) { + continue + } + w.Event(progress.ErrorEvent(eventName)) + return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", name)) + } + w.Event(progress.RemovedEvent(eventName)) + found++ } - if removed == 0 { + if found == 0 { // in practice, it's extremely unlikely for this to ever occur, as it'd // mean the network was present when we queried at the start of this // method but was then deleted by something else in the interim - w.Event(progress.NewEvent(eventName, progress.Done, "Warning: No resource found to remove")) + w.Event(progress.NewEvent(eventName, progress.Warning, "No resource found to remove")) return nil } - - w.Event(progress.RemovedEvent(eventName)) return nil } diff --git a/pkg/compose/down_test.go b/pkg/compose/down_test.go index 72827a521..78f5be280 100644 --- a/pkg/compose/down_test.go +++ b/pkg/compose/down_test.go @@ -79,6 +79,8 @@ func TestDown(t *testing.T) { {ID: "abc123", Name: "myProject_default"}, {ID: "def456", Name: "myProject_default"}, }, nil) + api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(moby.NetworkResource{ID: "abc123"}, nil) + api.EXPECT().NetworkInspect(gomock.Any(), "def456", gomock.Any()).Return(moby.NetworkResource{ID: "def456"}, nil) api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil) api.EXPECT().NetworkRemove(gomock.Any(), "def456").Return(nil) @@ -118,6 +120,7 @@ func TestDownRemoveOrphans(t *testing.T) { api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{ Filters: filters.NewArgs(filters.Arg("name", "myProject_default")), }).Return([]moby.NetworkResource{{ID: "abc123", Name: "myProject_default"}}, nil) + api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(moby.NetworkResource{ID: "abc123"}, nil) api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil) err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{RemoveOrphans: true})