Skip to content

Commit d999c23

Browse files
authored
Merge pull request docker#9281 from ndeloof/down_volume_external
don't remove external volumes/networks
2 parents 730609b + e7f5459 commit d999c23

File tree

4 files changed

+74
-45
lines changed

4 files changed

+74
-45
lines changed

pkg/compose/compose.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ import (
2424
"io"
2525
"strings"
2626

27-
"github.com/docker/compose/v2/pkg/api"
28-
"github.com/pkg/errors"
29-
3027
"github.com/compose-spec/compose-go/types"
3128
"github.com/docker/cli/cli/command"
3229
"github.com/docker/cli/cli/config/configfile"
3330
"github.com/docker/cli/cli/streams"
31+
"github.com/docker/compose/v2/pkg/api"
3432
moby "github.com/docker/docker/api/types"
33+
"github.com/docker/docker/api/types/filters"
3534
"github.com/docker/docker/client"
35+
"github.com/pkg/errors"
3636
"github.com/sanathkr/go-yaml"
3737
)
3838

@@ -194,3 +194,39 @@ func (s *composeService) actualState(ctx context.Context, projectName string, se
194194
}
195195
return containers, project, nil
196196
}
197+
198+
func (s *composeService) actualVolumes(ctx context.Context, projectName string) (types.Volumes, error) {
199+
volumes, err := s.apiClient().VolumeList(ctx, filters.NewArgs(projectFilter(projectName)))
200+
if err != nil {
201+
return nil, err
202+
}
203+
204+
actual := types.Volumes{}
205+
for _, vol := range volumes.Volumes {
206+
actual[vol.Labels[api.VolumeLabel]] = types.VolumeConfig{
207+
Name: vol.Name,
208+
Driver: vol.Driver,
209+
Labels: vol.Labels,
210+
}
211+
}
212+
return actual, nil
213+
}
214+
215+
func (s *composeService) actualNetworks(ctx context.Context, projectName string) (types.Networks, error) {
216+
networks, err := s.apiClient().NetworkList(ctx, moby.NetworkListOptions{
217+
Filters: filters.NewArgs(projectFilter(projectName)),
218+
})
219+
if err != nil {
220+
return nil, err
221+
}
222+
223+
actual := types.Networks{}
224+
for _, net := range networks {
225+
actual[net.Labels[api.NetworkLabel]] = types.NetworkConfig{
226+
Name: net.Name,
227+
Driver: net.Driver,
228+
Labels: net.Labels,
229+
}
230+
}
231+
return actual, nil
232+
}

pkg/compose/create.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,14 +1078,13 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi
10781078
return nil
10791079
}
10801080

