Browse code

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 authored on 2014/10/07 02:30:42
Showing 2 changed files
... ...
@@ -21,6 +21,7 @@ type Mount struct {
21 21
 	container   *Container
22 22
 	volume      *volumes.Volume
23 23
 	Writable    bool
24
+	copyData    bool
24 25
 }
25 26
 
26 27
 func (container *Container) prepareVolumes() error {
... ...
@@ -75,7 +76,7 @@ func (m *Mount) initialize() error {
75 75
 	m.container.VolumesRW[m.MountToPath] = m.Writable
76 76
 	m.container.Volumes[m.MountToPath] = m.volume.Path
77 77
 	m.volume.AddContainer(m.container.ID)
78
-	if m.Writable && !m.volume.IsBindMount {
78
+	if m.Writable && m.copyData {
79 79
 		// Copy whatever is in the container at the mntToPath to the volume
80 80
 		copyExistingContents(containerMntPath, m.volume.Path)
81 81
 	}
... ...
@@ -115,7 +116,12 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
115 115
 		if err != nil {
116 116
 			return nil, err
117 117
 		}
118
-		mounts[mountToPath] = &Mount{container: container, volume: vol, MountToPath: mountToPath, Writable: writable}
118
+		mounts[mountToPath] = &Mount{
119
+			container:   container,
120
+			volume:      vol,
121
+			MountToPath: mountToPath,
122
+			Writable:    writable,
123
+		}
119 124
 	}
120 125
 
121 126
 	// Get the rest of the volumes
... ...
@@ -129,7 +135,13 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
129 129
 		if err != nil {
130 130
 			return nil, err
131 131
 		}
132
-		mounts[path] = &Mount{container: container, MountToPath: path, volume: vol, Writable: true}
132
+		mounts[path] = &Mount{
133
+			container:   container,
134
+			MountToPath: path,
135
+			volume:      vol,
136
+			Writable:    true,
137
+			copyData:    true,
138
+		}
133 139
 	}
134 140
 
135 141
 	return mounts, nil
... ...
@@ -2303,3 +2303,39 @@ func TestRunReuseBindVolumeThatIsSymlink(t *testing.T) {
2303 2303
 	deleteAllContainers()
2304 2304
 	logDone("run - can remount old bindmount volume")
2305 2305
 }
2306
+
2307
+func TestVolumesNoCopyData(t *testing.T) {
2308
+	defer deleteImages("dataimage")
2309
+	defer deleteAllContainers()
2310
+	if _, err := buildImage("dataimage",
2311
+		`FROM busybox
2312
+		 RUN mkdir -p /foo
2313
+		 RUN touch /foo/bar`,
2314
+		true); err != nil {
2315
+		t.Fatal(err)
2316
+	}
2317
+
2318
+	cmd := exec.Command(dockerBinary, "run", "--name", "test", "-v", "/foo", "busybox")
2319
+	if _, err := runCommand(cmd); err != nil {
2320
+		t.Fatal(err)
2321
+	}
2322
+
2323
+	cmd = exec.Command(dockerBinary, "run", "--volumes-from", "test", "dataimage", "ls", "-lh", "/foo/bar")
2324
+	if out, _, err := runCommandWithOutput(cmd); err == nil || !strings.Contains(out, "No such file or directory") {
2325
+		t.Fatalf("Data was copied on volumes-from but shouldn't be:\n%q", out)
2326
+	}
2327
+
2328
+	tmpDir, err := ioutil.TempDir("", "docker_test_bind_mount_copy_data")
2329
+	if err != nil {
2330
+		t.Fatal(err)
2331
+	}
2332
+
2333
+	defer os.RemoveAll(tmpDir)
2334
+
2335
+	cmd = exec.Command(dockerBinary, "run", "-v", tmpDir+":/foo", "dataimage", "ls", "-lh", "/foo/bar")
2336
+	if out, _, err := runCommandWithOutput(cmd); err == nil || !strings.Contains(out, "No such file or directory") {
2337
+		t.Fatalf("Data was copied on bind-mount but shouldn't be:\n%q", out)
2338
+	}
2339
+
2340
+	logDone("run - volumes do not copy data for volumes-from and bindmounts")
2341
+}