run: return error code when only STDIN attached

During a `docker run`, the CLI has some different behavior/output
depending on whether the run is "detached" or not.

In some cases, the CLI is checking whether either `stdin`, `stdout` or
`stderr` are attached, but in other cases we're only checking `stdout`
and `stderr`, which leads to some inconsistencies:

```
$ docker run -a stdout --rm --name test alpine top
[docker kill test]
exit status 137

$ docker run -a stderr --rm --name test alpine top
[docker kill test]
exit status 137

$ docker run -a stdin --rm --name test alpine top
56820d94a89b96889478241ae68920323332c6d4cf9b51ba9340cba01e9e0565
[docker kill test]
[no exit code]
```

Since we're not checking for whether `stdin` is attached when deciding
whether to early exit without receiving on `statusChan`, the `docker run
-a stdin` is falling into the "detached mode" logic, which simply prints
the container ID and doesn't print/return the exit code.

This patch makes the "attached" checks consistent.

Signed-off-by: Laura Brehm <laurabrehm@hey.com>
This commit is contained in:
Laura Brehm 2024-11-29 16:59:36 +00:00
parent 5afa739692
commit aee9eebf34
No known key found for this signature in database
GPG Key ID: 08EC1B0491948487

View File

@ -161,7 +161,8 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
waitDisplayID chan struct{}
errCh chan error
)
if !config.AttachStdout && !config.AttachStderr {
attach := config.AttachStdin || config.AttachStdout || config.AttachStderr
if !attach {
// Make this asynchronous to allow the client to write to stdin before having to read the ID
waitDisplayID = make(chan struct{})
go func() {
@ -169,7 +170,6 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
_, _ = fmt.Fprintln(stdout, containerID)
}()
}
attach := config.AttachStdin || config.AttachStdout || config.AttachStderr
if attach {
detachKeys := dockerCli.ConfigFile().DetachKeys
if runOpts.detachKeys != "" {
@ -234,7 +234,7 @@ func runContainer(ctx context.Context, dockerCli command.Cli, runOpts *runOption
}
// Detached mode: wait for the id to be displayed and return.
if !config.AttachStdout && !config.AttachStderr {
if !attach {
// Detached mode
<-waitDisplayID
return nil