Browse code

Fix image's `CMD` after `WORKDIR` in Dockerfile

This fix tries to fix 29667 where image's `CMD` is modified
after `WORKDIR` in Dockerfile.

The value of `b.runConfig.Cmd` was modified in the processing
of `WORKDIR`, in order to fix 28902. However, the same
`b.runConfig.Cmd` is passed to `commit()`.

This fix restored the `b.runConfig.Cmd` before `commit()`
the image for `WORKDIR`.

A test has been added.

This fix fixes 29667.

This fix is related to 28902, 28909, 28514.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 083602384737635af9a89b75a6ca6d27f7515dc6)
Signed-off-by: Victor Vieux <vieux@docker.com>

Yong Tang authored on 2016/12/24 04:16:15
Showing 2 changed files
... ...
@@ -297,17 +297,17 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
297 297
 	}
298 298
 	b.runConfig.Image = b.image
299 299
 
300
-	cmd := b.runConfig.Cmd
301
-	b.runConfig.Cmd = strslice.StrSlice(append(getShell(b.runConfig), fmt.Sprintf("#(nop) WORKDIR %s", b.runConfig.WorkingDir)))
302
-	defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
303
-
304 300
 	if hit, err := b.probeCache(); err != nil {
305 301
 		return err
306 302
 	} else if hit {
307 303
 		return nil
308 304
 	}
309 305
 
310
-	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig})
306
+	// Actually copy the struct
307
+	workdirConfig := *b.runConfig
308
+	workdirConfig.Cmd = strslice.StrSlice(append(getShell(b.runConfig), fmt.Sprintf("#(nop) WORKDIR %s", b.runConfig.WorkingDir)))
309
+
310
+	container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: &workdirConfig})
311 311
 	if err != nil {
312 312
 		return err
313 313
 	}
... ...
@@ -7357,3 +7357,43 @@ func (s *DockerSuite) TestBuildWindowsEnvCaseInsensitive(c *check.C) {
7357 7357
 		c.Fatalf("Case insensitive environment variables on Windows failed. Got %s", res)
7358 7358
 	}
7359 7359
 }
7360
+
7361
+// Test case for 29667
7362
+func (s *DockerSuite) TestBuildWorkdirImageCmd(c *check.C) {
7363
+	testRequires(c, DaemonIsLinux)
7364
+
7365
+	image := "testworkdirimagecmd"
7366
+	dockerfile := `
7367
+FROM busybox
7368
+WORKDIR /foo/bar
7369
+`
7370
+	out, err := buildImage(image, dockerfile, true)
7371
+	c.Assert(err, checker.IsNil, check.Commentf("Output: %s", out))
7372
+
7373
+	out, _ = dockerCmd(c, "inspect", "--format", "{{ json .Config.Cmd }}", image)
7374
+	c.Assert(strings.TrimSpace(out), checker.Equals, `["sh"]`)
7375
+
7376
+	image = "testworkdirlabelimagecmd"
7377
+	dockerfile = `
7378
+FROM busybox
7379
+WORKDIR /foo/bar
7380
+LABEL a=b
7381
+`
7382
+	out, err = buildImage(image, dockerfile, true)
7383
+	c.Assert(err, checker.IsNil, check.Commentf("Output: %s", out))
7384
+
7385
+	out, _ = dockerCmd(c, "inspect", "--format", "{{ json .Config.Cmd }}", image)
7386
+	c.Assert(strings.TrimSpace(out), checker.Equals, `["sh"]`)
7387
+}
7388
+
7389
+// Test case for 28902/28090
7390
+func (s *DockerSuite) TestBuildWorkdirCmd(c *check.C) {
7391
+	testRequires(c, DaemonIsLinux)
7392
+
7393
+	dockerFile := `
7394
+                FROM golang:1.7-alpine
7395
+                WORKDIR /
7396
+                `
7397
+	_, err := buildImage("testbuildworkdircmd", dockerFile, false)
7398
+	c.Assert(err, checker.IsNil)
7399
+}