Browse code

Migrate data from old vfs paths to new local volumes path.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/06/04 07:31:20
Showing 2 changed files
... ...
@@ -129,12 +129,25 @@ func TestLoadWithVolume(t *testing.T) {
129 129
 
130 130
 	containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
131 131
 	containerPath := filepath.Join(tmp, containerId)
132
-	if err = os.MkdirAll(containerPath, 0755); err != nil {
132
+	if err := os.MkdirAll(containerPath, 0755); err != nil {
133 133
 		t.Fatal(err)
134 134
 	}
135 135
 
136 136
 	hostVolumeId := stringid.GenerateRandomID()
137
-	volumePath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
137
+	vfsPath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
138
+	volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
139
+
140
+	if err := os.MkdirAll(vfsPath, 0755); err != nil {
141
+		t.Fatal(err)
142
+	}
143
+	if err := os.MkdirAll(volumePath, 0755); err != nil {
144
+		t.Fatal(err)
145
+	}
146
+
147
+	content := filepath.Join(vfsPath, "helo")
148
+	if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
149
+		t.Fatal(err)
150
+	}
138 151
 
139 152
 	config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
140 153
 "Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
... ...
@@ -152,7 +165,7 @@ func TestLoadWithVolume(t *testing.T) {
152 152
 "Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
153 153
 "UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
154 154
 
155
-	cfg := fmt.Sprintf(config, volumePath)
155
+	cfg := fmt.Sprintf(config, vfsPath)
156 156
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
157 157
 		t.Fatal(err)
158 158
 	}
... ...
@@ -200,6 +213,15 @@ func TestLoadWithVolume(t *testing.T) {
200 200
 	if m.Driver != volume.DefaultDriverName {
201 201
 		t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
202 202
 	}
203
+
204
+	newVolumeContent := filepath.Join(volumePath, "helo")
205
+	b, err := ioutil.ReadFile(newVolumeContent)
206
+	if err != nil {
207
+		t.Fatal(err)
208
+	}
209
+	if string(b) != "HELO" {
210
+		t.Fatalf("Expected HELO, was %s\n", string(b))
211
+	}
203 212
 }
204 213
 
205 214
 func TestLoadWithBindMount(t *testing.T) {
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"path/filepath"
9 9
 	"strings"
10 10
 
11
+	"github.com/Sirupsen/logrus"
11 12
 	"github.com/docker/docker/pkg/chrootarchive"
12 13
 	"github.com/docker/docker/runconfig"
13 14
 	"github.com/docker/docker/volume"
... ...
@@ -272,6 +273,9 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
272 272
 
273 273
 		if strings.HasPrefix(hostPath, vfsPath) {
274 274
 			id := filepath.Base(hostPath)
275
+			if err := daemon.migrateVolume(id, hostPath); err != nil {
276
+				return err
277
+			}
275 278
 			container.addLocalMountPoint(id, destination, rw)
276 279
 		} else { // Bind mount
277 280
 			id, source, err := parseVolumeSource(hostPath)
... ...
@@ -287,6 +291,37 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
287 287
 	return container.ToDisk()
288 288
 }
289 289
 
290
+// migrateVolume moves the contents of a volume created pre Docker 1.7
291
+// to the location expected by the local driver. Steps:
292
+// 1. Save old directory that includes old volume's config json file.
293
+// 2. Move virtual directory with content to where the local driver expects it to be.
294
+// 3. Remove the backup of the old volume config.
295
+func (daemon *Daemon) migrateVolume(id, vfs string) error {
296
+	volumeInfo := filepath.Join(daemon.root, defaultVolumesPathName, id)
297
+	backup := filepath.Join(daemon.root, defaultVolumesPathName, id+".back")
298
+
299
+	var err error
300
+	if err = os.Rename(volumeInfo, backup); err != nil {
301
+		return err
302
+	}
303
+	defer func() {
304
+		// Put old configuration back in place in case one of the next steps fails.
305
+		if err != nil {
306
+			os.Rename(backup, volumeInfo)
307
+		}
308
+	}()
309
+
310
+	if err = os.Rename(vfs, volumeInfo); err != nil {
311
+		return err
312
+	}
313
+
314
+	if err = os.RemoveAll(backup); err != nil {
315
+		logrus.Errorf("Unable to remove volume info backup directory %s: %v", backup, err)
316
+	}
317
+
318
+	return nil
319
+}
320
+
290 321
 func createVolume(name, driverName string) (volume.Volume, error) {
291 322
 	vd, err := getVolumeDriver(driverName)
292 323
 	if err != nil {