diff --git a/builder/dispatchers.go b/builder/dispatchers.go index 36ce123d24..ec79f2c154 100644 --- a/builder/dispatchers.go +++ b/builder/dispatchers.go @@ -257,17 +257,30 @@ func cmd(b *Builder, args []string, attributes map[string]bool) error { // is initialized at NewBuilder time instead of through argument parsing. // func entrypoint(b *Builder, args []string, attributes map[string]bool) error { - b.Config.Entrypoint = handleJsonArgs(args, attributes) + parsed := handleJsonArgs(args, attributes) - if len(b.Config.Entrypoint) == 0 && len(b.Config.Cmd) == 0 { - b.Config.Entrypoint = []string{"/bin/sh", "-c"} - } else if !b.cmdSet { + switch { + case len(parsed) == 0: + // ENTYRPOINT [] + b.Config.Entrypoint = nil + case attributes["json"]: + // ENTRYPOINT ["echo", "hi"] + b.Config.Entrypoint = parsed + default: + // ENTYRPOINT echo hi + b.Config.Entrypoint = []string{"/bin/sh", "-c", parsed[0]} + } + + // when setting the entrypoint if a CMD was not explicitly set then + // set the command to nil + if !b.cmdSet { b.Config.Cmd = nil } if err := b.commit("", b.Config.Cmd, fmt.Sprintf("ENTRYPOINT %v", b.Config.Entrypoint)); err != nil { return err } + return nil } diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 8ae40f730a..2828f27918 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -2459,3 +2459,95 @@ func TestBuildIgnoreInvalidInstruction(t *testing.T) { logDone("build - ignore invalid Dockerfile instruction") } + +func TestBuildEntrypointInheritance(t *testing.T) { + defer deleteImages("parent", "child") + + if _, err := buildImage("parent", ` + FROM busybox + ENTRYPOINT exit 130 + `, true); err != nil { + t.Fatal(err) + } + + status, _ := runCommand(exec.Command(dockerBinary, "run", "parent")) + + if status != 130 { + t.Fatalf("expected exit code 130 but received %d", status) + } + + if _, err := buildImage("child", ` + FROM parent + ENTRYPOINT exit 5 + `, true); err != nil { + t.Fatal(err) + } + + status, _ = runCommand(exec.Command(dockerBinary, "run", "child")) + + if status != 5 { + t.Fatal("expected exit code 5 but received %d", status) + } + + logDone("build - clear entrypoint") +} + +func TestBuildEntrypointInheritanceInspect(t *testing.T) { + var ( + name = "testbuildepinherit" + name2 = "testbuildepinherit2" + expected = `["/bin/sh","-c","echo quux"]` + ) + + defer deleteImages(name, name2) + + if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil { + t.Fatal(err) + } + + if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil { + t.Fatal(err) + } + + res, err := inspectFieldJSON(name2, "Config.Entrypoint") + if err != nil { + t.Fatal(err, res) + } + + if res != expected { + t.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res) + } + + out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2)) + if err != nil { + t.Fatal(err, out) + } + + expected = "quux" + + if strings.TrimSpace(out) != expected { + t.Fatalf("Expected output is %s, got %s", expected, out) + } + + logDone("build - entrypoint override inheritance properly") +} + +func TestBuildRunShEntrypoint(t *testing.T) { + name := "testbuildentrypoint" + defer deleteImages(name) + _, err := buildImage(name, + `FROM busybox + ENTRYPOINT /bin/echo`, + true) + if err != nil { + t.Fatal(err) + } + + out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", name)) + + if err != nil { + t.Fatal(err, out) + } + + logDone("build - entrypoint with /bin/echo running successfully") +} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 89d6f0b0de..0b990340b8 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -302,8 +302,8 @@ func deleteAllContainers() error { return nil } -func deleteImages(images string) error { - rmiCmd := exec.Command(dockerBinary, "rmi", images) +func deleteImages(images ...string) error { + rmiCmd := exec.Command(dockerBinary, "rmi", strings.Join(images, " ")) exitCode, err := runCommand(rmiCmd) // set error manually if not set if exitCode != 0 && err == nil {