diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 4610853f0c..48e3f72705 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -824,13 +824,15 @@ RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' } } -func (s *DockerSuite) TestBuildCopyToNewParentDirectory(c *check.C) { +// This test is mainly for user namespaces to verify that new directories +// are created as the remapped root uid/gid pair +func (s *DockerSuite) TestBuildAddToNewDestination(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - name := "testcopytonewdir" + name := "testaddtonewdest" 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`, +ADD . /new_dir +RUN ls -l / +RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'root:root' ]`, map[string]string{ "test_dir/test_file": "test file", }) @@ -844,6 +846,30 @@ RUN ls -l /new_dir`, } } +// This test is mainly for user namespaces to verify that new directories +// are created as the remapped root uid/gid pair +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 /new_dir +RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'root:root' ]`, + 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) + } +} + +// This test is mainly for user namespaces to verify that new directories +// are created as the remapped root uid/gid pair func (s *DockerSuite) TestBuildWorkdirIsContainerRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test name := "testworkdirownership" diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 358ab097b2..47c563896b 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -881,9 +881,17 @@ func (archiver *Archiver) CopyWithTar(src, dst string) error { if !srcSt.IsDir() { return archiver.CopyFileWithTar(src, dst) } + + // if this archiver is set up with ID mapping we need to create + // the new destination directory with the remapped root UID/GID pair + // as owner + rootUID, rootGID, err := idtools.GetRootUIDGID(archiver.UIDMaps, archiver.GIDMaps) + if err != nil { + return err + } // Create dst, copy src's content into it logrus.Debugf("Creating dest directory: %s", dst) - if err := system.MkdirAll(dst, 0755); err != nil { + if err := idtools.MkdirAllNewAs(dst, 0755, rootUID, rootGID); err != nil { return err } logrus.Debugf("Calling TarUntar(%s, %s)", src, dst)