|
@@ -90,8 +90,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()
|
|
@@ -103,14 +103,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)
|
|
@@ -119,11 +127,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 {
|