[lxc-devel] [lxd/master] Fix migration of containers within projects

stgraber on Github lxc-bot at linuxcontainers.org
Tue Nov 20 05:28:03 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181120/d94e30a5/attachment.bin>
-------------- next part --------------
From 3f79e795596b43a2ee55ea506142dfab8e32d37f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 19 Nov 2018 17:13:01 -0500
Subject: [PATCH 1/8] lxd/containers: Properly clear static leases
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f0a197844b..5822874387 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3480,7 +3480,6 @@ func (c *containerLXC) Delete() error {
 		}
 
 		// Update network files
-		networkUpdateStatic(c.state, "")
 		for k, m := range c.expandedDevices {
 			if m["type"] != "nic" || m["nictype"] != "bridged" {
 				continue
@@ -3515,6 +3514,11 @@ func (c *containerLXC) Delete() error {
 		}
 	}
 
+	if !c.IsSnapshot() {
+		// Remove any static lease file
+		networkUpdateStatic(c.state, "")
+	}
+
 	logger.Info("Deleted container", ctxMap)
 
 	if c.IsSnapshot() {

From 2dd76d08e0c7e7952aef91b5cf58fe6b9ff24643 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 19 Nov 2018 17:33:26 -0500
Subject: [PATCH 2/8] lxd/storage/zfs: Fix project migrations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_zfs.go | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index a915356899..b17dd77968 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -1079,18 +1079,18 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 	snapshotSuffix := ""
 
 	targetName := target.Name()
-	targetDataset := fmt.Sprintf("%s/containers/%s", poolName, targetName)
+	targetDataset := fmt.Sprintf("%s/containers/%s", poolName, projectPrefix(target.Project(), targetName))
 	targetSnapshotDataset := ""
 
 	if sourceIsSnapshot {
 		sourceParentName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(source.Name())
 		snapshotSuffix = fmt.Sprintf("snapshot-%s", sourceSnapOnlyName)
 		sourceDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, sourceParentName, snapshotSuffix)
-		targetSnapshotDataset = fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, targetName, sourceSnapOnlyName)
+		targetSnapshotDataset = fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, projectPrefix(target.Project(), targetName), sourceSnapOnlyName)
 	} else {
 		snapshotSuffix = uuid.NewRandom().String()
-		sourceDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, sourceName, snapshotSuffix)
-		targetSnapshotDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, targetName, snapshotSuffix)
+		sourceDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, projectPrefix(source.Project(), sourceName), snapshotSuffix)
+		targetSnapshotDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, projectPrefix(target.Project(), targetName), snapshotSuffix)
 
 		fs := fmt.Sprintf("containers/%s", projectPrefix(source.Project(), sourceName))
 		err := zfsPoolVolumeSnapshotCreate(poolName, fs, snapshotSuffix)
