[lxc-devel] [lxd/master] Simplify storage migration function

stgraber on Github lxc-bot at linuxcontainers.org
Wed Nov 28 04:06:08 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/20181128/8c747488/attachment.bin>
-------------- next part --------------
From 232a9a4f54de644922f4991312ae34a390358cfd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 27 Nov 2018 17:06:35 -0500
Subject: [PATCH 1/3] lxd/migration: Simplify MigrationSource
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Move all regular arguments over to MigrationSourceArgs struct.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/migrate.go                 |  6 +++++-
 lxd/migrate_container.go       | 13 +++++++++----
 lxd/migrate_storage_volumes.go |  5 ++++-
 lxd/storage.go                 |  2 +-
 lxd/storage_btrfs.go           | 12 ++++++------
 lxd/storage_ceph_migration.go  | 16 ++++++++--------
 lxd/storage_dir.go             |  4 ++--
 lxd/storage_lvm.go             |  4 ++--
 lxd/storage_migration.go       | 16 ++++++++--------
 lxd/storage_mock.go            |  5 ++---
 lxd/storage_zfs.go             | 16 ++++++++--------
 11 files changed, 55 insertions(+), 44 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index d2589f3a5d..8257a35a68 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -274,7 +274,11 @@ type MigrationSinkArgs struct {
 }
 
 type MigrationSourceArgs struct {
-	// transport specific fields
+	// Container specific fields
+	Container     container
+	ContainerOnly bool
+
+	// Transport specific fields
 	RsyncArgs []string
 	ZfsArgs   []string
 }
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index e911784d38..af0e3e0e6a 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -444,10 +444,15 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 	}
 
 	// Set source args
-	sourceArgs := MigrationSourceArgs{rsyncArgs, zfsArgs}
+	sourceArgs := MigrationSourceArgs{
+		Container:     s.container,
+		ContainerOnly: s.containerOnly,
+		RsyncArgs:     rsyncArgs,
+		ZfsArgs:       zfsArgs,
+	}
 
 	// Initialize storage driver
