Browse Source

Fix #8398 - volumes copying data unexpectedly

Prior to the volumes re-factor, data was not being copied on
volumes-from or host-mounted volumes.
After the re-factor, data was being copied for volumes-from.
This reverts this unintentional change in behavior.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 10 years ago
parent
commit
e95b6fb648
2 changed files with 51 additions and 3 deletions
  1. 15 3
      daemon/volumes.go
  2. 36 0
      integration-cli/docker_cli_run_test.go

+ 15 - 3
daemon/volumes.go

@@ -21,6 +21,7 @@ type Mount struct {
 	container   *Container
 	volume      *volumes.Volume
 	Writable    bool
+	copyData    bool
 }
 
 func (container *Container) prepareVolumes() error {
@@ -75,7 +76,7 @@ func (m *Mount) initialize() error {
 	m.container.VolumesRW[m.MountToPath] = m.Writable
 	m.container.Volumes[m.MountToPath] = m.volume.Path
 	m.volume.AddContainer(m.container.ID)
-	if m.Writable && !m.volume.IsBindMount {
+	if m.Writable && m.copyData {
 		// Copy whatever is in the container at the mntToPath to the volume
 		copyExistingContents(containerMntPath, m.volume.Path)
 	}
@@ -115,7 +116,12 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 		if err != nil {
 			return nil, err
 		}
-		mounts[mountToPath] = &Mount{container: container, volume: vol, MountToPath: mountToPath, Writable: writable}
+		mounts[mountToPath] = &Mount{
+			container:   container,
+			volume:      vol,
+			MountToPath: mountToPath,
+			Writable:    writable,
+		}
 	}
 
 	// Get the rest of the volumes
@@ -129,7 +135,13 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 		if err != nil {
 			return nil, err
 		}
-		mounts[path] = &Mount{container: container, MountToPath: path, volume: vol, Writable: true}
+		mounts[path] = &Mount{
+			container:   container,
+			MountToPath: path,
+			volume:      vol,
+			Writable:    true,
+			copyData:    true,
+		}
 	}
 
 	return mounts, nil

+ 36 - 0
integration-cli/docker_cli_run_test.go

@@ -2303,3 +2303,39 @@ func TestRunReuseBindVolumeThatIsSymlink(t *testing.T) {
 	deleteAllContainers()
 	logDone("run - can remount old bindmount volume")
 }
+
+func TestVolumesNoCopyData(t *testing.T) {
+	defer deleteImages("dataimage")
+	defer deleteAllContainers()
+	if _, err := buildImage("dataimage",
+		`FROM busybox
+		 RUN mkdir -p /foo
+		 RUN touch /foo/bar`,
+		true); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd := exec.Command(dockerBinary, "run", "--name", "test", "-v", "/foo", "busybox")
+	if _, err := runCommand(cmd); err != nil {
+		t.Fatal(err)
+	}
+
+	cmd = exec.Command(dockerBinary, "run", "--volumes-from", "test", "dataimage", "ls", "-lh", "/foo/bar")
+	if out, _, err := runCommandWithOutput(cmd); err == nil || !strings.Contains(out, "No such file or directory") {
+		t.Fatalf("Data was copied on volumes-from but shouldn't be:\n%q", out)
+	}
+
+	tmpDir, err := ioutil.TempDir("", "docker_test_bind_mount_copy_data")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer os.RemoveAll(tmpDir)
+
+	cmd = exec.Command(dockerBinary, "run", "-v", tmpDir+":/foo", "dataimage", "ls", "-lh", "/foo/bar")
+	if out, _, err := runCommandWithOutput(cmd); err == nil || !strings.Contains(out, "No such file or directory") {
+		t.Fatalf("Data was copied on bind-mount but shouldn't be:\n%q", out)
+	}
+
+	logDone("run - volumes do not copy data for volumes-from and bindmounts")
+}