Skip to content

Commit 2ff71b9

Browse files
committed
up: gracefully teardown when command ctx cancelled
Previously, if a long-lived plugin process (such as an execution of `compose up`) was running and then detached from a terminal, signalling the parent CLI process to exit would leave the plugin process behind. To address this, changes were introduced on the CLI side (see: docker/cli#4599) to enable the CLI to notify a running plugin process that it should exit. This makes it so that, when the parent CLI process is going to exit, the command context of the plugin command being executed is cancelled. This commit takes advantage of these changes by tapping into the command context's done channel and using it to teardown on an up. Signed-off-by: Laura Brehm <laurabrehm@hey.com>
1 parent 6763745 commit 2ff71b9

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

pkg/compose/up.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
"github.com/hashicorp/go-multierror"
3232
)
3333

34-
func (s *composeService) Up(ctx context.Context, project *types.Project, options api.UpOptions) error {
34+
func (s *composeService) Up(ctx context.Context, project *types.Project, options api.UpOptions) error { //nolint:gocyclo
3535
err := progress.Run(ctx, tracing.SpanWrapFunc("project/up", tracing.ProjectOptions(project), func(ctx context.Context) error {
3636
err := s.create(ctx, project, options.Create)
3737
if err != nil {
@@ -69,24 +69,31 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
6969
doneCh := make(chan bool)
7070
eg.Go(func() error {
7171
first := true
72+
gracefulTeardown := func() {
73+
printer.Cancel()
74+
fmt.Fprintln(s.stdinfo(), "Gracefully stopping... (press Ctrl+C again to force)")
75+
eg.Go(func() error {
76+
err := s.Stop(context.Background(), project.Name, api.StopOptions{
77+
Services: options.Create.Services,
78+
Project: project,
79+
})
80+
isTerminated = true
81+
close(doneCh)
82+
return err
83+
})
84+
first = false
85+
}
7286
for {
7387
select {
7488
case <-doneCh:
7589
return nil
90+
case <-ctx.Done():
91+
if first {
92+
gracefulTeardown()
93+
}
7694
case <-signalChan:
7795
if first {
78-
printer.Cancel()
79-
fmt.Fprintln(s.stdinfo(), "Gracefully stopping... (press Ctrl+C again to force)")
80-
eg.Go(func() error {
81-
err := s.Stop(context.Background(), project.Name, api.StopOptions{
82-
Services: options.Create.Services,
83-
Project: project,
84-
})
85-
isTerminated = true
86-
close(doneCh)
87-
return err
88-
})
89-
first = false
96+
gracefulTeardown()
9097
} else {
9198
eg.Go(func() error {
9299
return s.Kill(context.Background(), project.Name, api.KillOptions{

0 commit comments

Comments
 (0)