Merge pull request #25861 from WeiZhang555/wait-remove-for-start
Using waitExitOrRemoved for `docker start`
This commit is contained in:
commit
bdadcfc1bb
2 changed files with 29 additions and 8 deletions
|
@ -89,8 +89,8 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
|
|||
resp, errAttach := dockerCli.Client().ContainerAttach(ctx, c.ID, options)
|
||||
if errAttach != nil && errAttach != httputil.ErrPersistEOF {
|
||||
// ContainerAttach return an ErrPersistEOF (connection closed)
|
||||
// means server met an error and put it in Hijacked connection
|
||||
// keep the error and read detailed error message from hijacked connection
|
||||
// means server met an error and already put it in Hijacked connection,
|
||||
// we would keep the error and read the detailed error message from hijacked connection
|
||||
return errAttach
|
||||
}
|
||||
defer resp.Close()
|
||||
|
@ -102,14 +102,22 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
|
|||
return errHijack
|
||||
})
|
||||
|
||||
// 3. Start the container.
|
||||
// 3. We should open a channel for receiving status code of the container
|
||||
// no matter it's detached, removed on daemon side(--rm) or exit normally.
|
||||
statusChan, statusErr := waitExitOrRemoved(dockerCli, context.Background(), c.ID, c.HostConfig.AutoRemove)
|
||||
|
||||
// 4. Start the container.
|
||||
if err := dockerCli.Client().ContainerStart(ctx, c.ID, types.ContainerStartOptions{}); err != nil {
|
||||
cancelFun()
|
||||
<-cErr
|
||||
if c.HostConfig.AutoRemove && statusErr == nil {
|
||||
// wait container to be removed
|
||||
<-statusChan
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 4. Wait for attachment to break.
|
||||
// 5. Wait for attachment to break.
|
||||
if c.Config.Tty && dockerCli.IsTerminalOut() {
|
||||
if err := dockerCli.MonitorTtySize(ctx, c.ID, false); err != nil {
|
||||
fmt.Fprintf(dockerCli.Err(), "Error monitoring TTY size: %s\n", err)
|
||||
|
@ -118,11 +126,12 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
|
|||
if attchErr := <-cErr; attchErr != nil {
|
||||
return attchErr
|
||||
}
|
||||
_, status, err := getExitCode(dockerCli, ctx, c.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
if statusErr != nil {
|
||||
return fmt.Errorf("can't get container's exit code: %v", statusErr)
|
||||
}
|
||||
if status != 0 {
|
||||
|
||||
if status := <-statusChan; status != 0 {
|
||||
return cli.StatusError{StatusCode: status}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -185,3 +185,15 @@ func (s *DockerSuite) TestStartAttachWithRename(c *check.C) {
|
|||
_, stderr, _, _ := runCommandWithStdoutStderr(exec.Command(dockerBinary, "start", "-a", "before"))
|
||||
c.Assert(stderr, checker.Not(checker.Contains), "No such container")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestStartReturnCorrectExitCode(c *check.C) {
|
||||
dockerCmd(c, "create", "--restart=on-failure:2", "--name", "withRestart", "busybox", "sh", "-c", "exit 11")
|
||||
dockerCmd(c, "create", "--rm", "--name", "withRm", "busybox", "sh", "-c", "exit 12")
|
||||
|
||||
_, exitCode, err := dockerCmdWithError("start", "-a", "withRestart")
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(exitCode, checker.Equals, 11)
|
||||
_, exitCode, err = dockerCmdWithError("start", "-a", "withRm")
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(exitCode, checker.Equals, 12)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue