Browse Source

Clean volume paths
Fixes #8659

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff 10 years ago
parent
commit
964f9965c7

+ 3 - 0
daemon/volumes.go

@@ -133,6 +133,7 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 	// Get the rest of the volumes
 	// Get the rest of the volumes
 	for path := range container.Config.Volumes {
 	for path := range container.Config.Volumes {
 		// Check if this is already added as a bind-mount
 		// Check if this is already added as a bind-mount
+		path = filepath.Clean(path)
 		if _, exists := mounts[path]; exists {
 		if _, exists := mounts[path]; exists {
 			continue
 			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)
 		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
 	return path, mountToPath, writable, nil
 }
 }
 
 

+ 50 - 0
integration-cli/docker_cli_run_test.go

@@ -2396,3 +2396,53 @@ func TestRunNoOutputFromPullInStdout(t *testing.T) {
 	}
 	}
 	logDone("run - no output from pull in stdout")
 	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 != "<no value>" {
+		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 != "<no value>" {
+		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")
+}

+ 4 - 2
integration-cli/docker_test_vars.go

@@ -16,8 +16,10 @@ var (
 	// the private registry to use for tests
 	// the private registry to use for tests
 	privateRegistryURL = "127.0.0.1:5000"
 	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
 	workingDirectory string
 )
 )

+ 10 - 0
integration-cli/docker_utils.go

@@ -509,6 +509,16 @@ func inspectFieldJSON(name, field string) (string, error) {
 	return strings.TrimSpace(out), nil
 	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) {
 func getIDByName(name string) (string, error) {
 	return inspectField(name, "Id")
 	return inspectField(name, "Id")
 }
 }

+ 3 - 2
volumes/repository.go

@@ -55,6 +55,7 @@ func (r *Repository) newVolume(path string, writable bool) (*Volume, error) {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
+	path = filepath.Clean(path)
 
 
 	path, err = filepath.EvalSymlinks(path)
 	path, err = filepath.EvalSymlinks(path)
 	if err != nil {
 	if err != nil {
@@ -126,7 +127,7 @@ func (r *Repository) get(path string) *Volume {
 	if err != nil {
 	if err != nil {
 		return nil
 		return nil
 	}
 	}
-	return r.volumes[path]
+	return r.volumes[filepath.Clean(path)]
 }
 }
 
 
 func (r *Repository) Add(volume *Volume) error {
 func (r *Repository) Add(volume *Volume) error {
@@ -160,7 +161,7 @@ func (r *Repository) Delete(path string) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	volume := r.get(path)
+	volume := r.get(filepath.Clean(path))
 	if volume == nil {
 	if volume == nil {
 		return fmt.Errorf("Volume %s does not exist", path)
 		return fmt.Errorf("Volume %s does not exist", path)
 	}
 	}