From 7583b491250beac9caeeac13b7b68c4e0f03eb60 Mon Sep 17 00:00:00 2001 From: Lei Jitang Date: Sun, 29 Mar 2015 13:35:36 +0800 Subject: [PATCH] Fix create volume in a directory which is a symbolic link Signed-off-by: Lei Jitang --- daemon/volumes.go | 9 ++++--- integration-cli/docker_cli_run_test.go | 36 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/daemon/volumes.go b/daemon/volumes.go index a4645dab26..7312264afd 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -189,10 +189,13 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error) if _, exists := container.Volumes[path]; exists { continue } - - if stat, err := os.Stat(filepath.Join(container.basefs, path)); err == nil { + realpath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, path), container.basefs) + if err != nil { + return nil, fmt.Errorf("failed to evaluate the absolute path of symlink") + } + if stat, err := os.Stat(realpath); err == nil { if !stat.IsDir() { - return nil, fmt.Errorf("file exists at %s, can't create volume there") + return nil, fmt.Errorf("file exists at %s, can't create volume there", realpath) } } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index b0fe914a3e..e28901c7ea 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -477,6 +477,42 @@ func TestRunWithVolumesFromExited(t *testing.T) { logDone("run - regression test for #4979 - volumes-from on exited container") } +// Test create volume in a dirctory which is a symbolic link +func TestRunCreateVolumesInSymlinkDir(t *testing.T) { + defer deleteAllContainers() + // This test has to create a file on host + hostFile := "/tmp/abcd" + cmd := exec.Command("touch", hostFile) + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatalf("failed to create file %s on host: %v, output: %q", hostFile, err, out) + } + defer func() { + cmd := exec.Command("rm", "-f", hostFile) + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatalf("failed to remove file %s on host: %v, output: %q", hostFile, err, out) + } + }() + // create symlink directory /home/test link to /tmp + cmd = exec.Command(dockerBinary, "run", "--name=test", "busybox", "ln", "-s", "/tmp", "/home/test") + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatalf("failed to run container: %v, output: %q", err, out) + } + cmd = exec.Command(dockerBinary, "commit", "test", "busybox:test") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatalf("failed to commit container: %v, output: %q", err, out) + } + cleanedImageID := stripTrailingCharacters(out) + defer deleteImages(cleanedImageID) + // directory /home/test is link to /tmp, /home/test/abcd==/tmp/abcd + cmd = exec.Command(dockerBinary, "run", "-v", "/home/test/abcd", "busybox", "touch", "/home/test/abcd/Hello") + if out, _, err = runCommandWithOutput(cmd); err != nil { + t.Fatalf("failed to create volume in symlink directory: %v, output %q", err, out) + } + + logDone("run - create volume in symlink directory") +} + // Regression test for #4830 func TestRunWithRelativePath(t *testing.T) { defer deleteAllContainers()