Skip to content

Commit 8e1b323

Browse files
committed
fix --remove-orphans not to consider disabled services as orphaned
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent a1b7bee commit 8e1b323

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

pkg/compose/containers.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"sort"
2323
"strconv"
2424

25+
"github.com/compose-spec/compose-go/types"
2526
"github.com/docker/compose/v2/pkg/api"
2627
"github.com/docker/compose/v2/pkg/utils"
2728
moby "github.com/docker/docker/api/types"
@@ -123,6 +124,21 @@ func isNotService(services ...string) containerPredicate {
123124
}
124125
}
125126

127+
// isOrphaned is a predicate to select containers without a matching service definition in compose project
128+
func isOrphaned(project *types.Project) containerPredicate {
129+
var services []string
130+
for _, s := range project.Services {
131+
services = append(services, s.Name)
132+
}
133+
for _, s := range project.DisabledServices {
134+
services = append(services, s.Name)
135+
}
136+
return func(c moby.Container) bool {
137+
service := c.Labels[api.ServiceLabel]
138+
return !utils.StringContains(services, service)
139+
}
140+
}
141+
126142
func isNotOneOff(c moby.Container) bool {
127143
v, ok := c.Labels[api.OneoffLabel]
128144
return !ok || v == "False"

pkg/compose/down.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
8383
return err
8484
}
8585

86-
orphans := containers.filter(isNotService(project.ServiceNames()...))
86+
orphans := containers.filter(isOrphaned(project))
8787
if options.RemoveOrphans && len(orphans) > 0 {
8888
err := s.removeContainers(ctx, w, orphans, options.Timeout, false)
8989
if err != nil {

pkg/e2e/compose_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,24 @@ func TestStopWithDependenciesAttached(t *testing.T) {
292292
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/dependencies/compose.yaml", "-p", projectName, "up", "--attach-dependencies", "foo")
293293
res.Assert(t, icmd.Expected{Out: "exited with code 0"})
294294
}
295+
296+
func TestRemoveOrphaned(t *testing.T) {
297+
const projectName = "compose-e2e-remove-orphaned"
298+
c := NewParallelCLI(t)
299+
300+
cleanup := func() {
301+
c.RunDockerComposeCmd(t, "-p", projectName, "down", "--remove-orphans", "--timeout=0")
302+
}
303+
cleanup()
304+
t.Cleanup(cleanup)
305+
306+
// run stack
307+
c.RunDockerComposeCmd(t, "-f", "./fixtures/sentences/compose.yaml", "-p", projectName, "up", "-d")
308+
309+
// down "web" service with orphaned removed
310+
c.RunDockerComposeCmd(t, "-f", "./fixtures/sentences/compose.yaml", "-p", projectName, "down", "--remove-orphans", "web")
311+
312+
// check "words" service has not been considered orphaned
313+
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/sentences/compose.yaml", "-p", projectName, "ps", "--format", "{{.Name}}")
314+
res.Assert(t, icmd.Expected{Out: fmt.Sprintf("%s-words-1", projectName)})
315+
}

0 commit comments

Comments
 (0)