@@ -2550,9 +2550,9 @@ func (s *zfsMigrationSourceDriver) Snapshots() []container {
 func (s *zfsMigrationSourceDriver) send(conn *websocket.Conn, zfsName string, zfsParent string, readWrapper func(io.ReadCloser) io.ReadCloser) error {
 	sourceParentName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
 	poolName := s.zfs.getOnDiskPoolName()
-	args := []string{"send", fmt.Sprintf("%s/containers/%s@%s", poolName, sourceParentName, zfsName)}
+	args := []string{"send", fmt.Sprintf("%s/containers/%s@%s", poolName, projectPrefix(s.container.Project(), sourceParentName), zfsName)}
 	if zfsParent != "" {
-		args = append(args, "-i", fmt.Sprintf("%s/containers/%s@%s", poolName, s.container.Name(), zfsParent))
+		args = append(args, "-i", fmt.Sprintf("%s/containers/%s@%s", poolName, projectPrefix(s.container.Project(), s.container.Name()), zfsParent))
 	}
 
 	cmd := exec.Command("zfs", args...)
@@ -2617,7 +2617,7 @@ func (s *zfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *op
 	}
 
 	s.runningSnapName = fmt.Sprintf("migration-send-%s", uuid.NewRandom().String())
-	if err := zfsPoolVolumeSnapshotCreate(s.zfs.getOnDiskPoolName(), fmt.Sprintf("containers/%s", s.container.Name()), s.runningSnapName); err != nil {
+	if err := zfsPoolVolumeSnapshotCreate(s.zfs.getOnDiskPoolName(), fmt.Sprintf("containers/%s", projectPrefix(s.container.Project(), s.container.Name())), s.runningSnapName); err != nil {
 		return err
 	}
 
@@ -2631,7 +2631,7 @@ func (s *zfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *op
 
 func (s *zfsMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwlimit string) error {
 	s.stoppedSnapName = fmt.Sprintf("migration-send-%s", uuid.NewRandom().String())
-	if err := zfsPoolVolumeSnapshotCreate(s.zfs.getOnDiskPoolName(), fmt.Sprintf("containers/%s", s.container.Name()), s.stoppedSnapName); err != nil {
+	if err := zfsPoolVolumeSnapshotCreate(s.zfs.getOnDiskPoolName(), fmt.Sprintf("containers/%s", projectPrefix(s.container.Project(), s.container.Name())), s.stoppedSnapName); err != nil {
 		return err
 	}
 
@@ -2645,10 +2645,10 @@ func (s *zfsMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwl
 func (s *zfsMigrationSourceDriver) Cleanup() {
 	poolName := s.zfs.getOnDiskPoolName()
 	if s.stoppedSnapName != "" {
-		zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", s.container.Name()), s.stoppedSnapName)
+		zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", projectPrefix(s.container.Project(), s.container.Name())), s.stoppedSnapName)
 	}
 	if s.runningSnapName != "" {
-		zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", s.container.Name()), s.runningSnapName)
+		zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", projectPrefix(s.container.Project(), s.container.Name())), s.runningSnapName)
 	}
 }
 
@@ -2683,7 +2683,7 @@ func (s *storageZfs) MigrationSource(ct container, containerOnly bool) (Migratio
 	* is that we send the oldest to newest snapshot, hopefully saving on
 	* xfer costs. Then, after all that, we send the container itself.
 	 */
-	snapshots, err := zfsPoolListSnapshots(s.getOnDiskPoolName(), fmt.Sprintf("containers/%s", ct.Name()))
+	snapshots, err := zfsPoolListSnapshots(s.getOnDiskPoolName(), fmt.Sprintf("containers/%s", projectPrefix(ct.Project(), ct.Name())))
 	if err != nil {
 		return nil, err
 	}
@@ -2757,7 +2757,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 	 * of a snapshot also needs tha actual fs that it has snapshotted
 	 * unmounted, so we do this before receiving anything.
 	 */
-	zfsName := fmt.Sprintf("containers/%s", container.Name())
+	zfsName := fmt.Sprintf("containers/%s", projectPrefix(container.Project(), container.Name()))
 	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	if shared.IsMountPoint(containerMntPoint) {
 		err := zfsUmount(poolName, zfsName, containerMntPoint)
@@ -2812,7 +2812,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		}
 
 		wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
-		name := fmt.Sprintf("containers/%s at snapshot-%s", container.Name(), snap.GetName())
+		name := fmt.Sprintf("containers/%s at snapshot-%s", projectPrefix(container.Project(), container.Name()), snap.GetName())
 		if err := zfsRecv(name, wrapper); err != nil {
 			return err
 		}
@@ -2828,7 +2828,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 
 	defer func() {
 		/* clean up our migration-send snapshots that we got from recv. */
-		zfsSnapshots, err := zfsPoolListSnapshots(poolName, fmt.Sprintf("containers/%s", container.Name()))
+		zfsSnapshots, err := zfsPoolListSnapshots(poolName, fmt.Sprintf("containers/%s", projectPrefix(container.Project(), container.Name())))
 		if err != nil {
 			logger.Errorf("Failed listing snapshots post migration: %s", err)
 			return
@@ -2840,7 +2840,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 				continue
 			}
 
-			zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", container.Name()), snap)
+			zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", projectPrefix(container.Project(), container.Name())), snap)
 		}
 	}()
 

From 01d9ebc9df725d3d3eff303e69934bdb28658cc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 19 Nov 2018 19:22:28 -0500
Subject: [PATCH 3/8] tests: Test migration in projects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 test/suites/migration.sh | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/test/suites/migration.sh b/test/suites/migration.sh
index 53f731d515..c5dc1c103d 100644
--- a/test/suites/migration.sh
+++ b/test/suites/migration.sh
@@ -307,6 +307,37 @@ migration() {
   lxc_remote storage volume delete l2:"$remote_pool2" vol2
   lxc_remote storage volume delete l2:"$remote_pool2" vol3
 
+  # Test some migration between projects
+  lxc_remote project create l1:proj -c features.images=false -c features.profiles=false
+  lxc_remote project switch l1 proj
+
+  lxc_remote init testimage l1:c1
+  lxc_remote copy l1:c1 l2:
+  lxc_remote start l2:c1
+  lxc_remote delete l2:c1 -f
+
+  lxc_remote snapshot l1:c1
+  lxc_remote snapshot l1:c1
+  lxc_remote snapshot l1:c1
+  lxc_remote copy l1:c1 l2:
+  lxc_remote start l2:c1
+  lxc_remote stop l2:c1 -f
+  lxc_remote delete l1:c1
+
+  lxc_remote copy l2:c1 l1:
+  lxc_remote start l1:c1
+  lxc_remote delete l1:c1 -f
+
+  lxc_remote delete l2:c1/snap0
+  lxc_remote delete l2:c1/snap1
+  lxc_remote delete l2:c1/snap2
+  lxc_remote copy l2:c1 l1:
+  lxc_remote start l1:c1
+  lxc_remote delete l1:c1 -f
+  lxc_remote delete l2:c1
+
+  lxc_remote project switch l1 default
+
   if ! which criu >/dev/null 2>&1; then
     echo "==> SKIP: live migration with CRIU (missing binary)"
     return

From fbcf4db9342df8f1a792f1dad73bc1f03ccc35d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 19 Nov 2018 19:41:22 -0500
Subject: [PATCH 4/8] lxd/storage/btrfs: Fix project migrations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_btrfs.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 8b810e6a40..19e526f293 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -1018,7 +1018,7 @@ func (s *storageBtrfs) copyContainer(target container, source container) error {
 	}
 	targetContainerSubvolumeName := getContainerMountPoint(target.Project(), s.pool.Name, target.Name())
 
-	containersPath := getContainerMountPoint(source.Project(), s.pool.Name, "")
+	containersPath := getContainerMountPoint("default", s.pool.Name, "")
 	// Ensure that the directories immediately preceding the subvolume directory exist.
 	if !shared.PathExists(containersPath) {
 		err := os.MkdirAll(containersPath, containersDirMode)
@@ -1692,7 +1692,7 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
 
 	// Make a temporary copy of the container
 	sourceVolume := getContainerMountPoint(source.Project(), s.pool.Name, source.Name())
-	containersPath := getContainerMountPoint(source.Project(), s.pool.Name, "")
+	containersPath := getContainerMountPoint("default", s.pool.Name, "")
 	tmpContainerMntPoint, err := ioutil.TempDir(containersPath, source.Name())
 	if err != nil {
 		return err
@@ -2501,7 +2501,7 @@ func (s *btrfsMigrationSourceDriver) send(conn *websocket.Conn, btrfsPath string
 func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string, containerOnly bool) error {
 	_, containerPool, _ := s.container.Storage().GetContainerPoolInfo()
 	containerName := s.container.Name()
-	containersPath := getContainerMountPoint(s.container.Project(), containerPool, "")
+	containersPath := getContainerMountPoint("default", containerPool, "")
 	sourceName := containerName
 
 	// Deal with sending a snapshot to create a container on another LXD

From 9a64dd5c4ab61f5d1f0bd8d7bcf8b070c7064dda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 20 Nov 2018 00:00:29 -0500
Subject: [PATCH 5/8] tests: Fix leftover file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 test/suites/migration.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/suites/migration.sh b/test/suites/migration.sh
index c5dc1c103d..4910cb533f 100644
--- a/test/suites/migration.sh
+++ b/test/suites/migration.sh
@@ -246,6 +246,7 @@ migration() {
   lxc_remote copy l1:c1 l2:c2 --refresh
   lxc_remote start l2:c2
   lxc_remote file pull l2:c2/root/testfile1 .
+  rm testfile1
   lxc_remote stop -f l2:c2
 
   # This will create snapshot c1/snap0

From 7dfc440335b4abb690e27f72495fc3c159d57b60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 20 Nov 2018 00:01:33 -0500
Subject: [PATCH 6/8] lxd/storage/btrfs: Tweak errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_btrfs.go | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 19e526f293..974063132f 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2672,7 +2672,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		// Remove the existing pre-created subvolume
 		err := btrfsSubVolumesDelete(targetPath)
 		if err != nil {
-			logger.Errorf("Failed to delete pre-created BTRFS subvolume: %s", btrfsPath)
+			logger.Errorf("Failed to delete pre-created BTRFS subvolume: %s: %v", btrfsPath, err)
 			return err
 		}
 
@@ -2765,7 +2765,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 	// A little neuroticism.
 	if parentStoragePool == "" {
-		return fmt.Errorf("detected that the container's root device is missing the pool property during BTRFS migration")
+		return fmt.Errorf("Detected that the container's root device is missing the pool property during BTRFS migration")
 	}
 
 	if !containerOnly {
@@ -2810,8 +2810,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 			wrapper := StorageProgressWriter(op, "fs_progress", *snap.Name)
 			err = btrfsRecv(*(snap.Name), tmpSnapshotMntPoint, snapshotMntPoint, true, wrapper)
-			os.RemoveAll(tmpSnapshotMntPoint)
-			if err != nil && !os.IsNotExist(err) {
+			if err != nil {
 				return err
 			}
 		}

From 355e30d1cb68890d526cc4baa7ae39096a759015 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 20 Nov 2018 00:01:49 -0500
Subject: [PATCH 7/8] lxd/storage: Fix snapshot migration with projects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_btrfs.go          | 6 +++---
 lxd/storage_ceph_migration.go | 2 +-
 lxd/storage_migration.go      | 7 ++++---
 lxd/storage_zfs.go            | 2 +-
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 974063132f..63e8d999b5 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2770,7 +2770,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 	if !containerOnly {
 		for _, snap := range snapshots {
-			args := snapshotProtobufToContainerArgs(containerName, snap)
+			args := snapshotProtobufToContainerArgs(container.Project(), containerName, snap)
 
 			// Ensure that snapshot and parent container have the
 			// same storage pool in their local root disk device.
@@ -2797,7 +2797,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 				return err
 			}
 
-			tmpSnapshotMntPoint, err := ioutil.TempDir(containersPath, containerName)
+			tmpSnapshotMntPoint, err := ioutil.TempDir(containersPath, projectPrefix(container.Project(), containerName))
 			if err != nil {
 				return err
 			}
@@ -2824,7 +2824,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 
 	/* finally, do the real container */
 	wrapper := StorageProgressWriter(op, "fs_progress", containerName)
-	tmpContainerMntPoint, err := ioutil.TempDir(containersMntPoint, containerName)
+	tmpContainerMntPoint, err := ioutil.TempDir(containersMntPoint, projectPrefix(container.Project(), containerName))
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index d3b73d22aa..57fd5265d3 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -276,7 +276,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	recvName := fmt.Sprintf("%s/container_%s", s.OSDPoolName, containerName)
 	for _, snap := range snapshots {
 		curSnapName := snap.GetName()
-		args := snapshotProtobufToContainerArgs(containerName, snap)
+		args := snapshotProtobufToContainerArgs(c.Project(), containerName, snap)
 
 		// Ensure that snapshot and parent container have the same
 		// storage pool in their local root disk device.  If the root
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 7b38ff32d9..0aa75ee3be 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -146,7 +146,7 @@ func rsyncMigrationSource(c container, containerOnly bool) (MigrationStorageSour
 	return rsyncStorageSourceDriver{c, snapshots}, nil
 }
 
-func snapshotProtobufToContainerArgs(containerName string, snap *migration.Snapshot) db.ContainerArgs {
+func snapshotProtobufToContainerArgs(project string, containerName string, snap *migration.Snapshot) db.ContainerArgs {
 	config := map[string]string{}
 
 	for _, ent := range snap.LocalConfig {
@@ -173,6 +173,7 @@ func snapshotProtobufToContainerArgs(containerName string, snap *migration.Snaps
 		Name:         name,
 		Profiles:     snap.Profiles,
 		Stateful:     snap.GetStateful(),
+		Project:      project,
 	}
 
 	if snap.GetCreationDate() != 0 {
@@ -258,7 +259,7 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 					continue
 				}
 
-				snapArgs := snapshotProtobufToContainerArgs(container.Name(), snap)
+				snapArgs := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
 
 				// Ensure that snapshot and parent container have the
 				// same storage pool in their local root disk device.
@@ -319,7 +320,7 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 					continue
 				}
 
-				snapArgs := snapshotProtobufToContainerArgs(container.Name(), snap)
+				snapArgs := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
 
 				// Ensure that snapshot and parent container have the
 				// same storage pool in their local root disk device.
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index b17dd77968..d949d9493d 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2793,7 +2793,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 	}
 
 	for _, snap := range snapshots {
-		args := snapshotProtobufToContainerArgs(container.Name(), snap)
+		args := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
 
 		// Ensure that snapshot and parent container have the
 		// same storage pool in their local root disk device.

From dfc23aff0d4681d8270c165a3d8b4fb1c2a4c37b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 20 Nov 2018 00:21:55 -0500
Subject: [PATCH 8/8] lxd/storage/ceph: Fix project migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_ceph_migration.go | 45 +++++++++++++----------------------
 1 file changed, 17 insertions(+), 28 deletions(-)

diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index 57fd5265d3..08c539e89b 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -34,7 +34,7 @@ func (s *rbdMigrationSourceDriver) Cleanup() {
 
 	if s.stoppedSnapName != "" {
 		err := cephRBDSnapshotDelete(s.ceph.ClusterName, s.ceph.OSDPoolName,
-			containerName, storagePoolVolumeTypeNameContainer,
+			projectPrefix(s.container.Project(), containerName), storagePoolVolumeTypeNameContainer,
 			s.stoppedSnapName, s.ceph.UserName)
 		if err != nil {
 			logger.Warnf(`Failed to delete RBD snapshot "%s" of container "%s"`, s.stoppedSnapName, containerName)
@@ -43,7 +43,7 @@ func (s *rbdMigrationSourceDriver) Cleanup() {
 
 	if s.runningSnapName != "" {
 		err := cephRBDSnapshotDelete(s.ceph.ClusterName, s.ceph.OSDPoolName,
-			containerName, storagePoolVolumeTypeNameContainer,
+			projectPrefix(s.container.Project(), containerName), storagePoolVolumeTypeNameContainer,
 			s.runningSnapName, s.ceph.UserName)
 		if err != nil {
 			logger.Warnf(`Failed to delete RBD snapshot "%s" of container "%s"`, s.runningSnapName, containerName)
@@ -55,7 +55,7 @@ func (s *rbdMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwl
 	containerName := s.container.Name()
 	s.stoppedSnapName = fmt.Sprintf("migration-send-%s", uuid.NewRandom().String())
 	err := cephRBDSnapshotCreate(s.ceph.ClusterName, s.ceph.OSDPoolName,
-		containerName, storagePoolVolumeTypeNameContainer,
+		projectPrefix(s.container.Project(), containerName), storagePoolVolumeTypeNameContainer,
 		s.stoppedSnapName, s.ceph.UserName)
 	if err != nil {
 		logger.Errorf(`Failed to create snapshot "%s" for RBD storage volume for image "%s" on storage pool "%s": %s`, s.stoppedSnapName, containerName, s.ceph.pool.Name, err)
@@ -63,7 +63,7 @@ func (s *rbdMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwl
 	}
 
 	cur := fmt.Sprintf("%s/container_%s@%s", s.ceph.OSDPoolName,
-		containerName, s.stoppedSnapName)
+		projectPrefix(s.container.Project(), containerName), s.stoppedSnapName)
 	err = s.rbdSend(conn, cur, s.runningSnapName, nil)
 	if err != nil {
 		logger.Errorf(`Failed to send exported diff of RBD storage volume "%s" from snapshot "%s": %s`, cur, s.runningSnapName, err)
@@ -111,7 +111,7 @@ func (s *rbdMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn,
 			sendSnapName := fmt.Sprintf(
 				"%s/container_%s@%s",
 				s.ceph.OSDPoolName,
-				containerName,
+				projectPrefix(s.container.Project(), containerName),
 				snap)
 
 			wrapper := StorageProgressReader(op, "fs_progress", snap)
@@ -131,7 +131,7 @@ func (s *rbdMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn,
 
 	s.runningSnapName = fmt.Sprintf("migration-send-%s", uuid.NewRandom().String())
 	err := cephRBDSnapshotCreate(s.ceph.ClusterName, s.ceph.OSDPoolName,
-		containerName, storagePoolVolumeTypeNameContainer,
+		projectPrefix(s.container.Project(), containerName), storagePoolVolumeTypeNameContainer,
 		s.runningSnapName, s.ceph.UserName)
 	if err != nil {
 		logger.Errorf(`Failed to create snapshot "%s" for RBD storage volume for image "%s" on storage pool "%s": %s`, s.runningSnapName, containerName, s.ceph.pool.Name, err)
@@ -139,7 +139,7 @@ func (s *rbdMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn,
 	}
 
 	cur := fmt.Sprintf("%s/container_%s@%s", s.ceph.OSDPoolName,
-		containerName, s.runningSnapName)
+		projectPrefix(s.container.Project(), containerName), s.runningSnapName)
 	wrapper := StorageProgressReader(op, "fs_progress", containerName)
 	err = s.rbdSend(conn, cur, lastSnap, wrapper)
 	if err != nil {
@@ -186,7 +186,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool) (Migratio
 	// that we send the oldest to newest snapshot, hopefully saving on xfer
 	// costs. Then, after all that, we send the container itself.
 	snapshots, err := cephRBDVolumeListSnapshots(s.ClusterName,
-		s.OSDPoolName, containerName,
+		s.OSDPoolName, projectPrefix(c.Project(), containerName),
 		storagePoolVolumeTypeNameContainer, s.UserName)
 	if err != nil {
 		if err != db.ErrNoSuchObject {
@@ -246,26 +246,20 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	// set to the correct cluster name for that LXD instance. Yeah, I think
 	// that's actually correct.
 	containerName := c.Name()
-	if !cephRBDVolumeExists(s.ClusterName, s.OSDPoolName, containerName,
-		storagePoolVolumeTypeNameContainer, s.UserName) {
-		err := cephRBDVolumeCreate(s.ClusterName, s.OSDPoolName,
-			containerName, storagePoolVolumeTypeNameContainer, "0",
-			s.UserName)
+	if !cephRBDVolumeExists(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName) {
+		err := cephRBDVolumeCreate(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, "0", s.UserName)
 		if err != nil {
 			logger.Errorf(`Failed to create RBD storage volume "%s" for cluster "%s" in OSD pool "%s" on storage pool "%s": %s`, containerName, s.ClusterName, s.OSDPoolName, s.pool.Name, err)
 			return err
 		}
-		logger.Debugf(`Created RBD storage volume "%s" on storage pool "%s"`,
-			containerName, s.pool.Name)
+		logger.Debugf(`Created RBD storage volume "%s" on storage pool "%s"`, containerName, s.pool.Name)
 	}
 
 	if len(snapshots) > 0 {
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", containerName)
-		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(c.Project(), containerName))
+		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(c.Project(), containerName))
 		if !shared.PathExists(snapshotMntPointSymlink) {
-			err := os.Symlink(
-				snapshotMntPointSymlinkTarget,
-				snapshotMntPointSymlink)
+			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
 				return err
 			}
@@ -273,7 +267,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	}
 
 	// Now we're ready to receive the actual fs.
-	recvName := fmt.Sprintf("%s/container_%s", s.OSDPoolName, containerName)
+	recvName := fmt.Sprintf("%s/container_%s", s.OSDPoolName, projectPrefix(c.Project(), containerName))
 	for _, snap := range snapshots {
 		curSnapName := snap.GetName()
 		args := snapshotProtobufToContainerArgs(c.Project(), containerName, snap)
@@ -313,9 +307,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	}
 
 	defer func() {
-		snaps, err := cephRBDVolumeListSnapshots(s.ClusterName,
-			s.OSDPoolName, containerName,
-			storagePoolVolumeTypeNameContainer, s.UserName)
+		snaps, err := cephRBDVolumeListSnapshots(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName)
 		if err == nil {
 			for _, snap := range snaps {
 				snapOnlyName, _, _ := containerGetParentAndSnapshotName(snap)
@@ -323,10 +315,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 					continue
 				}
 
-				err := cephRBDSnapshotDelete(s.ClusterName,
-					s.OSDPoolName, containerName,
-					storagePoolVolumeTypeNameContainer,
-					snapOnlyName, s.UserName)
+				err := cephRBDSnapshotDelete(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, snapOnlyName, s.UserName)
 				if err != nil {
 					logger.Warnf(`Failed to delete RBD container storage for snapshot "%s" of container "%s"`, snapOnlyName, containerName)
 				}


More information about the lxc-devel mailing list