Skip to content

Commit 6a3501f

Browse files
jsorianondeloof
authored andcommitted
Handle errors and allow to send multiple kills if one failed
Signed-off-by: Jaime Soriano Pastor <[email protected]>
1 parent 5daed33 commit 6a3501f

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

pkg/compose/up.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"os"
2323
"os/signal"
24+
"sync/atomic"
2425
"syscall"
2526

2627
"github.com/compose-spec/compose-go/v2/types"
@@ -29,6 +30,7 @@ import (
2930
"github.com/docker/compose/v2/internal/tracing"
3031
"github.com/docker/compose/v2/pkg/api"
3132
"github.com/docker/compose/v2/pkg/progress"
33+
"github.com/docker/docker/errdefs"
3234
"github.com/eiannone/keyboard"
3335
"github.com/hashicorp/go-multierror"
3436
"github.com/sirupsen/logrus"
@@ -106,6 +108,9 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
106108
}
107109
}
108110
}
111+
112+
// killRunning is used to control that we don't run more than one kill if signals are spammed.
113+
var killRunning atomic.Bool
109114
for {
110115
select {
111116
case <-doneCh:
@@ -117,19 +122,27 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
117122
case <-signalChan:
118123
if first {
119124
gracefulTeardown()
120-
} else {
121-
eg.Go(func() error {
122-
// Intentionally ignore errors, for cases where some
123-
// of the containers are already stopped.
124-
s.kill(context.Background(), project.Name, api.KillOptions{
125-
Services: options.Create.Services,
126-
Project: project,
127-
All: true,
128-
})
129-
return nil
130-
})
131-
return nil
125+
break
126+
}
127+
if !killRunning.CompareAndSwap(false, true) {
128+
break
132129
}
130+
eg.Go(func() error {
131+
defer killRunning.Store(false)
132+
// Intentionally ignore errors, for cases where some
133+
// of the containers are already stopped.
134+
err := s.kill(context.Background(), project.Name, api.KillOptions{
135+
Services: options.Create.Services,
136+
Project: project,
137+
All: true,
138+
})
139+
// Ignore errors indicating that some of the containers were already stopped or removed.
140+
if errdefs.IsNotFound(err) || errdefs.IsConflict(err) {
141+
return nil
142+
}
143+
144+
return err
145+
})
133146
case event := <-kEvents:
134147
formatter.KeyboardManager.HandleKeyEvents(event, ctx, project, options)
135148
}

0 commit comments

Comments
 (0)