Removes the build-args from the image history if they are in the
BuiltinAllowedBuildArgs map unless they are explicitly defined in an ARG
instruction.
Signed-off-by: Dave Tucker <dt@docker.com>
| ... | ... |
@@ -38,6 +38,8 @@ var validCommitCommands = map[string]bool{
|
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 | 40 |
// BuiltinAllowedBuildArgs is list of built-in allowed build args |
| 41 |
+// these args are considered transparent and are excluded from the image history. |
|
| 42 |
+// Filtering from history is implemented in dispatchers.go |
|
| 41 | 43 |
var BuiltinAllowedBuildArgs = map[string]bool{
|
| 42 | 44 |
"HTTP_PROXY": true, |
| 43 | 45 |
"http_proxy": true, |
| ... | ... |
@@ -411,6 +411,26 @@ func run(b *Builder, args []string, attributes map[string]bool, original string) |
| 411 | 411 |
// have the build-time env vars in it (if any) so that future cache look-ups |
| 412 | 412 |
// properly match it. |
| 413 | 413 |
b.runConfig.Env = env |
| 414 |
+ |
|
| 415 |
+ // remove BuiltinAllowedBuildArgs (see: builder.go) from the saveCmd |
|
| 416 |
+ // these args are transparent so resulting image should be the same regardless of the value |
|
| 417 |
+ if len(cmdBuildEnv) > 0 {
|
|
| 418 |
+ saveCmd = config.Cmd |
|
| 419 |
+ tmpBuildEnv := make([]string, len(cmdBuildEnv)) |
|
| 420 |
+ copy(tmpBuildEnv, cmdBuildEnv) |
|
| 421 |
+ for i, env := range tmpBuildEnv {
|
|
| 422 |
+ key := strings.SplitN(env, "=", 2)[0] |
|
| 423 |
+ if _, ok := BuiltinAllowedBuildArgs[key]; ok {
|
|
| 424 |
+ // If an built-in arg is explicitly added in the Dockerfile, don't prune it |
|
| 425 |
+ if _, ok := b.allowedBuildArgs[key]; !ok {
|
|
| 426 |
+ tmpBuildEnv = append(tmpBuildEnv[:i], tmpBuildEnv[i+1:]...) |
|
| 427 |
+ } |
|
| 428 |
+ } |
|
| 429 |
+ } |
|
| 430 |
+ sort.Strings(tmpBuildEnv) |
|
| 431 |
+ tmpEnv := append([]string{fmt.Sprintf("|%d", len(tmpBuildEnv))}, tmpBuildEnv...)
|
|
| 432 |
+ saveCmd = strslice.StrSlice(append(tmpEnv, saveCmd...)) |
|
| 433 |
+ } |
|
| 414 | 434 |
b.runConfig.Cmd = saveCmd |
| 415 | 435 |
return b.commit(cID, cmd, "run") |
| 416 | 436 |
} |
| ... | ... |
@@ -1396,6 +1396,35 @@ To use these, simply pass them on the command line using the flag: |
| 1396 | 1396 |
--build-arg <varname>=<value> |
| 1397 | 1397 |
``` |
| 1398 | 1398 |
|
| 1399 |
+By default, these pre-defined variables are excluded from the output of |
|
| 1400 |
+`docker history`. Excluding them reduces the risk of accidentally leaking |
|
| 1401 |
+sensitive authentication information in an `HTTP_PROXY` variable. |
|
| 1402 |
+ |
|
| 1403 |
+For example, consider building the following Dockerfile using |
|
| 1404 |
+`--build-arg HTTP_PROXY=http://user:pass@proxy.lon.example.com` |
|
| 1405 |
+ |
|
| 1406 |
+``` Dockerfile |
|
| 1407 |
+FROM ubuntu |
|
| 1408 |
+RUN echo "Hello World" |
|
| 1409 |
+``` |
|
| 1410 |
+ |
|
| 1411 |
+In this case, the value of the `HTTP_PROXY` variable is not available in the |
|
| 1412 |
+`docker history` and is not cached. If you were to change location, and your |
|
| 1413 |
+proxy server changed to `http://user:pass@proxy.sfo.example.com`, a subsequent |
|
| 1414 |
+build does not result in a cache miss. |
|
| 1415 |
+ |
|
| 1416 |
+If you need to override this behaviour then you may do so by adding an `ARG` |
|
| 1417 |
+statement in the Dockerfile as follows: |
|
| 1418 |
+ |
|
| 1419 |
+``` Dockerfile |
|
| 1420 |
+FROM ubuntu |
|
| 1421 |
+ARG HTTP_PROXY |
|
| 1422 |
+RUN echo "Hello World" |
|
| 1423 |
+``` |
|
| 1424 |
+ |
|
| 1425 |
+When building this Dockerfile, the `HTTP_PROXY` is preserved in the |
|
| 1426 |
+`docker history`, and changing its value invalidates the build cache. |
|
| 1427 |
+ |
|
| 1399 | 1428 |
### Impact on build caching |
| 1400 | 1429 |
|
| 1401 | 1430 |
`ARG` variables are not persisted into the built image as `ENV` variables are. |
| ... | ... |
@@ -1404,6 +1433,8 @@ Dockerfile defines an `ARG` variable whose value is different from a previous |
| 1404 | 1404 |
build, then a "cache miss" occurs upon its first usage, not its definition. In |
| 1405 | 1405 |
particular, all `RUN` instructions following an `ARG` instruction use the `ARG` |
| 1406 | 1406 |
variable implicitly (as an environment variable), thus can cause a cache miss. |
| 1407 |
+All predefined `ARG` variables are exempt from caching unless there is a |
|
| 1408 |
+matching `ARG` statement in the `Dockerfile`. |
|
| 1407 | 1409 |
|
| 1408 | 1410 |
For example, consider these two Dockerfile: |
| 1409 | 1411 |
|
| ... | ... |
@@ -4290,6 +4290,36 @@ func (s *DockerSuite) TestBuildBuildTimeArgHistory(c *check.C) {
|
| 4290 | 4290 |
} |
| 4291 | 4291 |
} |
| 4292 | 4292 |
|
| 4293 |
+func (s *DockerSuite) TestBuildTimeArgHistoryExclusions(c *check.C) {
|
|
| 4294 |
+ imgName := "bldargtest" |
|
| 4295 |
+ envKey := "foo" |
|
| 4296 |
+ envVal := "bar" |
|
| 4297 |
+ proxy := "HTTP_PROXY=http://user:password@proxy.example.com" |
|
| 4298 |
+ explicitProxyKey := "http_proxy" |
|
| 4299 |
+ explicitProxyVal := "http://user:password@someproxy.example.com" |
|
| 4300 |
+ dockerfile := fmt.Sprintf(`FROM busybox |
|
| 4301 |
+ ARG %s |
|
| 4302 |
+ ARG %s |
|
| 4303 |
+ RUN echo "Testing Build Args!"`, envKey, explicitProxyKey) |
|
| 4304 |
+ buildImage(imgName, |
|
| 4305 |
+ withBuildFlags("--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
|
|
| 4306 |
+ "--build-arg", fmt.Sprintf("%s=%s", explicitProxyKey, explicitProxyVal),
|
|
| 4307 |
+ "--build-arg", proxy), |
|
| 4308 |
+ withDockerfile(dockerfile), |
|
| 4309 |
+ ).Assert(c, icmd.Success) |
|
| 4310 |
+ |
|
| 4311 |
+ out, _ := dockerCmd(c, "history", "--no-trunc", imgName) |
|
| 4312 |
+ if strings.Contains(out, proxy) {
|
|
| 4313 |
+ c.Fatalf("failed to exclude proxy settings from history!")
|
|
| 4314 |
+ } |
|
| 4315 |
+ if !strings.Contains(out, fmt.Sprintf("%s=%s", envKey, envVal)) {
|
|
| 4316 |
+ c.Fatalf("explicitly defined ARG %s is not in output", explicitProxyKey)
|
|
| 4317 |
+ } |
|
| 4318 |
+ if !strings.Contains(out, fmt.Sprintf("%s=%s", envKey, envVal)) {
|
|
| 4319 |
+ c.Fatalf("missing build arguments from output")
|
|
| 4320 |
+ } |
|
| 4321 |
+} |
|
| 4322 |
+ |
|
| 4293 | 4323 |
func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {
|
| 4294 | 4324 |
imgName := "bldargtest" |
| 4295 | 4325 |
envKey := "foo" |