From 964f9965c75b89f95060c62ba512ed6ceb525992 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Mon, 20 Oct 2014 15:27:26 -0400 Subject: [PATCH] Clean volume paths Fixes #8659 Signed-off-by: Brian Goff --- daemon/volumes.go | 3 ++ integration-cli/docker_cli_run_test.go | 50 ++++++++++++++++++++++++++ integration-cli/docker_test_vars.go | 6 ++-- integration-cli/docker_utils.go | 10 ++++++ volumes/repository.go | 5 +-- 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/daemon/volumes.go b/daemon/volumes.go index c7a8d7bfcb6da..b34d9678cb966 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -133,6 +133,7 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error) // Get the rest of the volumes for path := range container.Config.Volumes { // Check if this is already added as a bind-mount + path = filepath.Clean(path) if _, exists := mounts[path]; exists { continue } @@ -182,6 +183,8 @@ func parseBindMountSpec(spec string) (string, string, bool, error) { return "", "", false, fmt.Errorf("cannot bind mount volume: %s volume paths must be absolute.", path) } + path = filepath.Clean(path) + mountToPath = filepath.Clean(mountToPath) return path, mountToPath, writable, nil } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 81ed693b2b1ef..eeb3601e7a49a 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -2396,3 +2396,53 @@ func TestRunNoOutputFromPullInStdout(t *testing.T) { } logDone("run - no output from pull in stdout") } + +func TestRunVolumesCleanPaths(t *testing.T) { + defer deleteAllContainers() + + if _, err := buildImage("run_volumes_clean_paths", + `FROM busybox + VOLUME /foo/`, + true); err != nil { + t.Fatal(err) + } + defer deleteImages("run_volumes_clean_paths") + + cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "-v", "/bar/", "--name", "dark_helmet", "run_volumes_clean_paths") + if out, _, err := runCommandWithOutput(cmd); err != nil { + t.Fatal(err, out) + } + + out, err := inspectFieldMap("dark_helmet", "Volumes", "/foo/") + if err != nil { + t.Fatal(err) + } + if out != "" { + t.Fatalf("Found unexpected volume entry for '/foo/' in volumes\n%q", out) + } + + out, err = inspectFieldMap("dark_helmet", "Volumes", "/foo") + if err != nil { + t.Fatal(err) + } + if !strings.Contains(out, volumesStoragePath) { + t.Fatalf("Volume was not defined for /foo\n%q", out) + } + + out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar/") + if err != nil { + t.Fatal(err) + } + if out != "" { + t.Fatalf("Found unexpected volume entry for '/bar/' in volumes\n%q", out) + } + out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar") + if err != nil { + t.Fatal(err) + } + if !strings.Contains(out, volumesStoragePath) { + t.Fatalf("Volume was not defined for /bar\n%q", out) + } + + logDone("run - volume paths are cleaned") +} diff --git a/integration-cli/docker_test_vars.go b/integration-cli/docker_test_vars.go index fdbcf073eceb4..23903a39a9e50 100644 --- a/integration-cli/docker_test_vars.go +++ b/integration-cli/docker_test_vars.go @@ -16,8 +16,10 @@ var ( // the private registry to use for tests privateRegistryURL = "127.0.0.1:5000" - execDriverPath = "/var/lib/docker/execdriver/native" - volumesConfigPath = "/var/lib/docker/volumes" + dockerBasePath = "/var/lib/docker" + execDriverPath = dockerBasePath + "/execdriver/native" + volumesConfigPath = dockerBasePath + "/volumes" + volumesStoragePath = dockerBasePath + "/vfs/dir" workingDirectory string ) diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index c3e5361713da5..109014db74974 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -509,6 +509,16 @@ func inspectFieldJSON(name, field string) (string, error) { return strings.TrimSpace(out), nil } +func inspectFieldMap(name, path, field string) (string, error) { + format := fmt.Sprintf("{{index .%s %q}}", path, field) + inspectCmd := exec.Command(dockerBinary, "inspect", "-f", format, name) + out, exitCode, err := runCommandWithOutput(inspectCmd) + if err != nil || exitCode != 0 { + return "", fmt.Errorf("failed to inspect %s: %s", name, out) + } + return strings.TrimSpace(out), nil +} + func getIDByName(name string) (string, error) { return inspectField(name, "Id") } diff --git a/volumes/repository.go b/volumes/repository.go index e765d944c2ca2..2383f34a93b69 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -55,6 +55,7 @@ func (r *Repository) newVolume(path string, writable bool) (*Volume, error) { return nil, err } } + path = filepath.Clean(path) path, err = filepath.EvalSymlinks(path) if err != nil { @@ -126,7 +127,7 @@ func (r *Repository) get(path string) *Volume { if err != nil { return nil } - return r.volumes[path] + return r.volumes[filepath.Clean(path)] } func (r *Repository) Add(volume *Volume) error { @@ -160,7 +161,7 @@ func (r *Repository) Delete(path string) error { if err != nil { return err } - volume := r.get(path) + volume := r.get(filepath.Clean(path)) if volume == nil { return fmt.Errorf("Volume %s does not exist", path) }