Browse code

Merge pull request #8665 from cpuguy83/8659_clean_paths_for_volumes

Clean volume paths

Tibor Vass authored on 2014/10/22 00:17:03
Showing 5 changed files
... ...
@@ -146,6 +146,7 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
146 146
 	// Get the rest of the volumes
147 147
 	for path := range container.Config.Volumes {
148 148
 		// Check if this is already added as a bind-mount
149
+		path = filepath.Clean(path)
149 150
 		if _, exists := mounts[path]; exists {
150 151
 			continue
151 152
 		}
... ...
@@ -195,6 +196,8 @@ func parseBindMountSpec(spec string) (string, string, bool, error) {
195 195
 		return "", "", false, fmt.Errorf("cannot bind mount volume: %s volume paths must be absolute.", path)
196 196
 	}
197 197
 
198
+	path = filepath.Clean(path)
199
+	mountToPath = filepath.Clean(mountToPath)
198 200
 	return path, mountToPath, writable, nil
199 201
 }
200 202
 
... ...
@@ -2396,3 +2396,53 @@ func TestRunNoOutputFromPullInStdout(t *testing.T) {
2396 2396
 	}
2397 2397
 	logDone("run - no output from pull in stdout")
2398 2398
 }
2399
+
2400
+func TestRunVolumesCleanPaths(t *testing.T) {
2401
+	defer deleteAllContainers()
2402
+
2403
+	if _, err := buildImage("run_volumes_clean_paths",
2404
+		`FROM busybox
2405
+		 VOLUME /foo/`,
2406
+		true); err != nil {
2407
+		t.Fatal(err)
2408
+	}
2409
+	defer deleteImages("run_volumes_clean_paths")
2410
+
2411
+	cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "-v", "/bar/", "--name", "dark_helmet", "run_volumes_clean_paths")
2412
+	if out, _, err := runCommandWithOutput(cmd); err != nil {
2413
+		t.Fatal(err, out)
2414
+	}
2415
+
2416
+	out, err := inspectFieldMap("dark_helmet", "Volumes", "/foo/")
2417
+	if err != nil {
2418
+		t.Fatal(err)
2419
+	}
2420
+	if out != "<no value>" {
2421
+		t.Fatalf("Found unexpected volume entry for '/foo/' in volumes\n%q", out)
2422
+	}
2423
+
2424
+	out, err = inspectFieldMap("dark_helmet", "Volumes", "/foo")
2425
+	if err != nil {
2426
+		t.Fatal(err)
2427
+	}
2428
+	if !strings.Contains(out, volumesStoragePath) {
2429
+		t.Fatalf("Volume was not defined for /foo\n%q", out)
2430
+	}
2431
+
2432
+	out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar/")
2433
+	if err != nil {
2434
+		t.Fatal(err)
2435
+	}
2436
+	if out != "<no value>" {
2437
+		t.Fatalf("Found unexpected volume entry for '/bar/' in volumes\n%q", out)
2438
+	}
2439
+	out, err = inspectFieldMap("dark_helmet", "Volumes", "/bar")
2440
+	if err != nil {
2441
+		t.Fatal(err)
2442
+	}
2443
+	if !strings.Contains(out, volumesStoragePath) {
2444
+		t.Fatalf("Volume was not defined for /bar\n%q", out)
2445
+	}
2446
+
2447
+	logDone("run - volume paths are cleaned")
2448
+}
... ...
@@ -16,8 +16,10 @@ var (
16 16
 	// the private registry to use for tests
17 17
 	privateRegistryURL = "127.0.0.1:5000"
18 18
 
19
-	execDriverPath    = "/var/lib/docker/execdriver/native"
20
-	volumesConfigPath = "/var/lib/docker/volumes"
19
+	dockerBasePath     = "/var/lib/docker"
20
+	execDriverPath     = dockerBasePath + "/execdriver/native"
21
+	volumesConfigPath  = dockerBasePath + "/volumes"
22
+	volumesStoragePath = dockerBasePath + "/vfs/dir"
21 23
 
22 24
 	workingDirectory string
23 25
 )
... ...
@@ -509,6 +509,16 @@ func inspectFieldJSON(name, field string) (string, error) {
509 509
 	return strings.TrimSpace(out), nil
510 510
 }
511 511
 
512
+func inspectFieldMap(name, path, field string) (string, error) {
513
+	format := fmt.Sprintf("{{index .%s %q}}", path, field)
514
+	inspectCmd := exec.Command(dockerBinary, "inspect", "-f", format, name)
515
+	out, exitCode, err := runCommandWithOutput(inspectCmd)
516
+	if err != nil || exitCode != 0 {
517
+		return "", fmt.Errorf("failed to inspect %s: %s", name, out)
518
+	}
519
+	return strings.TrimSpace(out), nil
520
+}
521
+
512 522
 func getIDByName(name string) (string, error) {
513 523
 	return inspectField(name, "Id")
514 524
 }
... ...
@@ -55,6 +55,7 @@ func (r *Repository) newVolume(path string, writable bool) (*Volume, error) {
55 55
 			return nil, err
56 56
 		}
57 57
 	}
58
+	path = filepath.Clean(path)
58 59
 
59 60
 	path, err = filepath.EvalSymlinks(path)
60 61
 	if err != nil {
... ...
@@ -126,7 +127,7 @@ func (r *Repository) get(path string) *Volume {
126 126
 	if err != nil {
127 127
 		return nil
128 128
 	}
129
-	return r.volumes[path]
129
+	return r.volumes[filepath.Clean(path)]
130 130
 }
131 131
 
132 132
 func (r *Repository) Add(volume *Volume) error {
... ...
@@ -160,7 +161,7 @@ func (r *Repository) Delete(path string) error {
160 160
 	if err != nil {
161 161
 		return err
162 162
 	}
163
-	volume := r.get(path)
163
+	volume := r.get(filepath.Clean(path))
164 164
 	if volume == nil {
165 165
 		return fmt.Errorf("Volume %s does not exist", path)
166 166
 	}