Browse code

Allow child to overwrite entrypoint from parent

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2014/10/08 07:39:50
Showing 3 changed files
... ...
@@ -257,17 +257,30 @@ func cmd(b *Builder, args []string, attributes map[string]bool) error {
257 257
 // is initialized at NewBuilder time instead of through argument parsing.
258 258
 //
259 259
 func entrypoint(b *Builder, args []string, attributes map[string]bool) error {
260
-	b.Config.Entrypoint = handleJsonArgs(args, attributes)
260
+	parsed := handleJsonArgs(args, attributes)
261
+
262
+	switch {
263
+	case len(parsed) == 0:
264
+		// ENTYRPOINT []
265
+		b.Config.Entrypoint = nil
266
+	case attributes["json"]:
267
+		// ENTRYPOINT ["echo", "hi"]
268
+		b.Config.Entrypoint = parsed
269
+	default:
270
+		// ENTYRPOINT echo hi
271
+		b.Config.Entrypoint = []string{"/bin/sh", "-c", parsed[0]}
272
+	}
261 273
 
262
-	if len(b.Config.Entrypoint) == 0 && len(b.Config.Cmd) == 0 {
263
-		b.Config.Entrypoint = []string{"/bin/sh", "-c"}
264
-	} else if !b.cmdSet {
274
+	// when setting the entrypoint if a CMD was not explicitly set then
275
+	// set the command to nil
276
+	if !b.cmdSet {
265 277
 		b.Config.Cmd = nil
266 278
 	}
267 279
 
268 280
 	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("ENTRYPOINT %v", b.Config.Entrypoint)); err != nil {
269 281
 		return err
270 282
 	}
283
+
271 284
 	return nil
272 285
 }
273 286
 
... ...
@@ -2459,3 +2459,95 @@ func TestBuildIgnoreInvalidInstruction(t *testing.T) {
2459 2459
 
2460 2460
 	logDone("build - ignore invalid Dockerfile instruction")
2461 2461
 }
2462
+
2463
+func TestBuildEntrypointInheritance(t *testing.T) {
2464
+	defer deleteImages("parent", "child")
2465
+
2466
+	if _, err := buildImage("parent", `
2467
+    FROM busybox
2468
+    ENTRYPOINT exit 130
2469
+    `, true); err != nil {
2470
+		t.Fatal(err)
2471
+	}
2472
+
2473
+	status, _ := runCommand(exec.Command(dockerBinary, "run", "parent"))
2474
+
2475
+	if status != 130 {
2476
+		t.Fatalf("expected exit code 130 but received %d", status)
2477
+	}
2478
+
2479
+	if _, err := buildImage("child", `
2480
+    FROM parent
2481
+    ENTRYPOINT exit 5
2482
+    `, true); err != nil {
2483
+		t.Fatal(err)
2484
+	}
2485
+
2486
+	status, _ = runCommand(exec.Command(dockerBinary, "run", "child"))
2487
+
2488
+	if status != 5 {
2489
+		t.Fatal("expected exit code 5 but received %d", status)
2490
+	}
2491
+
2492
+	logDone("build - clear entrypoint")
2493
+}
2494
+
2495
+func TestBuildEntrypointInheritanceInspect(t *testing.T) {
2496
+	var (
2497
+		name     = "testbuildepinherit"
2498
+		name2    = "testbuildepinherit2"
2499
+		expected = `["/bin/sh","-c","echo quux"]`
2500
+	)
2501
+
2502
+	defer deleteImages(name, name2)
2503
+
2504
+	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
2505
+		t.Fatal(err)
2506
+	}
2507
+
2508
+	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
2509
+		t.Fatal(err)
2510
+	}
2511
+
2512
+	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
2513
+	if err != nil {
2514
+		t.Fatal(err, res)
2515
+	}
2516
+
2517
+	if res != expected {
2518
+		t.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
2519
+	}
2520
+
2521
+	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
2522
+	if err != nil {
2523
+		t.Fatal(err, out)
2524
+	}
2525
+
2526
+	expected = "quux"
2527
+
2528
+	if strings.TrimSpace(out) != expected {
2529
+		t.Fatalf("Expected output is %s, got %s", expected, out)
2530
+	}
2531
+
2532
+	logDone("build - entrypoint override inheritance properly")
2533
+}
2534
+
2535
+func TestBuildRunShEntrypoint(t *testing.T) {
2536
+	name := "testbuildentrypoint"
2537
+	defer deleteImages(name)
2538
+	_, err := buildImage(name,
2539
+		`FROM busybox
2540
+                                ENTRYPOINT /bin/echo`,
2541
+		true)
2542
+	if err != nil {
2543
+		t.Fatal(err)
2544
+	}
2545
+
2546
+	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", name))
2547
+
2548
+	if err != nil {
2549
+		t.Fatal(err, out)
2550
+	}
2551
+
2552
+	logDone("build - entrypoint with /bin/echo running successfully")
2553
+}
... ...
@@ -302,8 +302,8 @@ func deleteAllContainers() error {
302 302
 	return nil
303 303
 }
304 304
 
305
-func deleteImages(images string) error {
306
-	rmiCmd := exec.Command(dockerBinary, "rmi", images)
305
+func deleteImages(images ...string) error {
306
+	rmiCmd := exec.Command(dockerBinary, "rmi", strings.Join(images, " "))
307 307
 	exitCode, err := runCommand(rmiCmd)
308 308
 	// set error manually if not set
309 309
 	if exitCode != 0 && err == nil {