Browse code

Fix create volume in a directory which is a symbolic link

Signed-off-by: Lei Jitang <leijitang@huawei.com>

Lei Jitang authored on 2015/03/29 14:35:36
Showing 2 changed files
... ...
@@ -189,10 +189,13 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
189 189
 		if _, exists := container.Volumes[path]; exists {
190 190
 			continue
191 191
 		}
192
-
193
-		if stat, err := os.Stat(filepath.Join(container.basefs, path)); err == nil {
192
+		realpath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, path), container.basefs)
193
+		if err != nil {
194
+			return nil, fmt.Errorf("failed to evaluate the absolute path of symlink")
195
+		}
196
+		if stat, err := os.Stat(realpath); err == nil {
194 197
 			if !stat.IsDir() {
195
-				return nil, fmt.Errorf("file exists at %s, can't create volume there")
198
+				return nil, fmt.Errorf("file exists at %s, can't create volume there", realpath)
196 199
 			}
197 200
 		}
198 201
 
... ...
@@ -477,6 +477,42 @@ func TestRunWithVolumesFromExited(t *testing.T) {
477 477
 	logDone("run - regression test for #4979 - volumes-from on exited container")
478 478
 }
479 479
 
480
+// Test create volume in a dirctory which is a symbolic link
481
+func TestRunCreateVolumesInSymlinkDir(t *testing.T) {
482
+	defer deleteAllContainers()
483
+	// This test has to create a file on host
484
+	hostFile := "/tmp/abcd"
485
+	cmd := exec.Command("touch", hostFile)
486
+	if out, _, err := runCommandWithOutput(cmd); err != nil {
487
+		t.Fatalf("failed to create file %s on host: %v, output: %q", hostFile, err, out)
488
+	}
489
+	defer func() {
490
+		cmd := exec.Command("rm", "-f", hostFile)
491
+		if out, _, err := runCommandWithOutput(cmd); err != nil {
492
+			t.Fatalf("failed to remove file %s on host: %v, output: %q", hostFile, err, out)
493
+		}
494
+	}()
495
+	// create symlink directory /home/test link to /tmp
496
+	cmd = exec.Command(dockerBinary, "run", "--name=test", "busybox", "ln", "-s", "/tmp", "/home/test")
497
+	if out, _, err := runCommandWithOutput(cmd); err != nil {
498
+		t.Fatalf("failed to run container: %v, output: %q", err, out)
499
+	}
500
+	cmd = exec.Command(dockerBinary, "commit", "test", "busybox:test")
501
+	out, _, err := runCommandWithOutput(cmd)
502
+	if err != nil {
503
+		t.Fatalf("failed to commit container: %v, output: %q", err, out)
504
+	}
505
+	cleanedImageID := stripTrailingCharacters(out)
506
+	defer deleteImages(cleanedImageID)
507
+	// directory /home/test is link to /tmp, /home/test/abcd==/tmp/abcd
508
+	cmd = exec.Command(dockerBinary, "run", "-v", "/home/test/abcd", "busybox", "touch", "/home/test/abcd/Hello")
509
+	if out, _, err = runCommandWithOutput(cmd); err != nil {
510
+		t.Fatalf("failed to create volume in symlink directory: %v, output %q", err, out)
511
+	}
512
+
513
+	logDone("run - create volume in symlink directory")
514
+}
515
+
480 516
 // Regression test for #4830
481 517
 func TestRunWithRelativePath(t *testing.T) {
482 518
 	defer deleteAllContainers()