Skip to content

Commit dc23e77

Browse files
authored
Merge pull request #5247 from Benehiko/hotfix-sigterm-container
fix: container stream should not be terminated by ctx
2 parents 2f529a1 + 991b130 commit dc23e77

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

cli/command/container/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ func runRun(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, ro
119119

120120
//nolint:gocyclo
121121
func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOptions, copts *containerOptions, containerCfg *containerConfig) error {
122+
ctx = context.WithoutCancel(ctx)
123+
122124
config := containerCfg.Config
123125
stdout, stderr := dockerCli.Out(), dockerCli.Err()
124126
apiClient := dockerCli.Client()
@@ -178,6 +180,9 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
178180
detachKeys = runOpts.detachKeys
179181
}
180182

183+
// ctx should not be cancellable here, as this would kill the stream to the container
184+
// and we want to keep the stream open until the process in the container exits or until
185+
// the user forcefully terminates the CLI.
181186
closeFn, err := attachContainer(ctx, dockerCli, containerID, &errCh, config, container.AttachOptions{
182187
Stream: true,
183188
Stdin: config.AttachStdin,

e2e/container/run_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package container
22

33
import (
4+
"bytes"
45
"fmt"
56
"strings"
7+
"syscall"
68
"testing"
79
"time"
810

@@ -13,6 +15,7 @@ import (
1315
is "gotest.tools/v3/assert/cmp"
1416
"gotest.tools/v3/golden"
1517
"gotest.tools/v3/icmd"
18+
"gotest.tools/v3/poll"
1619
"gotest.tools/v3/skip"
1720
)
1821

@@ -221,3 +224,26 @@ func TestMountSubvolume(t *testing.T) {
221224
})
222225
}
223226
}
227+
228+
func TestProcessTermination(t *testing.T) {
229+
var out bytes.Buffer
230+
cmd := icmd.Command("docker", "run", "--rm", "-i", fixtures.AlpineImage,
231+
"sh", "-c", "echo 'starting trap'; trap 'echo got signal; exit 0;' TERM; while true; do sleep 10; done")
232+
cmd.Stdout = &out
233+
cmd.Stderr = &out
234+
235+
result := icmd.StartCmd(cmd).Assert(t, icmd.Success)
236+
237+
poll.WaitOn(t, func(t poll.LogT) poll.Result {
238+
if strings.Contains(result.Stdout(), "starting trap") {
239+
return poll.Success()
240+
}
241+
return poll.Continue("waiting for process to trap signal")
242+
}, poll.WithDelay(1*time.Second), poll.WithTimeout(5*time.Second))
243+
244+
assert.NilError(t, result.Cmd.Process.Signal(syscall.SIGTERM))
245+
246+
icmd.WaitOnCmd(time.Second*10, result).Assert(t, icmd.Expected{
247+
ExitCode: 0,
248+
})
249+
}

0 commit comments

Comments
 (0)