Browse code

Allow unset `--entrypoint` in `docker run` or `docker create`

This fix tries to address the issue raised in #23498 to allow unset
`--entrypoint` in `docker run` or `docker create`.

This fix checks the flag `--entrypoint` and, in case `--entrypoint=` (`""`)
is passed, unset the Entrypoint during the container run.

Additional integration tests have been created to cover changes in this fix.

This fix fixes #23498.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/06/19 06:16:05
Showing 4 changed files
... ...
@@ -240,6 +240,10 @@ func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *i
240 240
 			return err
241 241
 		}
242 242
 	}
243
+	// Reset the Entrypoint if it is [""]
244
+	if len(config.Entrypoint) == 1 && config.Entrypoint[0] == "" {
245
+		config.Entrypoint = nil
246
+	}
243 247
 	if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
244 248
 		return fmt.Errorf("No command specified")
245 249
 	}
... ...
@@ -478,3 +478,31 @@ func (s *DockerSuite) TestCreate64ByteHexID(c *check.C) {
478 478
 
479 479
 	dockerCmd(c, "create", imageID)
480 480
 }
481
+
482
+// Test case for #23498
483
+func (s *DockerSuite) TestCreateUnsetEntrypoint(c *check.C) {
484
+	testRequires(c, DaemonIsLinux)
485
+	name := "test-entrypoint"
486
+	dockerfile := `FROM busybox
487
+ADD entrypoint.sh /entrypoint.sh
488
+RUN chmod 755 /entrypoint.sh
489
+ENTRYPOINT ["/entrypoint.sh"]
490
+CMD echo foobar`
491
+
492
+	ctx, err := fakeContext(dockerfile, map[string]string{
493
+		"entrypoint.sh": `#!/bin/sh
494
+echo "I am an entrypoint"
495
+exec "$@"`,
496
+	})
497
+	c.Assert(err, check.IsNil)
498
+	defer ctx.Close()
499
+
500
+	_, err = buildImageFromContext(name, ctx, true)
501
+	c.Assert(err, check.IsNil)
502
+
503
+	out, _ := dockerCmd(c, "create", "--entrypoint=", name, "echo", "foo")
504
+	id := strings.TrimSpace(out)
505
+	c.Assert(id, check.Not(check.Equals), "")
506
+	out, _ = dockerCmd(c, "start", "-a", id)
507
+	c.Assert(strings.TrimSpace(out), check.Equals, "foo")
508
+}
... ...
@@ -4497,3 +4497,33 @@ func (s *DockerSuite) TestRunAddHostInHostMode(c *check.C) {
4497 4497
 	out, _ := dockerCmd(c, "run", "--add-host=extra:1.2.3.4", "--net=host", "busybox", "cat", "/etc/hosts")
4498 4498
 	c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
4499 4499
 }
4500
+
4501
+// Test case for #23498
4502
+func (s *DockerSuite) TestRunUnsetEntrypoint(c *check.C) {
4503
+	testRequires(c, DaemonIsLinux)
4504
+	name := "test-entrypoint"
4505
+	dockerfile := `FROM busybox
4506
+ADD entrypoint.sh /entrypoint.sh
4507
+RUN chmod 755 /entrypoint.sh
4508
+ENTRYPOINT ["/entrypoint.sh"]
4509
+CMD echo foobar`
4510
+
4511
+	ctx, err := fakeContext(dockerfile, map[string]string{
4512
+		"entrypoint.sh": `#!/bin/sh
4513
+echo "I am an entrypoint"
4514
+exec "$@"`,
4515
+	})
4516
+	c.Assert(err, check.IsNil)
4517
+	defer ctx.Close()
4518
+
4519
+	_, err = buildImageFromContext(name, ctx, true)
4520
+	c.Assert(err, check.IsNil)
4521
+
4522
+	out, _ := dockerCmd(c, "run", "--entrypoint=", "-t", name, "echo", "foo")
4523
+	c.Assert(strings.TrimSpace(out), check.Equals, "foo")
4524
+
4525
+	// CMD will be reset as well (the same as setting a custom entrypoint)
4526
+	_, _, err = dockerCmdWithError("run", "--entrypoint=", "-t", name)
4527
+	c.Assert(err, check.NotNil)
4528
+	c.Assert(err.Error(), checker.Contains, "No command specified")
4529
+}
... ...
@@ -366,6 +366,9 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c
366 366
 	}
367 367
 	if copts.flEntrypoint != "" {
368 368
 		entrypoint = strslice.StrSlice{copts.flEntrypoint}
369
+	} else if flags.Changed("entrypoint") {
370
+		// if `--entrypoint=` is parsed then Entrypoint is reset
371
+		entrypoint = []string{""}
369 372
 	}
370 373
 
371 374
 	ports, portBindings, err := nat.ParsePortSpecs(copts.flPublish.GetAll())