Browse code

Fix `docker start` error with renamed container

This fix tries to fix the issue raised in #23716 where `docker start`
causes an error of `No such container:` if the container has been
renamed before `docker start` returns.

The issue is that `docker start` use container name passed at the
beginning to check for exit code at the end of the `docker start`.

This fix addresses the issue by always use container's `ID` to get
the information during `docker start`.

Additional integration tests have been added to cover this fix.

This fix fixes #23716.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 6e86733b47faf0d7629751987346022544b65cb7)

Yong Tang authored on 2016/06/19 08:43:30
Showing 2 changed files
... ...
@@ -63,8 +63,9 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
63 63
 			return err
64 64
 		}
65 65
 
66
+		// We always use c.ID instead of container to maintain consistency during `docker start`
66 67
 		if !c.Config.Tty {
67
-			sigc := dockerCli.ForwardAllSignals(ctx, container)
68
+			sigc := dockerCli.ForwardAllSignals(ctx, c.ID)
68 69
 			defer signal.StopCatch(sigc)
69 70
 		}
70 71
 
... ...
@@ -86,7 +87,7 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
86 86
 			in = dockerCli.In()
87 87
 		}
88 88
 
89
-		resp, errAttach := dockerCli.Client().ContainerAttach(ctx, container, options)
89
+		resp, errAttach := dockerCli.Client().ContainerAttach(ctx, c.ID, options)
90 90
 		if errAttach != nil && errAttach != httputil.ErrPersistEOF {
91 91
 			// ContainerAttach return an ErrPersistEOF (connection closed)
92 92
 			// means server met an error and put it in Hijacked connection
... ...
@@ -103,7 +104,7 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
103 103
 		})
104 104
 
105 105
 		// 3. Start the container.
106
-		if err := dockerCli.Client().ContainerStart(ctx, container, types.ContainerStartOptions{}); err != nil {
106
+		if err := dockerCli.Client().ContainerStart(ctx, c.ID, types.ContainerStartOptions{}); err != nil {
107 107
 			cancelFun()
108 108
 			<-cErr
109 109
 			return err
... ...
@@ -111,14 +112,14 @@ func runStart(dockerCli *client.DockerCli, opts *startOptions) error {
111 111
 
112 112
 		// 4. Wait for attachment to break.
113 113
 		if c.Config.Tty && dockerCli.IsTerminalOut() {
114
-			if err := dockerCli.MonitorTtySize(ctx, container, false); err != nil {
114
+			if err := dockerCli.MonitorTtySize(ctx, c.ID, false); err != nil {
115 115
 				fmt.Fprintf(dockerCli.Err(), "Error monitoring TTY size: %s\n", err)
116 116
 			}
117 117
 		}
118 118
 		if attchErr := <-cErr; attchErr != nil {
119 119
 			return attchErr
120 120
 		}
121
-		_, status, err := getExitCode(dockerCli, ctx, container)
121
+		_, status, err := getExitCode(dockerCli, ctx, c.ID)
122 122
 		if err != nil {
123 123
 			return err
124 124
 		}
... ...
@@ -2,6 +2,7 @@ package main
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"os/exec"
5 6
 	"strings"
6 7
 	"time"
7 8
 
... ...
@@ -171,3 +172,16 @@ func (s *DockerSuite) TestStartAttachMultipleContainers(c *check.C) {
171 171
 		c.Assert(out, checker.Equals, expected)
172 172
 	}
173 173
 }
174
+
175
+// Test case for #23716
176
+func (s *DockerSuite) TestStartAttachWithRename(c *check.C) {
177
+	testRequires(c, DaemonIsLinux)
178
+	dockerCmd(c, "create", "-t", "--name", "before", "busybox")
179
+	go func() {
180
+		c.Assert(waitRun("before"), checker.IsNil)
181
+		dockerCmd(c, "rename", "before", "after")
182
+		dockerCmd(c, "stop", "--time=2", "after")
183
+	}()
184
+	_, stderr, _, _ := runCommandWithStdoutStderr(exec.Command(dockerBinary, "start", "-a", "before"))
185
+	c.Assert(stderr, checker.Not(checker.Contains), "No such container")
186
+}