1081-
func (s *composeService) removeNetwork(ctx context.Context, networkID string, networkName string) error {
1082-
w := progress.ContextWriter(ctx)
1083-
eventName := fmt.Sprintf("Network %s", networkName)
1081+
func (s *composeService) removeNetwork(ctx context.Context, network string, w progress.Writer) error {
1082+
eventName := fmt.Sprintf("Network %s", network)
10841083
w.Event(progress.RemovingEvent(eventName))
10851084

1086-
if err := s.apiClient().NetworkRemove(ctx, networkID); err != nil {
1085+
if err := s.apiClient().NetworkRemove(ctx, network); err != nil {
10871086
w.Event(progress.ErrorEvent(eventName))
1088-
return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", networkID))
1087+
return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", network))
10891088
}
10901089

10911090
w.Event(progress.RemovedEvent(eventName))

pkg/compose/down.go

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
"github.com/compose-spec/compose-go/types"
2626
moby "github.com/docker/docker/api/types"
27-
"github.com/docker/docker/api/types/filters"
2827
"github.com/docker/docker/errdefs"
2928
"golang.org/x/sync/errgroup"
3029

@@ -41,7 +40,6 @@ func (s *composeService) Down(ctx context.Context, projectName string, options a
4140
}
4241

4342
func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error {
44-
builtFromResources := options.Project == nil
4543
w := progress.ContextWriter(ctx)
4644
resourceToRemove := false
4745

@@ -51,8 +49,9 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
5149
return err
5250
}
5351

54-
if builtFromResources {
55-
options.Project, err = s.getProjectWithVolumes(ctx, containers, projectName)
52+
project := options.Project
53+
if project == nil {
54+
project, err = s.getProjectWithResources(ctx, containers, projectName)
5655
if err != nil {
5756
return err
5857
}
@@ -62,7 +61,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
6261
resourceToRemove = true
6362
}
6463

65-
err = InReverseDependencyOrder(ctx, options.Project, func(c context.Context, service string) error {
64+
err = InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
6665
serviceContainers := containers.filter(isService(service))
6766
err := s.removeContainers(ctx, w, serviceContainers, options.Timeout, options.Volumes)
6867
return err
@@ -71,25 +70,22 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
7170
return err
7271
}
7372

74-
orphans := containers.filter(isNotService(options.Project.ServiceNames()...))
73+
orphans := containers.filter(isNotService(project.ServiceNames()...))
7574
if options.RemoveOrphans && len(orphans) > 0 {
7675
err := s.removeContainers(ctx, w, orphans, options.Timeout, false)
7776
if err != nil {
7877
return err
7978
}
8079
}
8180

82-
ops, err := s.ensureNetworksDown(ctx, projectName)
83-
if err != nil {
84-
return err
85-
}
81+
ops := s.ensureNetworksDown(ctx, project, w)
8682

8783
if options.Images != "" {
8884
ops = append(ops, s.ensureImagesDown(ctx, projectName, options, w)...)
8985
}
9086

9187
if options.Volumes {
92-
ops = append(ops, s.ensureVolumesDown(ctx, options.Project, w)...)
88+
ops = append(ops, s.ensureVolumesDown(ctx, project, w)...)
9389
}
9490

9591
if !resourceToRemove && len(ops) == 0 {
@@ -106,6 +102,9 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
106102
func (s *composeService) ensureVolumesDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp {
107103
var ops []downOp
108104
for _, vol := range project.Volumes {
105+
if vol.External.External {
106+
continue
107+
}
109108
volumeName := vol.Name
110109
ops = append(ops, func() error {
111110
return s.removeVolume(ctx, volumeName, w)
@@ -125,20 +124,18 @@ func (s *composeService) ensureImagesDown(ctx context.Context, projectName strin
125124
return ops
126125
}
127126

128-
func (s *composeService) ensureNetworksDown(ctx context.Context, projectName string) ([]downOp, error) {
127+
func (s *composeService) ensureNetworksDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp {
129128
var ops []downOp
130-
networks, err := s.apiClient().NetworkList(ctx, moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(projectName))})
131-
if err != nil {
132-
return ops, err
133-
}
134-
for _, n := range networks {
135-
networkID := n.ID
129+
for _, n := range project.Networks {
130+
if n.External.External {
131+
continue
132+
}
136133
networkName := n.Name
137134
ops = append(ops, func() error {
138-
return s.removeNetwork(ctx, networkID, networkName)
135+
return s.removeNetwork(ctx, networkName, w)
139136
})
140137
}
141-
return ops, nil
138+
return ops
142139
}
143140

144141
func (s *composeService) getServiceImages(options api.DownOptions, projectName string) map[string]struct{} {
@@ -233,21 +230,20 @@ func (s *composeService) removeContainers(ctx context.Context, w progress.Writer
233230
return eg.Wait()
234231
}
235232

236-
func (s *composeService) getProjectWithVolumes(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
233+
func (s *composeService) getProjectWithResources(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
237234
containers = containers.filter(isNotOneOff)
238235
project, _ := s.projectFromName(containers, projectName)
239-
volumes, err := s.apiClient().VolumeList(ctx, filters.NewArgs(projectFilter(projectName)))
236+
237+
volumes, err := s.actualVolumes(ctx, projectName)
240238
if err != nil {
241239
return nil, err
242240
}
241+
project.Volumes = volumes
243242

244-
project.Volumes = types.Volumes{}
245-
for _, vol := range volumes.Volumes {
246-
project.Volumes[vol.Labels[api.VolumeLabel]] = types.VolumeConfig{
247-
Name: vol.Name,
248-
Driver: vol.Driver,
249-
Labels: vol.Labels,
250-
}
243+
networks, err := s.actualNetworks(ctx, projectName)
244+
if err != nil {
245+
return nil, err
251246
}
247+
project.Networks = networks
252248
return project, nil
253249
}

pkg/compose/down_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ func TestDown(t *testing.T) {
4949
}, nil)
5050
api.EXPECT().VolumeList(gomock.Any(), filters.NewArgs(projectFilter(strings.ToLower(testProject)))).
5151
Return(volume.VolumeListOKBody{}, nil)
52+
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
53+
Return([]moby.NetworkResource{{Name: "myProject_default"}}, nil)
5254

5355
api.EXPECT().ContainerStop(gomock.Any(), "123", nil).Return(nil)
5456
api.EXPECT().ContainerStop(gomock.Any(), "456", nil).Return(nil)
@@ -58,9 +60,6 @@ func TestDown(t *testing.T) {
5860
api.EXPECT().ContainerRemove(gomock.Any(), "456", moby.ContainerRemoveOptions{Force: true}).Return(nil)
5961
api.EXPECT().ContainerRemove(gomock.Any(), "789", moby.ContainerRemoveOptions{Force: true}).Return(nil)
6062

61-
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).Return([]moby.NetworkResource{{ID: "myProject_default"}},
62-
nil)
63-
6463
api.EXPECT().NetworkRemove(gomock.Any(), "myProject_default").Return(nil)
6564

6665
err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{})
@@ -84,6 +83,8 @@ func TestDownRemoveOrphans(t *testing.T) {
8483
}, nil)
8584
api.EXPECT().VolumeList(gomock.Any(), filters.NewArgs(projectFilter(strings.ToLower(testProject)))).
8685
Return(volume.VolumeListOKBody{}, nil)
86+
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
87+
Return([]moby.NetworkResource{{Name: "myProject_default"}}, nil)
8788

8889
api.EXPECT().ContainerStop(gomock.Any(), "123", nil).Return(nil)
8990
api.EXPECT().ContainerStop(gomock.Any(), "789", nil).Return(nil)
@@ -93,9 +94,6 @@ func TestDownRemoveOrphans(t *testing.T) {
9394
api.EXPECT().ContainerRemove(gomock.Any(), "789", moby.ContainerRemoveOptions{Force: true}).Return(nil)
9495
api.EXPECT().ContainerRemove(gomock.Any(), "321", moby.ContainerRemoveOptions{Force: true}).Return(nil)
9596

96-
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).Return([]moby.NetworkResource{{ID: "myProject_default"}},
97-
nil)
98-
9997
api.EXPECT().NetworkRemove(gomock.Any(), "myProject_default").Return(nil)
10098

10199
err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{RemoveOrphans: true})
@@ -117,12 +115,12 @@ func TestDownRemoveVolumes(t *testing.T) {
117115
Return(volume.VolumeListOKBody{
118116
Volumes: []*moby.Volume{{Name: "myProject_volume"}},
119117
}, nil)
118+
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
119+
Return(nil, nil)
120120

121121
api.EXPECT().ContainerStop(gomock.Any(), "123", nil).Return(nil)
122122
api.EXPECT().ContainerRemove(gomock.Any(), "123", moby.ContainerRemoveOptions{Force: true, RemoveVolumes: true}).Return(nil)
123123

124-
api.EXPECT().NetworkList(gomock.Any(), moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).Return(nil, nil)
125-
126124
api.EXPECT().VolumeRemove(gomock.Any(), "myProject_volume", true).Return(nil)
127125

128126
err := tested.Down(context.Background(), strings.ToLower(testProject), compose.DownOptions{Volumes: true})

0 commit comments

Comments
 (0)