Browse code

Fix cache miss when builtin build args are used.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2017/04/29 01:49:50
Showing 2 changed files
... ...
@@ -408,9 +408,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
408 408
 	// that starts with "foo=abc" to be considered part of a build-time env var.
409 409
 	saveCmd := config.Cmd
410 410
 	if len(cmdBuildEnv) > 0 {
411
-		sort.Strings(cmdBuildEnv)
412
-		tmpEnv := append([]string{fmt.Sprintf("|%d", len(cmdBuildEnv))}, cmdBuildEnv...)
413
-		saveCmd = strslice.StrSlice(append(tmpEnv, saveCmd...))
411
+		saveCmd = prependEnvOnCmd(b.buildArgs, cmdBuildEnv, saveCmd)
414 412
 	}
415 413
 
416 414
 	b.runConfig.Cmd = saveCmd
... ...
@@ -445,25 +443,24 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
445 445
 	// properly match it.
446 446
 	b.runConfig.Env = env
447 447
 
448
-	// remove builtinAllowedBuildArgs (see: builder.go)  from the saveCmd
449
-	// these args are transparent so resulting image should be the same regardless of the value
450
-	if len(cmdBuildEnv) > 0 {
451
-		saveCmd = config.Cmd
452
-		var tmpBuildEnv []string
453
-		for _, env := range cmdBuildEnv {
454
-			key := strings.SplitN(env, "=", 2)[0]
455
-			if !b.buildArgs.IsUnreferencedBuiltin(key) {
456
-				tmpBuildEnv = append(tmpBuildEnv, env)
457
-			}
458
-		}
459
-		sort.Strings(tmpBuildEnv)
460
-		tmpEnv := append([]string{fmt.Sprintf("|%d", len(tmpBuildEnv))}, tmpBuildEnv...)
461
-		saveCmd = strslice.StrSlice(append(tmpEnv, saveCmd...))
462
-	}
463 448
 	b.runConfig.Cmd = saveCmd
464 449
 	return b.commit(cID, cmd, "run")
465 450
 }
466 451
 
452
+func prependEnvOnCmd(buildArgs *buildArgs, buildArgVars []string, cmd strslice.StrSlice) strslice.StrSlice {
453
+	var tmpBuildEnv []string
454
+	for _, env := range buildArgVars {
455
+		key := strings.SplitN(env, "=", 2)[0]
456
+		if !buildArgs.IsUnreferencedBuiltin(key) {
457
+			tmpBuildEnv = append(tmpBuildEnv, env)
458
+		}
459
+	}
460
+
461
+	sort.Strings(tmpBuildEnv)
462
+	tmpEnv := append([]string{fmt.Sprintf("|%d", len(tmpBuildEnv))}, tmpBuildEnv...)
463
+	return strslice.StrSlice(append(tmpEnv, cmd...))
464
+}
465
+
467 466
 // CMD foo
468 467
 //
469 468
 // Set the default command to run in the container (which may be empty).
... ...
@@ -4344,15 +4344,22 @@ func (s *DockerSuite) TestBuildTimeArgHistoryExclusions(c *check.C) {
4344 4344
 		ARG %s
4345 4345
 		ARG %s
4346 4346
 		RUN echo "Testing Build Args!"`, envKey, explicitProxyKey)
4347
-	buildImage(imgName,
4348
-		cli.WithFlags("--build-arg", "https_proxy=https://proxy.example.com",
4349
-			"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
4350
-			"--build-arg", fmt.Sprintf("%s=%s", explicitProxyKey, explicitProxyVal),
4351
-			"--build-arg", proxy),
4352
-		build.WithDockerfile(dockerfile),
4353
-	).Assert(c, icmd.Success)
4354 4347
 
4355
-	out, _ := dockerCmd(c, "history", "--no-trunc", imgName)
4348
+	buildImage := func(imgName string) string {
4349
+		cli.BuildCmd(c, imgName,
4350
+			cli.WithFlags("--build-arg", "https_proxy=https://proxy.example.com",
4351
+				"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
4352
+				"--build-arg", fmt.Sprintf("%s=%s", explicitProxyKey, explicitProxyVal),
4353
+				"--build-arg", proxy),
4354
+			build.WithDockerfile(dockerfile),
4355
+		)
4356
+		return getIDByName(c, imgName)
4357
+	}
4358
+
4359
+	origID := buildImage(imgName)
4360
+	result := cli.DockerCmd(c, "history", "--no-trunc", imgName)
4361
+	out := result.Stdout()
4362
+
4356 4363
 	if strings.Contains(out, proxy) {
4357 4364
 		c.Fatalf("failed to exclude proxy settings from history!")
4358 4365
 	}
... ...
@@ -4365,6 +4372,9 @@ func (s *DockerSuite) TestBuildTimeArgHistoryExclusions(c *check.C) {
4365 4365
 	if !strings.Contains(out, fmt.Sprintf("%s=%s", envKey, envVal)) {
4366 4366
 		c.Fatalf("missing build arguments from output")
4367 4367
 	}
4368
+
4369
+	cacheID := buildImage(imgName + "-two")
4370
+	c.Assert(origID, checker.Equals, cacheID)
4368 4371
 }
4369 4372
 
4370 4373
 func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {