Skip to content

Commit 63a2225

Browse files
committed
fix: hoist signal handling from prompt confirmation
Signed-off-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com>
1 parent c23a404 commit 63a2225

File tree

4 files changed

+17
-14
lines changed

4 files changed

+17
-14
lines changed

cli/command/utils.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ import (
99
"fmt"
1010
"io"
1111
"os"
12-
"os/signal"
1312
"path/filepath"
1413
"runtime"
1514
"strings"
16-
"syscall"
1715

1816
"github.com/docker/cli/cli/streams"
1917
"github.com/docker/docker/api/types/filters"
@@ -103,11 +101,6 @@ func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, m
103101

104102
result := make(chan bool)
105103

106-
// Catch the termination signal and exit the prompt gracefully.
107-
// The caller is responsible for properly handling the termination.
108-
notifyCtx, notifyCancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
109-
defer notifyCancel()
110-
111104
go func() {
112105
var res bool
113106
scanner := bufio.NewScanner(ins)
@@ -121,8 +114,7 @@ func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, m
121114
}()
122115

123116
select {
124-
case <-notifyCtx.Done():
125-
// print a newline on termination
117+
case <-ctx.Done():
126118
_, _ = fmt.Fprintln(outs, "")
127119
return false, ErrPromptTerminated
128120
case r := <-result:

cli/command/utils_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"io"
99
"os"
10+
"os/signal"
1011
"path/filepath"
1112
"strings"
1213
"syscall"
@@ -135,6 +136,9 @@ func TestPromptForConfirmation(t *testing.T) {
135136
}, promptResult{false, nil}},
136137
} {
137138
t.Run("case="+tc.desc, func(t *testing.T) {
139+
notifyCtx, notifyCancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
140+
t.Cleanup(notifyCancel)
141+
138142
buf.Reset()
139143
promptReader, promptWriter = io.Pipe()
140144

@@ -145,7 +149,7 @@ func TestPromptForConfirmation(t *testing.T) {
145149

146150
result := make(chan promptResult, 1)
147151
go func() {
148-
r, err := command.PromptForConfirmation(ctx, promptReader, promptOut, "")
152+
r, err := command.PromptForConfirmation(notifyCtx, promptReader, promptOut, "")
149153
result <- promptResult{r, err}
150154
}()
151155

cmd/docker/docker.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,15 @@ func runDocker(ctx context.Context, dockerCli *command.DockerCli) error {
349349
}
350350
}
351351

352+
// Catch the termination signal and exit the prompt gracefully.
353+
// The caller is responsible for properly handling the termination.
354+
notifyCtx, notifyCancel := signal.NotifyContext(ctx, platformsignals.TerminationSignals...)
355+
defer notifyCancel()
356+
352357
// We've parsed global args already, so reset args to those
353358
// which remain.
354359
cmd.SetArgs(args)
355-
err = cmd.Execute()
360+
err = cmd.ExecuteContext(notifyCtx)
356361
if err != nil {
357362
return err
358363
}

internal/test/cmd.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package test
33
import (
44
"context"
55
"os"
6-
"syscall"
76
"testing"
87
"time"
98

@@ -32,8 +31,11 @@ func TerminatePrompt(ctx context.Context, t *testing.T, cmd *cobra.Command, cli
3231
assert.NilError(t, err)
3332
cli.SetIn(streams.NewIn(r))
3433

34+
notifyCtx, notifyCancel := context.WithCancel(ctx)
35+
t.Cleanup(notifyCancel)
36+
3537
go func() {
36-
errChan <- cmd.ExecuteContext(ctx)
38+
errChan <- cmd.ExecuteContext(notifyCtx)
3739
}()
3840

3941
writeCtx, writeCancel := context.WithTimeout(ctx, 100*time.Millisecond)
@@ -66,7 +68,7 @@ func TerminatePrompt(ctx context.Context, t *testing.T, cmd *cobra.Command, cli
6668

6769
// sigint and sigterm are caught by the prompt
6870
// this allows us to gracefully exit the prompt with a 0 exit code
69-
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
71+
notifyCancel()
7072

7173
select {
7274
case <-errCtx.Done():

0 commit comments

Comments
 (0)