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)
| ... | ... |
@@ -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 |
+} |