From 61428c1cbb004afa89f860afdf5415dcc9205a28 Mon Sep 17 00:00:00 2001 From: CodeLoopdroid <214800619+CodeLoopdroid@users.noreply.github.com> Date: Wed, 25 Mar 2026 00:26:05 +0530 Subject: [PATCH] Fix up attach filtering Signed-off-by: CodeLoopdroid <214800619+CodeLoopdroid@users.noreply.github.com> --- pkg/compose/up.go | 18 +++++-- pkg/compose/up_test.go | 104 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 pkg/compose/up_test.go diff --git a/pkg/compose/up.go b/pkg/compose/up.go index 4f5b59bc7dc..f14d8ded39c 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -246,10 +246,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options } monitor.withListener(func(event api.ContainerEvent) { - if event.Type != api.ContainerEventStarted { - return - } - if slices.Contains(attached, event.ID) && !event.Restarting { + if !shouldFollowStartEvent(event, attached, options.Start.AttachTo) { return } eg.Go(func() error { @@ -302,3 +299,16 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options } return err } + +func shouldFollowStartEvent(event api.ContainerEvent, attached []string, attachTo []string) bool { + if event.Type != api.ContainerEventStarted { + return false + } + if len(attachTo) > 0 && !slices.Contains(attachTo, event.Service) { + return false + } + if slices.Contains(attached, event.ID) && !event.Restarting { + return false + } + return true +} diff --git a/pkg/compose/up_test.go b/pkg/compose/up_test.go new file mode 100644 index 00000000000..f38a9e1aeeb --- /dev/null +++ b/pkg/compose/up_test.go @@ -0,0 +1,104 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package compose + +import ( + "testing" + + "gotest.tools/v3/assert" + + "github.com/docker/compose/v5/pkg/api" +) + +func TestShouldFollowStartEvent(t *testing.T) { + tests := []struct { + name string + event api.ContainerEvent + attached []string + attachTo []string + want bool + }{ + { + name: "ignores non-start events", + event: api.ContainerEvent{ + Type: api.ContainerEventExited, + Service: "validator", + }, + attachTo: []string{"validator"}, + want: false, + }, + { + name: "ignores services outside explicit attach selection", + event: api.ContainerEvent{ + Type: api.ContainerEventStarted, + Service: "event-bus-validator", + ID: "event-bus-validator-1", + }, + attachTo: []string{"validator"}, + want: false, + }, + { + name: "ignores containers already attached unless restarting", + event: api.ContainerEvent{ + Type: api.ContainerEventStarted, + Service: "validator", + ID: "validator-1", + }, + attached: []string{"validator-1"}, + attachTo: []string{"validator"}, + want: false, + }, + { + name: "follows restarts for attached service", + event: api.ContainerEvent{ + Type: api.ContainerEventStarted, + Service: "validator", + ID: "validator-1", + Restarting: true, + }, + attached: []string{"validator-1"}, + attachTo: []string{"validator"}, + want: true, + }, + { + name: "follows selected service when not already attached", + event: api.ContainerEvent{ + Type: api.ContainerEventStarted, + Service: "validator", + ID: "validator-2", + }, + attachTo: []string{"validator"}, + want: true, + }, + { + name: "follows service when no explicit attach filter exists", + event: api.ContainerEvent{ + Type: api.ContainerEventStarted, + Service: "validator", + ID: "validator-2", + }, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := shouldFollowStartEvent(tt.event, tt.attached, tt.attachTo) + assert.Equal(t, got, tt.want) + }) + } +}