From 7a61b9ae425e5c100da2bb32b929031c6302b3fb Mon Sep 17 00:00:00 2001 From: Phil Estes Date: Fri, 26 Feb 2016 21:50:50 -0500 Subject: [PATCH] Fix ownership of non-existing parent dir During "COPY" or other tar unpack operations, a target/destination parent dir might not exist and should be created with ownership of the root in the right context (including remapped root when user namespaces are enabled) Docker-DCO-1.1-Signed-off-by: Phil Estes (github: estesp) --- integration-cli/docker_cli_build_test.go | 20 ++++++++++++++++++++ pkg/archive/archive.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index a34efca2da..4c4e3f7d23 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -824,6 +824,26 @@ RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' } } +func (s *DockerSuite) TestBuildCopyToNewParentDirectory(c *check.C) { + testRequires(c, DaemonIsLinux) // Linux specific test + name := "testcopytonewdir" + ctx, err := fakeContext(`FROM busybox +COPY test_dir /new_dir +RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'root:root' ] +RUN ls -l /new_dir`, + map[string]string{ + "test_dir/test_file": "test file", + }) + if err != nil { + c.Fatal(err) + } + defer ctx.Close() + + if _, err := buildImageFromContext(name, ctx, true); err != nil { + c.Fatal(err) + } +} + func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) { name := "testaddmultiplefilestofile" diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 1281683ee4..e81f587eae 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -660,7 +660,7 @@ loop: parent := filepath.Dir(hdr.Name) parentPath := filepath.Join(dest, parent) if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) { - err = system.MkdirAll(parentPath, 0777) + err = idtools.MkdirAllNewAs(parentPath, 0777, remappedRootUID, remappedRootGID) if err != nil { return err }