From 2a5a50dca7dc56d390a70c0258ac1b8df3cd4d94 Mon Sep 17 00:00:00 2001 From: Lei Jitang Date: Sun, 8 Mar 2015 13:44:25 +0800 Subject: [PATCH] Fix docker start muliple containers continue on one failed and add docker start show error message from daemon when start failed Signed-off-by: Lei Jitang --- api/client/commands.go | 12 +++++- integration-cli/docker_cli_start_test.go | 53 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index ccab770f58..0d11e358f5 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -778,14 +778,18 @@ func (cli *DockerCli) CmdStart(args ...string) error { return err } } - + var encounteredError error for _, name := range cmd.Args() { _, _, err := readBody(cli.call("POST", "/containers/"+name+"/start", nil, false)) if err != nil { if !*attach && !*openStdin { + // attach and openStdin is false means it could be starting multiple containers + // when a container start failed, show the error message and start next fmt.Fprintf(cli.err, "%s\n", err) + encounteredError = fmt.Errorf("Error: failed to start one or more containers") + } else { + encounteredError = err } - return fmt.Errorf("Error: failed to start one or more containers") } else { if !*attach && !*openStdin { fmt.Fprintf(cli.out, "%s\n", name) @@ -793,6 +797,10 @@ func (cli *DockerCli) CmdStart(args ...string) error { } } + if encounteredError != nil { + return encounteredError + } + if *openStdin || *attach { if tty && cli.isTerminalOut { if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go index 8604f3a338..01f0ef95a1 100644 --- a/integration-cli/docker_cli_start_test.go +++ b/integration-cli/docker_cli_start_test.go @@ -187,3 +187,56 @@ func TestStartPausedContainer(t *testing.T) { logDone("start - error should show if trying to start paused container") } + +func TestStartMultipleContainers(t *testing.T) { + defer deleteAllContainers() + // run a container named 'parent' and create two container link to `parent` + cmd := exec.Command(dockerBinary, "run", "-d", "--name", "parent", "busybox", "top") + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatal(out, err) + } + for _, container := range []string{"child_first", "child_second"} { + cmd = exec.Command(dockerBinary, "create", "--name", container, "--link", "parent:parent", "busybox", "top") + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatal(out, err) + } + } + + // stop 'parent' container + cmd = exec.Command(dockerBinary, "stop", "parent") + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatal(out, err) + } + cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", "parent") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatal(out, err) + } + out = strings.Trim(out, "\r\n") + if out != "false" { + t.Fatal("Container should be stopped") + } + + // start all the three containers, container `child_first` start first which should be faild + // container 'parent' start second and then start container 'child_second' + cmd = exec.Command(dockerBinary, "start", "child_first", "parent", "child_second") + out, _, err = runCommandWithOutput(cmd) + if !strings.Contains(out, "Cannot start container child_first") || err == nil { + t.Fatal("Expected error but got none") + } + + for container, expected := range map[string]string{"parent": "true", "child_first": "false", "child_second": "true"} { + cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Running}}", container) + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatal(out, err) + } + out = strings.Trim(out, "\r\n") + if out != expected { + t.Fatal("Container running state wrong") + } + + } + + logDone("start - start multiple containers continue on one failed") +}