diff --git a/api/client/commands.go b/api/client/commands.go index 2c44bb63c5..29c72667cc 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -619,13 +619,13 @@ func (cli *DockerCli) CmdStart(args ...string) error { return fmt.Errorf("You cannot start and attach multiple containers at once.") } - steam, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false) + stream, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false) if err != nil { return err } env := engine.Env{} - if err := env.Decode(steam); err != nil { + if err := env.Decode(stream); err != nil { return err } config := env.GetSubEnv("Config") @@ -681,7 +681,16 @@ func (cli *DockerCli) CmdStart(args ...string) error { log.Errorf("Error monitoring TTY size: %s", err) } } - return <-cErr + if attchErr := <-cErr; attchErr != nil { + return attchErr + } + _, status, err := getExitCode(cli, cmd.Arg(0)) + if err != nil { + return err + } + if status != 0 { + return &utils.StatusError{StatusCode: status} + } } return nil } diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go index 18ad96aef1..af0a785185 100644 --- a/integration-cli/docker_cli_start_test.go +++ b/integration-cli/docker_cli_start_test.go @@ -1,7 +1,9 @@ package main import ( + "fmt" "os/exec" + "strings" "testing" "time" ) @@ -36,3 +38,33 @@ func TestStartAttachReturnsOnError(t *testing.T) { logDone("start - error on start with attach exits") } + +// gh#8555: Exit code should be passed through when using start -a +func TestStartAttachCorrectExitCode(t *testing.T) { + defer deleteAllContainers() + + runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 2; exit 1") + out, _, _, err := runCommandWithStdoutStderr(runCmd) + if err != nil { + t.Fatalf("failed to run container: %v, output: %q", err, out) + } + + out = stripTrailingCharacters(out) + + // make sure the container has exited before trying the "start -a" + waitCmd := exec.Command(dockerBinary, "wait", out) + if out, _, err = runCommandWithOutput(waitCmd); err != nil { + t.Fatal(out, err) + } + + startCmd := exec.Command(dockerBinary, "start", "-a", out) + startOut, exitCode, err := runCommandWithOutput(startCmd) + if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) { + t.Fatalf("start command failed unexpectedly with error: %v, output: %q", err, startOut) + } + if exitCode != 1 { + t.Fatalf("start -a did not respond with proper exit code: expected 1, got %d", exitCode) + } + + logDone("start - correct exit code returned with -a") +}