Kaynağa Gözat

Allow child to overwrite entrypoint from parent

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Michael Crosby 10 yıl önce
ebeveyn
işleme
50fa9dffcf

+ 17 - 4
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)
+
+	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]}
+	}
 
-	if len(b.Config.Entrypoint) == 0 && len(b.Config.Cmd) == 0 {
-		b.Config.Entrypoint = []string{"/bin/sh", "-c"}
-	} else if !b.cmdSet {
+	// 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
 }
 

+ 92 - 0
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")
+}

+ 2 - 2
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 {