-	driver, fsErr := s.container.Storage().MigrationSource(s.container, s.containerOnly, sourceArgs)
+	driver, fsErr := s.container.Storage().MigrationSource(sourceArgs)
 	if fsErr != nil {
 		s.sendControl(fsErr)
 		return fsErr
@@ -459,9 +464,9 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 		header.Fs = &myType
 
 		if header.GetRefresh() {
-			driver, _ = rsyncRefreshSource(s.container, s.containerOnly, header.GetSnapshotNames(), sourceArgs)
+			driver, _ = rsyncRefreshSource(header.GetSnapshotNames(), sourceArgs)
 		} else {
-			driver, _ = rsyncMigrationSource(s.container, s.containerOnly, sourceArgs)
+			driver, _ = rsyncMigrationSource(sourceArgs)
 		}
 
 		// Check if this storage pool has a rate limit set for rsync.
diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 66c8978873..991d133044 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -110,7 +110,10 @@ func (s *migrationSourceWs) DoStorage(migrateOp *operation) error {
 	}
 
 	// Set source args
-	sourceArgs := MigrationSourceArgs{rsyncArgs, zfsArgs}
+	sourceArgs := MigrationSourceArgs{
+		RsyncArgs: rsyncArgs,
+		ZfsArgs:   zfsArgs,
+	}
 
 	driver, fsErr := s.storage.StorageMigrationSource(sourceArgs)
 	if fsErr != nil {
diff --git a/lxd/storage.go b/lxd/storage.go
index b394968d8d..52b0bef699 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -232,7 +232,7 @@ type storage interface {
 	// We leave sending containers which are snapshots of other containers
 	// already present on the target instance as an exercise for the
 	// enterprising developer.
-	MigrationSource(c container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error)
+	MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error)
 	MigrationSink(
 		live bool,
 		c container,
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 3325fa0ea7..1b797a73a4 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2625,9 +2625,9 @@ func (s *storageBtrfs) PreservesInodes() bool {
 	return true
 }
 
-func (s *storageBtrfs) MigrationSource(c container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+func (s *storageBtrfs) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
 	if s.s.OS.RunningInUserNS {
-		return rsyncMigrationSource(c, containerOnly, args)
+		return rsyncMigrationSource(args)
 	}
 
 	/* List all the snapshots in order of reverse creation. The idea here
@@ -2636,21 +2636,21 @@ func (s *storageBtrfs) MigrationSource(c container, containerOnly bool, args Mig
 	 */
 	var err error
 	var snapshots = []container{}
-	if !containerOnly {
-		snapshots, err = c.Snapshots()
+	if !args.ContainerOnly {
+		snapshots, err = args.Container.Snapshots()
 		if err != nil {
 			return nil, err
 		}
 	}
 
 	driver := &btrfsMigrationSourceDriver{
-		container:          c,
+		container:          args.Container,
 		snapshots:          snapshots,
 		btrfsSnapshotNames: []string{},
 		btrfs:              s,
 	}
 
-	if !containerOnly {
+	if !args.ContainerOnly {
 		for _, snap := range snapshots {
 			btrfsPath := getSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			driver.btrfsSnapshotNames = append(driver.btrfsSnapshotNames, btrfsPath)
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index 6abd4d76af..f9951328f9 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -159,25 +159,25 @@ func (s *storageCeph) PreservesInodes() bool {
 	return false
 }
 
-func (s *storageCeph) MigrationSource(c container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+func (s *storageCeph) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
 	// If the container is a snapshot, let's just send that. We don't need
 	// to send anything else, because that's all the user asked for.
-	if c.IsSnapshot() {
+	if args.Container.IsSnapshot() {
 		return &rbdMigrationSourceDriver{
-			container: c,
+			container: args.Container,
 			ceph:      s,
 		}, nil
 	}
 
 	driver := rbdMigrationSourceDriver{
-		container:        c,
+		container:        args.Container,
 		snapshots:        []container{},
 		rbdSnapshotNames: []string{},
 		ceph:             s,
 	}
 
-	containerName := c.Name()
-	if containerOnly {
+	containerName := args.Container.Name()
+	if args.ContainerOnly {
 		logger.Debugf(`Only migrating the RBD storage volume for container "%s" on storage pool "%s`, containerName, s.pool.Name)
 		return &driver, nil
 	}
@@ -186,7 +186,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool, args Migr
 	// 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, projectPrefix(c.Project(), containerName),
+		s.OSDPoolName, projectPrefix(args.Container.Project(), containerName),
 		storagePoolVolumeTypeNameContainer, s.UserName)
 	if err != nil {
 		if err != db.ErrNoSuchObject {
@@ -206,7 +206,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool, args Migr
 		}
 
 		lxdName := fmt.Sprintf("%s%s%s", containerName, shared.SnapshotDelimiter, snap[len("snapshot_"):])
-		snapshot, err := containerLoadByProjectAndName(s.s, c.Project(), lxdName)
+		snapshot, err := containerLoadByProjectAndName(s.s, args.Container.Project(), lxdName)
 		if err != nil {
 			logger.Errorf(`Failed to load snapshot "%s" for RBD storage volume "%s" on storage pool "%s": %s`, lxdName, containerName, s.pool.Name, err)
 			return nil, err
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 20059b4993..bc9a6c014f 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1272,8 +1272,8 @@ func (s *storageDir) PreservesInodes() bool {
 	return false
 }
 
-func (s *storageDir) MigrationSource(container container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
-	return rsyncMigrationSource(container, containerOnly, args)
+func (s *storageDir) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+	return rsyncMigrationSource(args)
 }
 
 func (s *storageDir) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index a2b5df8d82..505afe2c83 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2069,8 +2069,8 @@ func (s *storageLvm) PreservesInodes() bool {
 	return false
 }
 
-func (s *storageLvm) MigrationSource(container container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
-	return rsyncMigrationSource(container, containerOnly, args)
+func (s *storageLvm) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+	return rsyncMigrationSource(args)
 }
 
 func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index c7e7c8e972..3064bfa5d7 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -113,10 +113,10 @@ func rsyncStorageMigrationSource(args MigrationSourceArgs) (MigrationStorageSour
 	return rsyncStorageSourceDriver{nil, nil, args.RsyncArgs}, nil
 }
 
-func rsyncRefreshSource(c container, containerOnly bool, refreshSnapshots []string, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+func rsyncRefreshSource(refreshSnapshots []string, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
 	var snapshots = []container{}
-	if !containerOnly {
-		allSnapshots, err := c.Snapshots()
+	if !args.ContainerOnly {
+		allSnapshots, err := args.Container.Snapshots()
 		if err != nil {
 			return nil, err
 		}
@@ -131,20 +131,20 @@ func rsyncRefreshSource(c container, containerOnly bool, refreshSnapshots []stri
 		}
 	}
 
-	return rsyncStorageSourceDriver{c, snapshots, args.RsyncArgs}, nil
+	return rsyncStorageSourceDriver{args.Container, snapshots, args.RsyncArgs}, nil
 }
 
-func rsyncMigrationSource(c container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+func rsyncMigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
 	var err error
 	var snapshots = []container{}
-	if !containerOnly {
-		snapshots, err = c.Snapshots()
+	if !args.ContainerOnly {
+		snapshots, err = args.Container.Snapshots()
 		if err != nil {
 			return nil, err
 		}
 	}
 
-	return rsyncStorageSourceDriver{c, snapshots, args.RsyncArgs}, nil
+	return rsyncStorageSourceDriver{args.Container, snapshots, args.RsyncArgs}, nil
 }
 
 func snapshotProtobufToContainerArgs(project string, containerName string, snap *migration.Snapshot) db.ContainerArgs {
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index d7757612f4..897ec9a2e8 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"io"
 
 	"github.com/gorilla/websocket"
@@ -226,8 +225,8 @@ func (s *storageMock) PreservesInodes() bool {
 	return false
 }
 
-func (s *storageMock) MigrationSource(container container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
-	return nil, fmt.Errorf("not implemented")
+func (s *storageMock) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+	return nil, nil
 }
 
 func (s *storageMock) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index a008909172..3cf2c7e543 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2663,23 +2663,23 @@ func (s *storageZfs) PreservesInodes() bool {
 	return true
 }
 
-func (s *storageZfs) MigrationSource(ct container, containerOnly bool, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
+func (s *storageZfs) MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
 	/* If the container is a snapshot, let's just send that; we don't need
 	* to send anything else, because that's all the user asked for.
 	 */
-	if ct.IsSnapshot() {
-		return &zfsMigrationSourceDriver{container: ct, zfs: s, zfsArgs: args.ZfsArgs}, nil
+	if args.Container.IsSnapshot() {
+		return &zfsMigrationSourceDriver{container: args.Container, zfs: s, zfsArgs: args.ZfsArgs}, nil
 	}
 
 	driver := zfsMigrationSourceDriver{
-		container:        ct,
+		container:        args.Container,
 		snapshots:        []container{},
 		zfsSnapshotNames: []string{},
 		zfs:              s,
 		zfsArgs:          args.ZfsArgs,
 	}
 
-	if containerOnly {
+	if args.ContainerOnly {
 		return &driver, nil
 	}
 
@@ -2687,7 +2687,7 @@ func (s *storageZfs) MigrationSource(ct container, containerOnly bool, args Migr
 	* 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", projectPrefix(ct.Project(), ct.Name())))
+	snapshots, err := zfsPoolListSnapshots(s.getOnDiskPoolName(), fmt.Sprintf("containers/%s", projectPrefix(args.Container.Project(), args.Container.Name())))
 	if err != nil {
 		return nil, err
 	}
@@ -2702,8 +2702,8 @@ func (s *storageZfs) MigrationSource(ct container, containerOnly bool, args Migr
 			continue
 		}
 
-		lxdName := fmt.Sprintf("%s%s%s", ct.Name(), shared.SnapshotDelimiter, snap[len("snapshot-"):])
-		snapshot, err := containerLoadByProjectAndName(s.s, ct.Project(), lxdName)
+		lxdName := fmt.Sprintf("%s%s%s", args.Container.Name(), shared.SnapshotDelimiter, snap[len("snapshot-"):])
+		snapshot, err := containerLoadByProjectAndName(s.s, args.Container.Project(), lxdName)
 		if err != nil {
 			return nil, err
 		}

From a46f1956c58b4a80445de62dc7cf873b919af351 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 27 Nov 2018 17:57:36 -0500
Subject: [PATCH 2/3] lxd/migration: Simplify StorageMigrationSink
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/migrate.go                 | 12 ++++++------
 lxd/migrate_storage_volumes.go | 18 +++++++++++-------
 lxd/storage.go                 |  2 +-
 lxd/storage_btrfs.go           |  4 ++--
 lxd/storage_ceph.go            |  4 ++--
 lxd/storage_dir.go             |  4 ++--
 lxd/storage_lvm.go             |  4 ++--
 lxd/storage_migration.go       | 12 ++++++------
 lxd/storage_mock.go            |  2 +-
 lxd/storage_zfs.go             |  4 ++--
 10 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index 8257a35a68..a7133a8b65 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -254,23 +254,23 @@ type migrationSink struct {
 }
 
 type MigrationSinkArgs struct {
+	// General migration fields
 	Url     string
 	Dialer  websocket.Dialer
 	Secrets map[string]string
 	Push    bool
 
-	// container specific fields
-	Live          bool
+	// Container specific fields
 	Container     container
 	ContainerOnly bool
+	Live          bool
+	Refresh       bool
 
-	// storage specific fields
+	// Storage specific fields
 	Storage storage
 
-	// transport specific fields
+	// Transport specific fields
 	RsyncArgs []string
-
-	Refresh bool
 }
 
 type MigrationSourceArgs struct {
diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 991d133044..3d0f76b836 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -288,20 +288,24 @@ func (c *migrationSink) DoStorage(migrateOp *operation) error {
 		resp.Fs = &myType
 	}
 
-	args := MigrationSinkArgs{}
 	rsyncFeatures := header.GetRsyncFeatures()
 
 	// Handle rsync options
-	args.RsyncArgs = []string{}
+	rsyncArgs := []string{}
 	if rsyncFeatures.GetXattrs() {
-		args.RsyncArgs = append(args.RsyncArgs, "--xattrs")
+		rsyncArgs = append(rsyncArgs, "--xattrs")
 	}
 	if rsyncFeatures.GetDelete() {
-		args.RsyncArgs = append(args.RsyncArgs, "--delete")
+		rsyncArgs = append(rsyncArgs, "--delete")
 	}
 	if rsyncFeatures.GetCompress() {
-		args.RsyncArgs = append(args.RsyncArgs, "--compress")
-		args.RsyncArgs = append(args.RsyncArgs, "--compress-level=2")
+		rsyncArgs = append(rsyncArgs, "--compress")
+		rsyncArgs = append(rsyncArgs, "--compress-level=2")
+	}
+
+	args := MigrationSinkArgs{
+		Storage:   c.dest.storage,
+		RsyncArgs: rsyncArgs,
 	}
 
 	err = sender(&resp)
@@ -318,7 +322,7 @@ func (c *migrationSink) DoStorage(migrateOp *operation) error {
 		fsConn = c.src.fsConn
 	}
 
-	err = mySink(fsConn, migrateOp, c.dest.storage, args)
+	err = mySink(fsConn, migrateOp, args)
 	if err != nil {
 		logger.Errorf("Failed to start storage volume migration sink")
 		controller(err)
diff --git a/lxd/storage.go b/lxd/storage.go
index 52b0bef699..a43632c501 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -244,7 +244,7 @@ type storage interface {
 		args MigrationSinkArgs) error
 
 	StorageMigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error)
-	StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error
+	StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error
 }
 
 func storageCoreInit(driver string) (storage, error) {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 1b797a73a4..331a86b5ab 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -3042,8 +3042,8 @@ func (s *storageBtrfs) StorageMigrationSource(args MigrationSourceArgs) (Migrati
 	return rsyncStorageMigrationSource(args)
 }
 
-func (s *storageBtrfs) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	return rsyncStorageMigrationSink(conn, op, storage, args)
+func (s *storageBtrfs) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncStorageMigrationSink(conn, op, args)
 }
 
 func (s *storageBtrfs) GetStoragePool() *api.StoragePool {
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 2382757dab..c141c26974 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2738,8 +2738,8 @@ func (s *storageCeph) StorageMigrationSource(args MigrationSourceArgs) (Migratio
 	return rsyncStorageMigrationSource(args)
 }
 
-func (s *storageCeph) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	return rsyncStorageMigrationSink(conn, op, storage, args)
+func (s *storageCeph) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncStorageMigrationSink(conn, op, args)
 }
 
 func (s *storageCeph) GetStoragePool() *api.StoragePool {
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index bc9a6c014f..b13c66a83d 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1359,8 +1359,8 @@ func (s *storageDir) StorageMigrationSource(args MigrationSourceArgs) (Migration
 	return rsyncStorageMigrationSource(args)
 }
 
-func (s *storageDir) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	return rsyncStorageMigrationSink(conn, op, storage, args)
+func (s *storageDir) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncStorageMigrationSink(conn, op, args)
 }
 
 func (s *storageDir) GetStoragePool() *api.StoragePool {
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 505afe2c83..7ed618b7fe 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2282,8 +2282,8 @@ func (s *storageLvm) StorageMigrationSource(args MigrationSourceArgs) (Migration
 	return rsyncStorageMigrationSource(args)
 }
 
-func (s *storageLvm) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	return rsyncStorageMigrationSink(conn, op, storage, args)
+func (s *storageLvm) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncStorageMigrationSink(conn, op, args)
 }
 
 func (s *storageLvm) GetStoragePool() *api.StoragePool {
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 3064bfa5d7..379a09be61 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -188,22 +188,22 @@ func snapshotProtobufToContainerArgs(project string, containerName string, snap
 	return args
 }
 
-func rsyncStorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	err := storage.StoragePoolVolumeCreate()
+func rsyncStorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	err := args.Storage.StoragePoolVolumeCreate()
 	if err != nil {
 		return err
 	}
 
-	ourMount, err := storage.StoragePoolVolumeMount()
+	ourMount, err := args.Storage.StoragePoolVolumeMount()
 	if err != nil {
 		return err
 	}
 	if ourMount {
-		defer storage.StoragePoolVolumeUmount()
+		defer args.Storage.StoragePoolVolumeUmount()
 	}
 
-	pool := storage.GetStoragePool()
-	volume := storage.GetStoragePoolVolume()
+	pool := args.Storage.GetStoragePool()
+	volume := args.Storage.GetStoragePoolVolume()
 
 	wrapper := StorageProgressWriter(op, "fs_progress", volume.Name)
 	path := getStoragePoolVolumeMountPoint(pool.Name, volume.Name)
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 897ec9a2e8..dca8827238 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -249,7 +249,7 @@ func (s *storageMock) StorageMigrationSource(args MigrationSourceArgs) (Migratio
 	return nil, nil
 }
 
-func (s *storageMock) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
+func (s *storageMock) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
 	return nil
 }
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 3cf2c7e543..e3ada9b2e3 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -3251,8 +3251,8 @@ func (s *storageZfs) StorageMigrationSource(args MigrationSourceArgs) (Migration
 	return rsyncStorageMigrationSource(args)
 }
 
-func (s *storageZfs) StorageMigrationSink(conn *websocket.Conn, op *operation, storage storage, args MigrationSinkArgs) error {
-	return rsyncStorageMigrationSink(conn, op, storage, args)
+func (s *storageZfs) StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncStorageMigrationSink(conn, op, args)
 }
 
 func (s *storageZfs) GetStoragePool() *api.StoragePool {

From 4ef6e87c5885b2c6d11a099036dc84a5e67ea322 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 27 Nov 2018 22:40:51 -0500
Subject: [PATCH 3/3] lxd/migration: Simplify MigrationSink
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/migrate.go                |  7 +++--
 lxd/migrate_container.go      | 13 +++++---
 lxd/storage.go                | 10 +-----
 lxd/storage_btrfs.go          | 51 +++++++++++++++---------------
 lxd/storage_ceph_migration.go | 47 +++++++++++++---------------
 lxd/storage_dir.go            |  5 ++-
 lxd/storage_lvm.go            |  5 ++-
 lxd/storage_migration.go      | 59 +++++++++++++++++------------------
 lxd/storage_mock.go           |  3 +-
 lxd/storage_zfs.go            | 43 +++++++++++++------------
 10 files changed, 116 insertions(+), 127 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index a7133a8b65..2b4bcc2437 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -20,6 +20,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -255,16 +256,18 @@ type migrationSink struct {
 
 type MigrationSinkArgs struct {
 	// General migration fields
-	Url     string
 	Dialer  websocket.Dialer
-	Secrets map[string]string
 	Push    bool
+	Secrets map[string]string
+	Url     string
 
 	// Container specific fields
 	Container     container
 	ContainerOnly bool
+	Idmap         *idmap.IdmapSet
 	Live          bool
 	Refresh       bool
+	Snapshots     []*migration.Snapshot
 
 	// Storage specific fields
 	Storage storage
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index af0e3e0e6a..a3dae97243 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -999,13 +999,16 @@ func (c *migrationSink) Do(migrateOp *operation) error {
 			}
 
 			args := MigrationSinkArgs{
-				Refresh:   c.refresh,
-				RsyncArgs: c.rsyncArgs,
+				Container:     c.src.container,
+				ContainerOnly: c.src.containerOnly,
+				Idmap:         srcIdmap,
+				Live:          sendFinalFsDelta,
+				Refresh:       c.refresh,
+				RsyncArgs:     c.rsyncArgs,
+				Snapshots:     snapshots,
 			}
 
-			err = mySink(sendFinalFsDelta, c.src.container,
-				snapshots, fsConn, srcIdmap, migrateOp,
-				c.src.containerOnly, args)
+			err = mySink(fsConn, migrateOp, args)
 			if err != nil {
 				fsTransfer <- err
 				return
diff --git a/lxd/storage.go b/lxd/storage.go
index a43632c501..3b2dca1ddc 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -233,15 +233,7 @@ type storage interface {
 	// already present on the target instance as an exercise for the
 	// enterprising developer.
 	MigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error)
-	MigrationSink(
-		live bool,
-		c container,
-		objects []*migration.Snapshot,
-		conn *websocket.Conn,
-		srcIdmap *idmap.IdmapSet,
-		op *operation,
-		containerOnly bool,
-		args MigrationSinkArgs) error
+	MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error
 
 	StorageMigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error)
 	StorageMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 331a86b5ab..7c423976c3 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -22,7 +22,6 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -2660,9 +2659,9 @@ func (s *storageBtrfs) MigrationSource(args MigrationSourceArgs) (MigrationStora
 	return driver, nil
 }
 
-func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
+func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
 	if s.s.OS.RunningInUserNS {
-		return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly, args)
+		return rsyncMigrationSink(conn, op, args)
 	}
 
 	btrfsRecv := func(snapName string, btrfsPath string, targetPath string, isSnapshot bool, writeWrapper func(io.WriteCloser) io.WriteCloser) error {
@@ -2734,17 +2733,17 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		return nil
 	}
 
-	containerName := container.Name()
-	_, containerPool, _ := container.Storage().GetContainerPoolInfo()
-	containersPath := getSnapshotMountPoint(container.Project(), containerPool, containerName)
-	if !containerOnly && len(snapshots) > 0 {
+	containerName := args.Container.Name()
+	_, containerPool, _ := args.Container.Storage().GetContainerPoolInfo()
+	containersPath := getSnapshotMountPoint(args.Container.Project(), containerPool, containerName)
+	if !args.ContainerOnly && len(args.Snapshots) > 0 {
 		err := os.MkdirAll(containersPath, containersDirMode)
 		if err != nil {
 			return err
 		}
 
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", containerPool, "containers-snapshots", projectPrefix(container.Project(), containerName))
-		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(container.Project(), containerName))
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", containerPool, "containers-snapshots", projectPrefix(args.Container.Project(), containerName))
+		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(args.Container.Project(), containerName))
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
@@ -2757,7 +2756,7 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 	// container's root disk device so we can simply
 	// retrieve it from the expanded devices.
 	parentStoragePool := ""
-	parentExpandedDevices := container.ExpandedDevices()
+	parentExpandedDevices := args.Container.ExpandedDevices()
 	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := shared.GetRootDiskDevice(parentExpandedDevices)
 	if parentLocalRootDiskDeviceKey != "" {
 		parentStoragePool = parentLocalRootDiskDevice["pool"]
@@ -2768,36 +2767,36 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		return fmt.Errorf("Detected that the container's root device is missing the pool property during BTRFS migration")
 	}
 
-	if !containerOnly {
-		for _, snap := range snapshots {
-			args := snapshotProtobufToContainerArgs(container.Project(), containerName, snap)
+	if !args.ContainerOnly {
+		for _, snap := range args.Snapshots {
+			ctArgs := snapshotProtobufToContainerArgs(args.Container.Project(), containerName, snap)
 
 			// Ensure that snapshot and parent container have the
 			// same storage pool in their local root disk device.
 			// If the root disk device for the snapshot comes from a
 			// profile on the new instance as well we don't need to
 			// do anything.
-			if args.Devices != nil {
-				snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(args.Devices)
+			if ctArgs.Devices != nil {
+				snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(ctArgs.Devices)
 				if snapLocalRootDiskDeviceKey != "" {
-					args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
+					ctArgs.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 				}
 			}
 
-			snapshotMntPoint := getSnapshotMountPoint(container.Project(), containerPool, args.Name)
-			_, err := containerCreateEmptySnapshot(container.DaemonState(), args)
+			snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), containerPool, ctArgs.Name)
+			_, err := containerCreateEmptySnapshot(args.Container.DaemonState(), ctArgs)
 			if err != nil {
 				return err
 			}
 
-			snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(container.Project(), containerName))
-			snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(container.Project(), containerName))
+			snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(args.Container.Project(), containerName))
+			snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(args.Container.Project(), containerName))
 			err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
 				return err
 			}
 
-			tmpSnapshotMntPoint, err := ioutil.TempDir(containersPath, projectPrefix(container.Project(), containerName))
+			tmpSnapshotMntPoint, err := ioutil.TempDir(containersPath, projectPrefix(args.Container.Project(), containerName))
 			if err != nil {
 				return err
 			}
@@ -2816,15 +2815,15 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		}
 	}
 
-	containersMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, "")
-	err := createContainerMountpoint(containersMntPoint, container.Path(), container.IsPrivileged())
+	containersMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, "")
+	err := createContainerMountpoint(containersMntPoint, args.Container.Path(), args.Container.IsPrivileged())
 	if err != nil {
 		return err
 	}
 
 	/* finally, do the real container */
 	wrapper := StorageProgressWriter(op, "fs_progress", containerName)
-	tmpContainerMntPoint, err := ioutil.TempDir(containersMntPoint, projectPrefix(container.Project(), containerName))
+	tmpContainerMntPoint, err := ioutil.TempDir(containersMntPoint, projectPrefix(args.Container.Project(), containerName))
 	if err != nil {
 		return err
 	}
@@ -2835,13 +2834,13 @@ func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots [
 		return err
 	}
 
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
 	err = btrfsRecv("", tmpContainerMntPoint, containerMntPoint, false, wrapper)
 	if err != nil {
 		return err
 	}
 
-	if live {
+	if args.Live {
 		err = btrfsRecv("", tmpContainerMntPoint, containerMntPoint, false, wrapper)
 		if err != nil {
 			return err
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index f9951328f9..5f3e441888 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -10,7 +10,6 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 
 	"github.com/pborman/uuid"
@@ -219,13 +218,11 @@ func (s *storageCeph) MigrationSource(args MigrationSourceArgs) (MigrationStorag
 	return &driver, nil
 }
 
-func (s *storageCeph) MigrationSink(live bool, c container,
-	snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet,
-	op *operation, containerOnly bool, args MigrationSinkArgs) error {
+func (s *storageCeph) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
 	// Check that we received a valid root disk device with a pool property
 	// set.
 	parentStoragePool := ""
-	parentExpandedDevices := c.ExpandedDevices()
+	parentExpandedDevices := args.Container.ExpandedDevices()
 	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := shared.GetRootDiskDevice(parentExpandedDevices)
 	if parentLocalRootDiskDeviceKey != "" {
 		parentStoragePool = parentLocalRootDiskDevice["pool"]
@@ -245,9 +242,9 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	// the receiving LXD instance it also means that s.ClusterName has been
 	// 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, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName) {
-		err := cephRBDVolumeCreate(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, "0", s.UserName)
+	containerName := args.Container.Name()
+	if !cephRBDVolumeExists(s.ClusterName, s.OSDPoolName, projectPrefix(args.Container.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName) {
+		err := cephRBDVolumeCreate(s.ClusterName, s.OSDPoolName, projectPrefix(args.Container.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
@@ -255,9 +252,9 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 		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", projectPrefix(c.Project(), containerName))
-		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(c.Project(), containerName))
+	if len(args.Snapshots) > 0 {
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(args.Container.Project(), containerName))
+		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(args.Container.Project(), containerName))
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
@@ -267,22 +264,22 @@ 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, projectPrefix(c.Project(), containerName))
-	for _, snap := range snapshots {
+	recvName := fmt.Sprintf("%s/container_%s", s.OSDPoolName, projectPrefix(args.Container.Project(), containerName))
+	for _, snap := range args.Snapshots {
 		curSnapName := snap.GetName()
-		args := snapshotProtobufToContainerArgs(c.Project(), containerName, snap)
+		ctArgs := snapshotProtobufToContainerArgs(args.Container.Project(), containerName, snap)
 
 		// Ensure that snapshot and parent container have the same
 		// storage pool in their local root disk device.  If the root
 		// disk device for the snapshot comes from a profile on the new
 		// instance as well we don't need to do anything.
-		if args.Devices != nil {
-			snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(args.Devices)
+		if ctArgs.Devices != nil {
+			snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(ctArgs.Devices)
 			if snapLocalRootDiskDeviceKey != "" {
-				args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
+				ctArgs.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 			}
 		}
-		_, err := containerCreateEmptySnapshot(c.DaemonState(), args)
+		_, err := containerCreateEmptySnapshot(args.Container.DaemonState(), ctArgs)
 		if err != nil {
 			logger.Errorf(`Failed to create empty RBD storage volume for container "%s" on storage pool "%s: %s`, containerName, s.OSDPoolName, err)
 			return err
@@ -297,7 +294,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 		}
 		logger.Debugf(`Received RBD storage volume "%s"`, curSnapName)
 
-		snapshotMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, fmt.Sprintf("%s/%s", containerName, *snap.Name))
+		snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), s.pool.Name, fmt.Sprintf("%s/%s", containerName, *snap.Name))
 		if !shared.PathExists(snapshotMntPoint) {
 			err := os.MkdirAll(snapshotMntPoint, 0700)
 			if err != nil {
@@ -307,7 +304,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	}
 
 	defer func() {
-		snaps, err := cephRBDVolumeListSnapshots(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName)
+		snaps, err := cephRBDVolumeListSnapshots(s.ClusterName, s.OSDPoolName, projectPrefix(args.Container.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName)
 		if err == nil {
 			for _, snap := range snaps {
 				snapOnlyName, _, _ := containerGetParentAndSnapshotName(snap)
@@ -315,7 +312,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 					continue
 				}
 
-				err := cephRBDSnapshotDelete(s.ClusterName, s.OSDPoolName, projectPrefix(c.Project(), containerName), storagePoolVolumeTypeNameContainer, snapOnlyName, s.UserName)
+				err := cephRBDSnapshotDelete(s.ClusterName, s.OSDPoolName, projectPrefix(args.Container.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)
 				}
@@ -332,7 +329,7 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 	}
 	logger.Debugf(`Received RBD storage volume "%s"`, recvName)
 
-	if live {
+	if args.Live {
 		err := s.rbdRecv(conn, recvName, wrapper)
 		if err != nil {
 			logger.Errorf(`Failed to receive RBD storage volume "%s": %s`, recvName, err)
@@ -341,11 +338,11 @@ func (s *storageCeph) MigrationSink(live bool, c container,
 		logger.Debugf(`Received RBD storage volume "%s"`, recvName)
 	}
 
-	containerMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, containerName)
+	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
 	err = createContainerMountpoint(
 		containerMntPoint,
-		c.Path(),
-		c.IsPrivileged())
+		args.Container.Path(),
+		args.Container.IsPrivileged())
 	if err != nil {
 		logger.Errorf(`Failed to create mountpoint "%s" for RBD storage volume for container "%s" on storage pool "%s": %s"`, containerMntPoint, containerName, s.pool.Name, err)
 		return err
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index b13c66a83d..dd7f7a3396 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -16,7 +16,6 @@ import (
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -1276,8 +1275,8 @@ func (s *storageDir) MigrationSource(args MigrationSourceArgs) (MigrationStorage
 	return rsyncMigrationSource(args)
 }
 
-func (s *storageDir) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
-	return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly, args)
+func (s *storageDir) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncMigrationSink(conn, op, args)
 }
 
 func (s *storageDir) StorageEntitySetQuota(volumeType int, size int64, data interface{}) error {
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 7ed618b7fe..5377c0a49b 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -17,7 +17,6 @@ import (
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -2073,8 +2072,8 @@ func (s *storageLvm) MigrationSource(args MigrationSourceArgs) (MigrationStorage
 	return rsyncMigrationSource(args)
 }
 
-func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
-	return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly, args)
+func (s *storageLvm) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	return rsyncMigrationSink(conn, op, args)
 }
 
 func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data interface{}) error {
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 379a09be61..7ee15ed430 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -10,7 +10,6 @@ import (
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -212,19 +211,19 @@ func rsyncStorageMigrationSink(conn *websocket.Conn, op *operation, args Migrati
 	return RsyncRecv(path, conn, wrapper, args.RsyncArgs)
 }
 
-func rsyncMigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
-	ourStart, err := container.StorageStart()
+func rsyncMigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
+	ourStart, err := args.Container.StorageStart()
 	if err != nil {
 		return err
 	}
 	if ourStart {
-		defer container.StorageStop()
+		defer args.Container.StorageStop()
 	}
 
 	// At this point we have already figured out the parent container's root
 	// disk device so we can simply retrieve it from the expanded devices.
 	parentStoragePool := ""
-	parentExpandedDevices := container.ExpandedDevices()
+	parentExpandedDevices := args.Container.ExpandedDevices()
 	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := shared.GetRootDiskDevice(parentExpandedDevices)
 	if parentLocalRootDiskDeviceKey != "" {
 		parentStoragePool = parentLocalRootDiskDevice["pool"]
@@ -235,15 +234,15 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 		return fmt.Errorf("the container's root device is missing the pool property")
 	}
 
-	localSnapshots, err := container.Snapshots()
+	localSnapshots, err := args.Container.Snapshots()
 	if err != nil {
 		return err
 	}
 
-	isDirBackend := container.Storage().GetStorageType() == storageTypeDir
+	isDirBackend := args.Container.Storage().GetStorageType() == storageTypeDir
 	if isDirBackend {
-		if !containerOnly {
-			for _, snap := range snapshots {
+		if !args.ContainerOnly {
+			for _, snap := range args.Snapshots {
 				isSnapshotOutdated := true
 
 				for _, localSnap := range localSnapshots {
@@ -260,7 +259,7 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 					continue
 				}
 
-				snapArgs := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
+				snapArgs := snapshotProtobufToContainerArgs(args.Container.Project(), args.Container.Name(), snap)
 
 				// Ensure that snapshot and parent container have the
 				// same storage pool in their local root disk device.
@@ -275,11 +274,11 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 				}
 
 				// Try and a load container
-				s, err := containerLoadByProjectAndName(container.DaemonState(),
-					container.Project(), snapArgs.Name)
+				s, err := containerLoadByProjectAndName(args.Container.DaemonState(),
+					args.Container.Project(), snapArgs.Name)
 				if err != nil {
 					// Create the snapshot since it doesn't seem to exist
-					s, err = containerCreateEmptySnapshot(container.DaemonState(), snapArgs)
+					s, err = containerCreateEmptySnapshot(args.Container.DaemonState(), snapArgs)
 					if err != nil {
 						return err
 					}
@@ -290,21 +289,21 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 					return err
 				}
 
-				err = ShiftIfNecessary(container, srcIdmap)
+				err = ShiftIfNecessary(args.Container, args.Idmap)
 				if err != nil {
 					return err
 				}
 			}
 		}
 
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		err = RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper, args.RsyncArgs)
+		wrapper := StorageProgressWriter(op, "fs_progress", args.Container.Name())
+		err = RsyncRecv(shared.AddSlash(args.Container.Path()), conn, wrapper, args.RsyncArgs)
 		if err != nil {
 			return err
 		}
 	} else {
-		if !containerOnly {
-			for _, snap := range snapshots {
+		if !args.ContainerOnly {
+			for _, snap := range args.Snapshots {
 				isSnapshotOutdated := true
 
 				for _, localSnap := range localSnapshots {
@@ -321,7 +320,7 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 					continue
 				}
 
-				snapArgs := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
+				snapArgs := snapshotProtobufToContainerArgs(args.Container.Project(), args.Container.Name(), snap)
 
 				// Ensure that snapshot and parent container have the
 				// same storage pool in their local root disk device.
@@ -336,20 +335,20 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 				}
 
 				wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
-				err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper, args.RsyncArgs)
+				err := RsyncRecv(shared.AddSlash(args.Container.Path()), conn, wrapper, args.RsyncArgs)
 				if err != nil {
 					return err
 				}
 
-				err = ShiftIfNecessary(container, srcIdmap)
+				err = ShiftIfNecessary(args.Container, args.Idmap)
 				if err != nil {
 					return err
 				}
 
-				_, err = containerLoadByProjectAndName(container.DaemonState(),
-					container.Project(), snapArgs.Name)
+				_, err = containerLoadByProjectAndName(args.Container.DaemonState(),
+					args.Container.Project(), snapArgs.Name)
 				if err != nil {
-					_, err = containerCreateAsSnapshot(container.DaemonState(), snapArgs, container)
+					_, err = containerCreateAsSnapshot(args.Container.DaemonState(), snapArgs, args.Container)
 					if err != nil {
 						return err
 					}
@@ -357,23 +356,23 @@ func rsyncMigrationSink(live bool, container container, snapshots []*migration.S
 			}
 		}
 
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		err = RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper, args.RsyncArgs)
+		wrapper := StorageProgressWriter(op, "fs_progress", args.Container.Name())
+		err = RsyncRecv(shared.AddSlash(args.Container.Path()), conn, wrapper, args.RsyncArgs)
 		if err != nil {
 			return err
 		}
 	}
 
-	if live {
+	if args.Live {
 		/* now receive the final sync */
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
-		err := RsyncRecv(shared.AddSlash(container.Path()), conn, wrapper, args.RsyncArgs)
+		wrapper := StorageProgressWriter(op, "fs_progress", args.Container.Name())
+		err := RsyncRecv(shared.AddSlash(args.Container.Path()), conn, wrapper, args.RsyncArgs)
 		if err != nil {
 			return err
 		}
 	}
 
-	err = ShiftIfNecessary(container, srcIdmap)
+	err = ShiftIfNecessary(args.Container, args.Idmap)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index dca8827238..c5f2e23772 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -8,7 +8,6 @@ import (
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -229,7 +228,7 @@ func (s *storageMock) MigrationSource(args MigrationSourceArgs) (MigrationStorag
 	return nil, nil
 }
 
-func (s *storageMock) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
+func (s *storageMock) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
 	return nil
 }
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index e3ada9b2e3..4fe785f984 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -19,7 +19,6 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/logger"
 
 	"github.com/pborman/uuid"
@@ -2715,7 +2714,7 @@ func (s *storageZfs) MigrationSource(args MigrationSourceArgs) (MigrationStorage
 	return &driver, nil
 }
 
-func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*migration.Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool, args MigrationSinkArgs) error {
+func (s *storageZfs) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
 	poolName := s.getOnDiskPoolName()
 	zfsRecv := func(zfsName string, writeWrapper func(io.WriteCloser) io.WriteCloser) error {
 		zfsFsName := fmt.Sprintf("%s/%s", poolName, zfsName)
@@ -2761,8 +2760,8 @@ 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", projectPrefix(container.Project(), container.Name()))
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	zfsName := fmt.Sprintf("containers/%s", projectPrefix(args.Container.Project(), args.Container.Name()))
+	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, args.Container.Name())
 	if shared.IsMountPoint(containerMntPoint) {
 		err := zfsUmount(poolName, zfsName, containerMntPoint)
 		if err != nil {
@@ -2770,9 +2769,9 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		}
 	}
 
-	if len(snapshots) > 0 {
-		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(container.Project(), s.volume.Name))
-		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(container.Project(), container.Name()))
+	if len(args.Snapshots) > 0 {
+		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", projectPrefix(args.Container.Project(), s.volume.Name))
+		snapshotMntPointSymlink := shared.VarPath("snapshots", projectPrefix(args.Container.Project(), args.Container.Name()))
 		if !shared.PathExists(snapshotMntPointSymlink) {
 			err := os.Symlink(snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 			if err != nil {
@@ -2785,7 +2784,7 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 	// container's root disk device so we can simply
 	// retrieve it from the expanded devices.
 	parentStoragePool := ""
-	parentExpandedDevices := container.ExpandedDevices()
+	parentExpandedDevices := args.Container.ExpandedDevices()
 	parentLocalRootDiskDeviceKey, parentLocalRootDiskDevice, _ := shared.GetRootDiskDevice(parentExpandedDevices)
 	if parentLocalRootDiskDeviceKey != "" {
 		parentStoragePool = parentLocalRootDiskDevice["pool"]
@@ -2796,32 +2795,32 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 		return fmt.Errorf("detected that the container's root device is missing the pool property during BTRFS migration")
 	}
 
-	for _, snap := range snapshots {
-		args := snapshotProtobufToContainerArgs(container.Project(), container.Name(), snap)
+	for _, snap := range args.Snapshots {
+		ctArgs := snapshotProtobufToContainerArgs(args.Container.Project(), args.Container.Name(), snap)
 
 		// Ensure that snapshot and parent container have the
 		// same storage pool in their local root disk device.
 		// If the root disk device for the snapshot comes from a
 		// profile on the new instance as well we don't need to
 		// do anything.
-		if args.Devices != nil {
-			snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(args.Devices)
+		if ctArgs.Devices != nil {
+			snapLocalRootDiskDeviceKey, _, _ := shared.GetRootDiskDevice(ctArgs.Devices)
 			if snapLocalRootDiskDeviceKey != "" {
-				args.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
+				ctArgs.Devices[snapLocalRootDiskDeviceKey]["pool"] = parentStoragePool
 			}
 		}
-		_, err := containerCreateEmptySnapshot(container.DaemonState(), args)
+		_, err := containerCreateEmptySnapshot(args.Container.DaemonState(), ctArgs)
 		if err != nil {
 			return err
 		}
 
 		wrapper := StorageProgressWriter(op, "fs_progress", snap.GetName())
-		name := fmt.Sprintf("containers/%s at snapshot-%s", projectPrefix(container.Project(), container.Name()), snap.GetName())
+		name := fmt.Sprintf("containers/%s at snapshot-%s", projectPrefix(args.Container.Project(), args.Container.Name()), snap.GetName())
 		if err := zfsRecv(name, wrapper); err != nil {
 			return err
 		}
 
-		snapshotMntPoint := getSnapshotMountPoint(container.Project(), poolName, fmt.Sprintf("%s/%s", container.Name(), *snap.Name))
+		snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), poolName, fmt.Sprintf("%s/%s", args.Container.Name(), *snap.Name))
 		if !shared.PathExists(snapshotMntPoint) {
 			err := os.MkdirAll(snapshotMntPoint, 0700)
 			if err != nil {
@@ -2832,7 +2831,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", projectPrefix(container.Project(), container.Name())))
+		zfsSnapshots, err := zfsPoolListSnapshots(poolName, fmt.Sprintf("containers/%s", projectPrefix(args.Container.Project(), args.Container.Name())))
 		if err != nil {
 			logger.Errorf("Failed listing snapshots post migration: %s", err)
 			return
@@ -2840,23 +2839,23 @@ func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*
 
 		for _, snap := range zfsSnapshots {
 			// If we received a bunch of snapshots, remove the migration-send-* ones, if not, wipe any snapshot we got
-			if snapshots != nil && len(snapshots) > 0 && !strings.HasPrefix(snap, "migration-send") {
+			if args.Snapshots != nil && len(args.Snapshots) > 0 && !strings.HasPrefix(snap, "migration-send") {
 				continue
 			}
 
-			zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", projectPrefix(container.Project(), container.Name())), snap)
+			zfsPoolVolumeSnapshotDestroy(poolName, fmt.Sprintf("containers/%s", projectPrefix(args.Container.Project(), args.Container.Name())), snap)
 		}
 	}()
 
 	/* finally, do the real container */
-	wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
+	wrapper := StorageProgressWriter(op, "fs_progress", args.Container.Name())
 	if err := zfsRecv(zfsName, wrapper); err != nil {
 		return err
 	}
 
-	if live {
+	if args.Live {
 		/* and again for the post-running snapshot if this was a live migration */
-		wrapper := StorageProgressWriter(op, "fs_progress", container.Name())
+		wrapper := StorageProgressWriter(op, "fs_progress", args.Container.Name())
 		if err := zfsRecv(zfsName, wrapper); err != nil {
 			return err
 		}


More information about the lxc-devel mailing list