From cb6c5cfbb8fa1d4073edf9a1824a096da9737c59 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Wed, 9 Apr 2014 21:50:46 -0400 Subject: [PATCH] Fixes permissions on volumes when dir in container is empty Docker-DCO-1.1-Signed-off-by: Brian Goff (github: cpuguy83) Upstream-commit: ff7b52abd3f26d9650c2e674400d58fbe8157ad8 Component: engine --- components/engine/daemon/volumes.go | 30 +++++++++---------- .../engine/integration/container_test.go | 28 ++++++++++++++++- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/components/engine/daemon/volumes.go b/components/engine/daemon/volumes.go index 4a5c4475b7..19bb7cab3f 100644 --- a/components/engine/daemon/volumes.go +++ b/components/engine/daemon/volumes.go @@ -246,22 +246,22 @@ func createVolumes(container *Container) error { if err := archive.CopyWithTar(rootVolPath, srcPath); err != nil { return err } + } + } - var stat syscall.Stat_t - if err := syscall.Stat(rootVolPath, &stat); err != nil { - return err - } - var srcStat syscall.Stat_t - if err := syscall.Stat(srcPath, &srcStat); err != nil { - return err - } - // Change the source volume's ownership if it differs from the root - // files that were just copied - if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid { - if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil { - return err - } - } + var stat syscall.Stat_t + if err := syscall.Stat(rootVolPath, &stat); err != nil { + return err + } + var srcStat syscall.Stat_t + if err := syscall.Stat(srcPath, &srcStat); err != nil { + return err + } + // Change the source volume's ownership if it differs from the root + // files that were just copied + if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid { + if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil { + return err } } } diff --git a/components/engine/integration/container_test.go b/components/engine/integration/container_test.go index 67b2783ce9..8fe52a3cd6 100644 --- a/components/engine/integration/container_test.go +++ b/components/engine/integration/container_test.go @@ -407,7 +407,7 @@ func TestCopyVolumeUidGid(t *testing.T) { defer r.Nuke() // Add directory not owned by root - container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && touch /hello/test.txt && chown daemon.daemon /hello"}, t) + container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && touch /hello/test && chown daemon.daemon /hello"}, t) defer r.Destroy(container1) if container1.State.IsRunning() { @@ -432,6 +432,32 @@ func TestCopyVolumeUidGid(t *testing.T) { if !strings.Contains(stdout1, "daemon daemon") { t.Fatal("Container failed to transfer uid and gid to volume") } + + container2, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && chown daemon.daemon /hello"}, t) + defer r.Destroy(container1) + + if container2.State.IsRunning() { + t.Errorf("Container shouldn't be running") + } + if err := container2.Run(); err != nil { + t.Fatal(err) + } + if container2.State.IsRunning() { + t.Errorf("Container shouldn't be running") + } + + img2, err := r.Commit(container2, "", "", "unit test commited image", "", nil) + if err != nil { + t.Error(err) + } + + // Test that the uid and gid is copied from the image to the volume + tmpDir2 := tempDir(t) + defer os.RemoveAll(tmpDir2) + stdout2, _ := runContainer(eng, r, []string{"-v", "/hello", img2.ID, "stat", "-c", "%U %G", "/hello"}, t) + if !strings.Contains(stdout2, "daemon daemon") { + t.Fatal("Container failed to transfer uid and gid to volume") + } } // Test for #1582