Ver Fonte

Merge pull request #13728 from calavera/copy_old_volume_content

Migrate data from old vfs paths to new local volumes path.
Michael Crosby há 10 anos atrás
pai
commit
b26428257f
2 ficheiros alterados com 60 adições e 3 exclusões
  1. 25 3
      daemon/daemon_test.go
  2. 35 0
      daemon/volumes.go

+ 25 - 3
daemon/daemon_test.go

@@ -129,12 +129,25 @@ func TestLoadWithVolume(t *testing.T) {
 
 
 	containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
 	containerId := "d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e"
 	containerPath := filepath.Join(tmp, containerId)
 	containerPath := filepath.Join(tmp, containerId)
-	if err = os.MkdirAll(containerPath, 0755); err != nil {
+	if err := os.MkdirAll(containerPath, 0755); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
 	hostVolumeId := stringid.GenerateRandomID()
 	hostVolumeId := stringid.GenerateRandomID()
-	volumePath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
+	vfsPath := filepath.Join(tmp, "vfs", "dir", hostVolumeId)
+	volumePath := filepath.Join(tmp, "volumes", hostVolumeId)
+
+	if err := os.MkdirAll(vfsPath, 0755); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.MkdirAll(volumePath, 0755); err != nil {
+		t.Fatal(err)
+	}
+
+	content := filepath.Join(vfsPath, "helo")
+	if err := ioutil.WriteFile(content, []byte("HELO"), 0644); err != nil {
+		t.Fatal(err)
+	}
 
 
 	config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
 	config := `{"State":{"Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":2464,"ExitCode":0,
 "Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
 "Error":"","StartedAt":"2015-05-26T16:48:53.869308965Z","FinishedAt":"0001-01-01T00:00:00Z"},
@@ -152,7 +165,7 @@ func TestLoadWithVolume(t *testing.T) {
 "Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
 "Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0,
 "UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
 "UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
 
 
-	cfg := fmt.Sprintf(config, volumePath)
+	cfg := fmt.Sprintf(config, vfsPath)
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
 	if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(cfg), 0644); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -200,6 +213,15 @@ func TestLoadWithVolume(t *testing.T) {
 	if m.Driver != volume.DefaultDriverName {
 	if m.Driver != volume.DefaultDriverName {
 		t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
 		t.Fatalf("Expected mount driver local, was %s\n", m.Driver)
 	}
 	}
+
+	newVolumeContent := filepath.Join(volumePath, "helo")
+	b, err := ioutil.ReadFile(newVolumeContent)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(b) != "HELO" {
+		t.Fatalf("Expected HELO, was %s\n", string(b))
+	}
 }
 }
 
 
 func TestLoadWithBindMount(t *testing.T) {
 func TestLoadWithBindMount(t *testing.T) {

+ 35 - 0
daemon/volumes.go

@@ -8,6 +8,7 @@ import (
 	"path/filepath"
 	"path/filepath"
 	"strings"
 	"strings"
 
 
+	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume"
@@ -272,6 +273,9 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
 
 
 		if strings.HasPrefix(hostPath, vfsPath) {
 		if strings.HasPrefix(hostPath, vfsPath) {
 			id := filepath.Base(hostPath)
 			id := filepath.Base(hostPath)
+			if err := daemon.migrateVolume(id, hostPath); err != nil {
+				return err
+			}
 			container.addLocalMountPoint(id, destination, rw)
 			container.addLocalMountPoint(id, destination, rw)
 		} else { // Bind mount
 		} else { // Bind mount
 			id, source, err := parseVolumeSource(hostPath)
 			id, source, err := parseVolumeSource(hostPath)
@@ -287,6 +291,37 @@ func (daemon *Daemon) verifyVolumesInfo(container *Container) error {
 	return container.ToDisk()
 	return container.ToDisk()
 }
 }
 
 
+// migrateVolume moves the contents of a volume created pre Docker 1.7
+// to the location expected by the local driver. Steps:
+// 1. Save old directory that includes old volume's config json file.
+// 2. Move virtual directory with content to where the local driver expects it to be.
+// 3. Remove the backup of the old volume config.
+func (daemon *Daemon) migrateVolume(id, vfs string) error {
+	volumeInfo := filepath.Join(daemon.root, defaultVolumesPathName, id)
+	backup := filepath.Join(daemon.root, defaultVolumesPathName, id+".back")
+
+	var err error
+	if err = os.Rename(volumeInfo, backup); err != nil {
+		return err
+	}
+	defer func() {
+		// Put old configuration back in place in case one of the next steps fails.
+		if err != nil {
+			os.Rename(backup, volumeInfo)
+		}
+	}()
+
+	if err = os.Rename(vfs, volumeInfo); err != nil {
+		return err
+	}
+
+	if err = os.RemoveAll(backup); err != nil {
+		logrus.Errorf("Unable to remove volume info backup directory %s: %v", backup, err)
+	}
+
+	return nil
+}
+
 func createVolume(name, driverName string) (volume.Volume, error) {
 func createVolume(name, driverName string) (volume.Volume, error) {
 	vd, err := getVolumeDriver(driverName)
 	vd, err := getVolumeDriver(driverName)
 	if err != nil {
 	if err != nil {