[lxc-devel] [lxd/master] Storage Remove Legacy Storage for custom volumes

tomponline on Github lxc-bot at linuxcontainers.org
Fri Nov 1 09:42:57 UTC 2019


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/20191101/16957331/attachment-0001.bin>
-------------- next part --------------
From 55cd3375cfdf9ff6eed28d80c46da65708da463e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 08:50:12 +0000
Subject: [PATCH 01/14] lxd/container/lxc: Removes usage of legacy
 ContainerGetUsage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/container_lxc.go | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 8dc40f7292..937856218d 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -42,7 +42,6 @@ import (
 	"github.com/lxc/lxd/lxd/seccomp"
 	"github.com/lxc/lxd/lxd/state"
 	storagePools "github.com/lxc/lxd/lxd/storage"
-	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
 	"github.com/lxc/lxd/lxd/template"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
@@ -5907,24 +5906,16 @@ func (c *containerLXC) diskState() map[string]api.InstanceStateDisk {
 
 		var usage int64
 
-		// Check if we can load new storage layer for pool driver type.
 		pool, err := storagePools.GetPoolByName(c.state, dev.Config["pool"])
-		if err != storageDrivers.ErrUnknownDriver {
-			if err != nil {
-				logger.Errorf("Error loading storage pool for %s: %v", c.Name(), err)
-				continue
-			}
+		if err != nil {
+			logger.Errorf("Error loading storage pool for %s: %v", c.Name(), err)
+			continue
+		}
 
-			usage, err = pool.GetInstanceUsage(c)
-			if err != nil {
-				logger.Errorf("Error getting disk usage for %s: %v", c.Name(), err)
-				continue
-			}
-		} else {
-			usage, err = c.storage.ContainerGetUsage(c)
-			if err != nil {
-				continue
-			}
+		usage, err = pool.GetInstanceUsage(c)
+		if err != nil {
+			logger.Errorf("Error getting disk usage for %s: %v", c.Name(), err)
+			continue
 		}
 
 		disk[dev.Name] = api.InstanceStateDisk{Usage: usage}

From 6f6923fddaa867d8f85e1599a19ec6a1144cece0 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 08:54:22 +0000
Subject: [PATCH 02/14] lxd/images: Removes usage of legacy ImageCreate

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/images.go | 30 ++++++------------------------
 1 file changed, 6 insertions(+), 24 deletions(-)

diff --git a/lxd/images.go b/lxd/images.go
index 77b543cd06..9ede764e74 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -34,7 +34,6 @@ import (
 	"github.com/lxc/lxd/lxd/response"
 	"github.com/lxc/lxd/lxd/state"
 	storagePools "github.com/lxc/lxd/lxd/storage"
-	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
 	"github.com/lxc/lxd/lxd/task"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
@@ -628,31 +627,14 @@ func imageCreateInPool(d *Daemon, info *api.Image, storagePool string) error {
 		return fmt.Errorf("No storage pool specified")
 	}
 
-	// Check if we can load new storage layer for pool driver type.
 	pool, err := storagePools.GetPoolByName(d.State(), storagePool)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return err
-		}
-
-		err = pool.CreateImage(info.Fingerprint, nil)
-		if err != nil {
-			return err
-		}
-	} else {
-		// Initialize a new storage interface.
-		s, err := storagePoolInit(d.State(), storagePool)
-		if err != nil {
-			return err
-		}
-
-		// Create the storage volume for the image on the requested storage
-		// pool.
-		err = s.ImageCreate(info.Fingerprint, nil)
-		if err != nil {
-			return err
-		}
+	if err != nil {
+		return err
+	}
 
+	err = pool.CreateImage(info.Fingerprint, nil)
+	if err != nil {
+		return err
 	}
 
 	return nil

From 7343816cb8cb846a433c52a7f360dee87f3d5a1d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 08:56:39 +0000
Subject: [PATCH 03/14] lxd/migrate/storage/volumes: Removes use of legacy
 storage in migration source DoStorage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/migrate_storage_volumes.go | 141 ++++++---------------------------
 1 file changed, 25 insertions(+), 116 deletions(-)

diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 978d95ed88..5404dc34c9 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -43,56 +43,19 @@ func (s *migrationSourceWs) DoStorage(state *state.State, poolName string, volNa
 	var offerHeader migration.MigrationHeader
 	var poolMigrationTypes []migration.Type
 
-	// Check if sending storage pool supports new storage layer.
 	pool, err := storagePools.GetPoolByName(state, poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return err
-		}
-
-		poolMigrationTypes = pool.MigrationTypes(storageDrivers.ContentTypeFS)
-		if len(poolMigrationTypes) < 0 {
-			return fmt.Errorf("No source migration types available")
-		}
-
-		// Convert the pool's migration type options to an offer header to target.
-		offerHeader = migration.TypesToHeader(poolMigrationTypes...)
-	} else {
-		storage, err := storagePoolVolumeInit(state, "default", poolName, volName, storagePoolVolumeTypeCustom)
-		if err != nil {
-			return err
-		}
-		s.storage = storage
-		myType := s.storage.MigrationType()
-		hasFeature := true
-		offerHeader = migration.MigrationHeader{
-			Fs: &myType,
-			RsyncFeatures: &migration.RsyncFeatures{
-				Xattrs:        &hasFeature,
-				Delete:        &hasFeature,
-				Compress:      &hasFeature,
-				Bidirectional: &hasFeature,
-			},
-		}
-
-		if len(zfsVersion) >= 3 && zfsVersion[0:3] != "0.6" {
-			offerHeader.ZfsFeatures = &migration.ZfsFeatures{
-				Compress: &hasFeature,
-			}
-		}
+	if err != nil {
+		return err
+	}
 
-		// Storage needs to start unconditionally now, since we need to initialize a new
-		// storage interface.
-		ourMount, err := s.storage.StoragePoolVolumeMount()
-		if err != nil {
-			logger.Errorf("Failed to mount storage volume")
-			return err
-		}
-		if ourMount {
-			defer s.storage.StoragePoolVolumeUmount()
-		}
+	poolMigrationTypes = pool.MigrationTypes(storageDrivers.ContentTypeFS)
+	if len(poolMigrationTypes) < 0 {
+		return fmt.Errorf("No source migration types available")
 	}
 
+	// Convert the pool's migration type options to an offer header to target.
+	offerHeader = migration.TypesToHeader(poolMigrationTypes...)
+
 	snapshots := []*migration.Snapshot{}
 	snapshotNames := []string{}
 
@@ -141,78 +104,24 @@ func (s *migrationSourceWs) DoStorage(state *state.State, poolName string, volNa
 		return err
 	}
 
-	// Use new storage layer for migration if supported.
-	if pool != nil {
-		migrationType, err := migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
-		if err != nil {
-			logger.Errorf("Failed to neogotiate migration type: %v", err)
-			s.sendControl(err)
-			return err
-		}
-
-		volSourceArgs := migration.VolumeSourceArgs{
-			Name:          volName,
-			MigrationType: migrationType,
-			Snapshots:     snapshotNames,
-			TrackProgress: true,
-		}
-
-		err = pool.MigrateCustomVolume(&shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
-		if err != nil {
-			go s.sendControl(err)
-			return err
-		}
-	} else {
-		// Use legacy storage layer for migration.
-
-		// Get target's rsync options.
-		rsyncFeatures := respHeader.GetRsyncFeaturesSlice()
-		if !shared.StringInSlice("bidirectional", rsyncFeatures) {
-			// If no bi-directional support, assume LXD 3.7 level
-			// NOTE: Do NOT extend this list of arguments
-			rsyncFeatures = []string{"xattrs", "delete", "compress"}
-		}
-
-		// Get target's zfs options.
-		zfsFeatures := respHeader.GetZfsFeaturesSlice()
-
-		// Set source args
-		sourceArgs := MigrationSourceArgs{
-			RsyncFeatures: rsyncFeatures,
-			ZfsFeatures:   zfsFeatures,
-			VolumeOnly:    s.volumeOnly,
-		}
-
-		driver, fsErr := s.storage.StorageMigrationSource(sourceArgs)
-		if fsErr != nil {
-			logger.Errorf("Failed to initialize new storage volume migration driver")
-			s.sendControl(fsErr)
-			return fsErr
-		}
-
-		bwlimit := ""
-
-		if *offerHeader.Fs != *respHeader.Fs {
-			driver, _ = rsyncStorageMigrationSource(sourceArgs)
-
-			// Check if this storage pool has a rate limit set for rsync.
-			poolwritable := s.storage.GetStoragePoolWritable()
-			if poolwritable.Config != nil {
-				bwlimit = poolwritable.Config["rsync.bwlimit"]
-			}
-		}
+	migrationType, err := migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
+	if err != nil {
+		logger.Errorf("Failed to neogotiate migration type: %v", err)
+		s.sendControl(err)
+		return err
+	}
 
-		abort := func(err error) error {
-			driver.Cleanup()
-			go s.sendControl(err)
-			return err
-		}
+	volSourceArgs := migration.VolumeSourceArgs{
+		Name:          volName,
+		MigrationType: migrationType,
+		Snapshots:     snapshotNames,
+		TrackProgress: true,
+	}
 
-		err = driver.SendStorageVolume(s.fsConn, migrateOp, bwlimit, s.storage, s.volumeOnly)
-		if err != nil {
-			logger.Errorf("Failed to send storage volume")
-			return abort(err)
-		}
+	err = pool.MigrateCustomVolume(&shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
+	if err != nil {
+		go s.sendControl(err)
+		return err
 	}
 
 	msg := migration.MigrationControl{}

From 3cdb031eb934d958220050f7a11f6fc6475a55b7 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 08:57:45 +0000
Subject: [PATCH 04/14] lxd/migrate/storage/volumes: Removes use of legacy
 storage from migration sink DoStorage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/migrate_storage_volumes.go | 105 ++++++++++-----------------------
 1 file changed, 31 insertions(+), 74 deletions(-)

diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 5404dc34c9..42a480c1f3 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -242,88 +242,45 @@ func (c *migrationSink) DoStorage(state *state.State, poolName string, req *api.
 	// The migration header to be sent back to source with our target options.
 	var respHeader migration.MigrationHeader
 
-	// Check if we can load new storage layer for pool driver type.
 	pool, err := storagePools.GetPoolByName(state, poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return err
-		}
-
-		// Extract the source's migration type and then match it against our pool's
-		// supported types and features. If a match is found the combined features list
-		// will be sent back to requester.
-		respType, err := migration.MatchTypes(offerHeader, migration.MigrationFSType_RSYNC, pool.MigrationTypes(storageDrivers.ContentTypeFS))
-		if err != nil {
-			return err
-		}
-
-		// Convert response type to response header and copy snapshot info into it.
-		respHeader = migration.TypesToHeader(respType)
-		respHeader.SnapshotNames = offerHeader.SnapshotNames
-		respHeader.Snapshots = offerHeader.Snapshots
-
-		// Translate the legacy MigrationSinkArgs to a VolumeTargetArgs suitable for use
-		// with the new storage layer.
-		myTarget = func(conn *websocket.Conn, op *operations.Operation, args MigrationSinkArgs) error {
-			volTargetArgs := migration.VolumeTargetArgs{
-				Name:          req.Name,
-				Config:        req.Config,
-				Description:   req.Description,
-				MigrationType: respType,
-				TrackProgress: true,
-			}
-
-			// A zero length Snapshots slice indicates volume only migration in
-			// VolumeTargetArgs. So if VoluneOnly was requested, do not populate them.
-			if !args.VolumeOnly {
-				volTargetArgs.Snapshots = make([]string, 0, len(args.Snapshots))
-				for _, snap := range args.Snapshots {
-					volTargetArgs.Snapshots = append(volTargetArgs.Snapshots, *snap.Name)
-				}
-			}
+	if err != nil {
+		return err
+	}
 
-			return pool.CreateCustomVolumeFromMigration(&shared.WebsocketIO{Conn: conn}, volTargetArgs, op)
-		}
-	} else {
-		// Setup legacy storage migration sink if destination pool isn't supported yet by
-		// new storage layer.
-		storage, err := storagePoolVolumeDBCreateInternal(state, poolName, req)
-		if err != nil {
-			return err
-		}
+	// Extract the source's migration type and then match it against our pool's
+	// supported types and features. If a match is found the combined features list
+	// will be sent back to requester.
+	respType, err := migration.MatchTypes(offerHeader, migration.MigrationFSType_RSYNC, pool.MigrationTypes(storageDrivers.ContentTypeFS))
+	if err != nil {
+		return err
+	}
 
-		// Link the storage variable into the migrationSink (like NewStorageMigrationSink
-		// would have done originally).
-		c.src.storage = storage
-		c.dest.storage = storage
-		myTarget = c.src.storage.StorageMigrationSink
-		myType := c.src.storage.MigrationType()
-
-		hasFeature := true
-		respHeader = migration.MigrationHeader{
-			Fs:            &myType,
-			Snapshots:     offerHeader.Snapshots,
-			SnapshotNames: offerHeader.SnapshotNames,
-			RsyncFeatures: &migration.RsyncFeatures{
-				Xattrs:        &hasFeature,
-				Delete:        &hasFeature,
-				Compress:      &hasFeature,
-				Bidirectional: &hasFeature,
-			},
+	// Convert response type to response header and copy snapshot info into it.
+	respHeader = migration.TypesToHeader(respType)
+	respHeader.SnapshotNames = offerHeader.SnapshotNames
+	respHeader.Snapshots = offerHeader.Snapshots
+
+	// Translate the legacy MigrationSinkArgs to a VolumeTargetArgs suitable for use
+	// with the new storage layer.
+	myTarget = func(conn *websocket.Conn, op *operations.Operation, args MigrationSinkArgs) error {
+		volTargetArgs := migration.VolumeTargetArgs{
+			Name:          req.Name,
+			Config:        req.Config,
+			Description:   req.Description,
+			MigrationType: respType,
+			TrackProgress: true,
 		}
 
-		if len(zfsVersion) >= 3 && zfsVersion[0:3] != "0.6" {
-			respHeader.ZfsFeatures = &migration.ZfsFeatures{
-				Compress: &hasFeature,
+		// A zero length Snapshots slice indicates volume only migration in
+		// VolumeTargetArgs. So if VoluneOnly was requested, do not populate them.
+		if !args.VolumeOnly {
+			volTargetArgs.Snapshots = make([]string, 0, len(args.Snapshots))
+			for _, snap := range args.Snapshots {
+				volTargetArgs.Snapshots = append(volTargetArgs.Snapshots, *snap.Name)
 			}
 		}
 
-		// If the storage type the source has doesn't match what we have, then we have to
-		// use rsync.
-		if *offerHeader.Fs != *respHeader.Fs {
-			myTarget = rsyncStorageMigrationSink
-			myType = migration.MigrationFSType_RSYNC
-		}
+		return pool.CreateCustomVolumeFromMigration(&shared.WebsocketIO{Conn: conn}, volTargetArgs, op)
 	}
 
 	err = sender(&respHeader)

From 99f75bd05b4a499bbf11cb04e204de0dd3577fb2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 08:59:08 +0000
Subject: [PATCH 05/14] lxd/storage/volumes/snapshot: Removes use of legacy
 storage from storagePoolVolumeSnapshotsTypePost

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes_snapshot.go | 59 ++++-----------------------------
 1 file changed, 6 insertions(+), 53 deletions(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 7e21741a34..d0923530a8 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -85,9 +85,7 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) response.Res
 		return response.BadRequest(fmt.Errorf("Volumes used by LXD itself cannot have snapshots"))
 	}
 
-	// Retrieve ID of the storage pool (and check if the storage pool
-	// exists).
-	poolID, err := d.cluster.StoragePoolGetID(poolName)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
 	if err != nil {
 		return response.SmartError(err)
 	}
@@ -97,19 +95,13 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) response.Res
 		return resp
 	}
 
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), volumeName, volumeType)
 	if resp != nil {
 		return resp
 	}
 
-	// Ensure that the storage volume exists.
-	storage, err := storagePoolVolumeInit(d.State(), "default", poolName, volumeName, volumeType)
-	if err != nil {
-		return response.SmartError(err)
-	}
-
 	// Ensure that the snapshot doesn't already exist
-	_, _, err = d.cluster.StoragePoolNodeVolumeGetType(fmt.Sprintf("%s/%s", volumeName, req.Name), volumeType, poolID)
+	_, _, err = d.cluster.StoragePoolNodeVolumeGetType(fmt.Sprintf("%s/%s", volumeName, req.Name), volumeType, pool.ID())
 	if err != db.ErrNoSuchObject {
 		if err != nil {
 			return response.SmartError(err)
@@ -119,48 +111,9 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) response.Res
 	}
 
 	snapshot := func(op *operations.Operation) error {
-		// Check if we can load new storage layer for pool driver type.
-		pool, err := storagePools.GetPoolByName(d.State(), poolName)
-		if err != storageDrivers.ErrUnknownDriver {
-			if err != nil {
-				return err
-			}
-
-			err = pool.CreateCustomVolumeSnapshot(volumeName, req.Name, op)
-			if err != nil {
-				return err
-			}
-		} else {
-			// Start the storage.
-			ourMount, err := storage.StoragePoolVolumeMount()
-			if err != nil {
-				return err
-			}
-			if ourMount {
-				defer storage.StoragePoolVolumeUmount()
-			}
-
-			volWritable := storage.GetStoragePoolVolumeWritable()
-			fullSnapName := fmt.Sprintf("%s%s%s", volumeName, shared.SnapshotDelimiter, req.Name)
-			req.Name = fullSnapName
-			dbArgs := &db.StorageVolumeArgs{
-				Name:        fullSnapName,
-				PoolName:    poolName,
-				TypeName:    volumeTypeName,
-				Snapshot:    true,
-				Config:      volWritable.Config,
-				Description: volWritable.Description,
-			}
-
-			err = storage.StoragePoolVolumeSnapshotCreate(&req)
-			if err != nil {
-				return err
-			}
-
-			_, err = storagePoolVolumeSnapshotDBCreateInternal(d.State(), dbArgs)
-			if err != nil {
-				return err
-			}
+		err = pool.CreateCustomVolumeSnapshot(volumeName, req.Name, op)
+		if err != nil {
+			return err
 		}
 
 		return nil

From 77f0c13e8422b907c197a6dbf8752d774b1a2ee4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:00:49 +0000
Subject: [PATCH 06/14] lxd/storage/volumes/snapshot: Removes use of legacy
 storage from storagePoolVolumeSnapshotTypePost

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes_snapshot.go | 23 +++--------------------
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index d0923530a8..d292174731 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -252,36 +252,19 @@ func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) response.Resp
 		return resp
 	}
 
-	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
 	if err != nil {
 		return response.SmartError(err)
 	}
 
 	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), fullSnapshotName, volumeType)
 	if resp != nil {
 		return resp
 	}
 
-	s, err := storagePoolVolumeInit(d.State(), "default", poolName, fullSnapshotName, volumeType)
-	if err != nil {
-		return response.NotFound(err)
-	}
-
 	snapshotRename := func(op *operations.Operation) error {
-		// Check if we can load new storage layer for pool driver type.
-		pool, err := storagePools.GetPoolByName(d.State(), poolName)
-		if err != storageDrivers.ErrUnknownDriver {
-			if err != nil {
-				return err
-			}
-
-			err = pool.RenameCustomVolumeSnapshot(fullSnapshotName, req.Name, op)
-		} else {
-			err = s.StoragePoolVolumeSnapshotRename(req.Name)
-		}
-
-		return err
+		return pool.RenameCustomVolumeSnapshot(fullSnapshotName, req.Name, op)
 	}
 
 	resources := map[string][]string{}

From 4daf69d4045161d7ce3af6ff7ff3bcb92c981b7a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:02:04 +0000
Subject: [PATCH 07/14] lxd/storage/volumes/snapshot: Removes use of legacy
 storage from storagePoolVolumeSnapshotTypeDelete

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes_snapshot.go | 24 +++---------------------
 1 file changed, 3 insertions(+), 21 deletions(-)

diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index d292174731..afbebcad8f 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -12,7 +12,6 @@ import (
 	"github.com/lxc/lxd/lxd/operations"
 	"github.com/lxc/lxd/lxd/response"
 	storagePools "github.com/lxc/lxd/lxd/storage"
-	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -447,36 +446,19 @@ func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) response.Re
 		return resp
 	}
 
-	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
 	if err != nil {
 		return response.SmartError(err)
 	}
 
 	fullSnapshotName := fmt.Sprintf("%s/%s", volumeName, snapshotName)
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, fullSnapshotName, volumeType)
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), fullSnapshotName, volumeType)
 	if resp != nil {
 		return resp
 	}
 
-	s, err := storagePoolVolumeInit(d.State(), "default", poolName, fullSnapshotName, volumeType)
-	if err != nil {
-		return response.NotFound(err)
-	}
-
 	snapshotDelete := func(op *operations.Operation) error {
-		// Check if we can load new storage layer for pool driver type.
-		pool, err := storagePools.GetPoolByName(d.State(), poolName)
-		if err != storageDrivers.ErrUnknownDriver {
-			if err != nil {
-				return err
-			}
-
-			err = pool.DeleteCustomVolumeSnapshot(fullSnapshotName, op)
-		} else {
-			err = s.StoragePoolVolumeSnapshotDelete()
-		}
-
-		return err
+		return pool.DeleteCustomVolumeSnapshot(fullSnapshotName, op)
 	}
 
 	resources := map[string][]string{}

From 52058075e9f9744df58231e4ea47319e6a6fea0b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:04:55 +0000
Subject: [PATCH 08/14] lxd/storage/volumes: Removes use of legacy storage from
 doVolumeCreateOrCopy

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 26 ++++++++------------------
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 1f7f31cea4..02188c0fe5 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -294,27 +294,17 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) response.Response {
 }
 
 func doVolumeCreateOrCopy(d *Daemon, poolName string, req *api.StorageVolumesPost) response.Response {
-	var run func(op *operations.Operation) error
-
-	// Check if we can load new storage layer for both target and source pool driver types.
 	pool, err := storagePools.GetPoolByName(d.State(), poolName)
-	_, srcPoolErr := storagePools.GetPoolByName(d.State(), req.Source.Pool)
-	if err != storageDrivers.ErrUnknownDriver && srcPoolErr != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		run = func(op *operations.Operation) error {
-			if req.Source.Name == "" {
-				return pool.CreateCustomVolume(req.Name, req.Description, req.Config, op)
-			}
+	if err != nil {
+		return response.SmartError(err)
+	}
 
-			return pool.CreateCustomVolumeFromCopy(req.Name, req.Description, req.Config, req.Source.Pool, req.Source.Name, req.Source.VolumeOnly, op)
-		}
-	} else {
-		run = func(op *operations.Operation) error {
-			return storagePoolVolumeCreateInternal(d.State(), poolName, req)
+	run := func(op *operations.Operation) error {
+		if req.Source.Name == "" {
+			return pool.CreateCustomVolume(req.Name, req.Description, req.Config, op)
 		}
+
+		return pool.CreateCustomVolumeFromCopy(req.Name, req.Description, req.Config, req.Source.Pool, req.Source.Name, req.Source.VolumeOnly, op)
 	}
 
 	// If no source name supplied then this a volume create operation.

From 7a87fbc0fa8e523c8c75625e4cbbb45ca8dffc4e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:06:59 +0000
Subject: [PATCH 09/14] lxd/storage/volumes: Removes use of legacy storage from
 storagePoolVolumeTypePostRename

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 31 ++++++++-----------------------
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 02188c0fe5..4707eda868 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -636,31 +636,16 @@ func storagePoolVolumeTypePostRename(d *Daemon, poolName string, volumeName stri
 		return response.SmartError(err)
 	}
 
-	// Check if we can load new storage layer for pool driver type.
 	pool, err := storagePools.GetPoolByName(d.State(), poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		err = pool.RenameCustomVolume(volumeName, req.Name, nil)
-		if err != nil {
-			// Notify users of the volume that it's name is changing back.
-			storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
-			return response.SmartError(err)
-		}
-	} else {
-		s, err := storagePoolVolumeInit(d.State(), "default", poolName, volumeName, volumeType)
-		if err != nil {
-			return response.InternalError(err)
-		}
+	if err != nil {
+		return response.SmartError(err)
+	}
 
-		err = s.StoragePoolVolumeRename(req.Name)
-		if err != nil {
-			// Notify users of the volume that it's name is changing back.
-			storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
-			return response.SmartError(err)
-		}
+	err = pool.RenameCustomVolume(volumeName, req.Name, nil)
+	if err != nil {
+		// Notify users of the volume that it's name is changing back.
+		storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
+		return response.SmartError(err)
 	}
 
 	return response.SyncResponseLocation(true, nil, fmt.Sprintf("/%s/storage-pools/%s/volumes/%s", version.APIVersion, poolName, storagePoolVolumeAPIEndpointCustom))

From 3570136b1dbd3c9a13e231bf983c27ecd8ddff6a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:09:31 +0000
Subject: [PATCH 10/14] lxd/storage/volumes: Removes use of legacy storage from
 storagePoolVolumeTypePostMove

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 103 +++++++----------------------------------
 1 file changed, 18 insertions(+), 85 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 4707eda868..024826ce28 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -653,100 +653,33 @@ func storagePoolVolumeTypePostRename(d *Daemon, poolName string, volumeName stri
 
 // storagePoolVolumeTypePostMove handles volume move type POST requests.
 func storagePoolVolumeTypePostMove(d *Daemon, poolName string, volumeName string, volumeType int, req api.StorageVolumePost) response.Response {
-	var run func(op *operations.Operation) error
+	srcPool, err := storagePools.GetPoolByName(d.State(), poolName)
+	if err != nil {
+		return response.SmartError(err)
+	}
 
-	// Check if we can load new storage layer for both target and source pool driver types.
-	srcPool, srcPoolErr := storagePools.GetPoolByName(d.State(), poolName)
 	pool, err := storagePools.GetPoolByName(d.State(), req.Pool)
-	if err != storageDrivers.ErrUnknownDriver && srcPoolErr != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		run = func(op *operations.Operation) error {
-			// Notify users of the volume that it's name is changing.
-			err := storagePoolVolumeUpdateUsers(d, poolName, volumeName, req.Pool, req.Name)
-			if err != nil {
-				return err
-			}
-
-			// Provide empty description and nil config to instruct
-			// CreateCustomVolumeFromCopy to copy it from source volume.
-			err = pool.CreateCustomVolumeFromCopy(req.Name, "", nil, poolName, volumeName, false, op)
-			if err != nil {
-				// Notify users of the volume that it's name is changing back.
-				storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
-				return err
-			}
-
-			return srcPool.DeleteCustomVolume(volumeName, op)
-		}
-	} else {
-		// Convert poolName to poolID.
-		poolID, _, err := d.cluster.StoragePoolGet(poolName)
-		if err != nil {
-			return response.SmartError(err)
-		}
+	if err != nil {
+		return response.SmartError(err)
+	}
 
-		// Get the storage volume.
-		_, volume, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID)
+	run := func(op *operations.Operation) error {
+		// Notify users of the volume that it's name is changing.
+		err = storagePoolVolumeUpdateUsers(d, poolName, volumeName, req.Pool, req.Name)
 		if err != nil {
-			return response.SmartError(err)
+			return err
 		}
 
-		// Get storage volume snapshots.
-		snapshots, err := d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName, volumeType, poolID)
+		// Provide empty description and nil config to instruct
+		// CreateCustomVolumeFromCopy to copy it from source volume.
+		err = pool.CreateCustomVolumeFromCopy(req.Name, "", nil, poolName, volumeName, false, op)
 		if err != nil {
-			return response.SmartError(err)
+			// Notify users of the volume that it's name is changing back.
+			storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
+			return err
 		}
 
-		// This is a move request, so copy the volume and then delete the original.
-		moveReq := api.StorageVolumesPost{}
-		moveReq.Name = req.Name
-		moveReq.Type = "custom"
-		moveReq.Config = volume.Config
-		moveReq.Source.Name = volumeName
-		moveReq.Source.Pool = poolName
-
-		run = func(op *operations.Operation) error {
-			// Notify users of the volume that it's name is changing.
-			err := storagePoolVolumeUpdateUsers(d, poolName, volumeName, req.Pool, req.Name)
-			if err != nil {
-				return err
-			}
-
-			err = storagePoolVolumeCreateInternal(d.State(), req.Pool, &moveReq)
-			if err != nil {
-				// Notify users of the volume that it's name is changing back.
-				storagePoolVolumeUpdateUsers(d, req.Pool, req.Name, poolName, volumeName)
-				return err
-			}
-
-			// Delete snapshot volumes.
-			for _, snapshot := range snapshots {
-				s, err := storagePoolVolumeInit(d.State(), "default", poolName, snapshot.Name, volumeType)
-				if err != nil {
-					return err
-				}
-
-				err = s.StoragePoolVolumeSnapshotDelete()
-				if err != nil {
-					return err
-				}
-			}
-
-			s, err := storagePoolVolumeInit(d.State(), "default", poolName, volumeName, volumeType)
-			if err != nil {
-				return err
-			}
-
-			err = s.StoragePoolVolumeDelete()
-			if err != nil {
-				return err
-			}
-
-			return nil
-		}
+		return srcPool.DeleteCustomVolume(volumeName, op)
 	}
 
 	op, err := operations.OperationCreate(d.State(), "", operations.OperationClassTask, db.OperationVolumeMove, nil, nil, run, nil, nil)

From be736fde88c6c360b463c74cf7b1702e219d9913 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:15:13 +0000
Subject: [PATCH 11/14] lxd/storage/volumes: Removes use of legacy storage from
 storagePoolVolumeTypePut

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 100 +++++++++++++----------------------------
 1 file changed, 32 insertions(+), 68 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 024826ce28..1b207a960b 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -815,23 +815,23 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string)
 		return response.BadRequest(fmt.Errorf("Invalid storage volume type %s", volumeTypeName))
 	}
 
-	poolID, poolRow, err := d.cluster.StoragePoolGet(poolName)
-	if err != nil {
-		return response.SmartError(err)
-	}
-
 	resp := ForwardedResponseIfTargetIsRemote(d, r)
 	if resp != nil {
 		return resp
 	}
 
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
+	if err != nil {
+		return response.SmartError(err)
+	}
+
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), volumeName, volumeType)
 	if resp != nil {
 		return resp
 	}
 
 	// Get the existing storage volume.
-	_, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID)
+	_, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, pool.ID())
 	if err != nil {
 		return response.SmartError(err)
 	}
@@ -849,76 +849,40 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string)
 		return response.BadRequest(err)
 	}
 
-	// Check if we can load new storage layer for pool driver type.
-	pool, err := storagePools.GetPoolByName(d.State(), poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		if volumeType == db.StoragePoolVolumeTypeCustom {
-			// Restore custom volume from snapshot if requested. This should occur first
-			// before applying config changes so that changes are applied to the
-			// restored volume.
-			if req.Restore != "" {
-				err = pool.RestoreCustomVolume(vol.Name, req.Restore, nil)
-				if err != nil {
-					return response.SmartError(err)
-				}
-			}
-
-			// Handle update requests.
-			err = pool.UpdateCustomVolume(vol.Name, req.Description, req.Config, nil)
+	if volumeType == db.StoragePoolVolumeTypeCustom {
+		// Restore custom volume from snapshot if requested. This should occur first
+		// before applying config changes so that changes are applied to the
+		// restored volume.
+		if req.Restore != "" {
+			err = pool.RestoreCustomVolume(vol.Name, req.Restore, nil)
 			if err != nil {
 				return response.SmartError(err)
 			}
-		} else {
-			// You are only allowed to modify the description for non-custom volumes.
-			// This is a special case because the rootfs devices do not provide a way
-			// to update a non-custom volume's description.
-			if len(req.Config) > 0 {
-				return response.BadRequest(fmt.Errorf("Only description can be modified for volume type %s", volumeTypeName))
-			}
-
-			// There is a bug in the lxc client (lxc/storage_volume.go#L829-L865) which
-			// means that modifying a snapshot's description gets routed here rather
-			// than the dedicated snapshot editing route. So need to handle snapshot
-			// volumes here too.
+		}
 
-			// Update the database if description changed.
-			if req.Description != vol.Description {
-				err = d.cluster.StoragePoolVolumeUpdate(vol.Name, volumeType, poolID, req.Description, vol.Config)
-				if err != nil {
-					response.SmartError(err)
-				}
-			}
+		// Handle update requests.
+		err = pool.UpdateCustomVolume(vol.Name, req.Description, req.Config, nil)
+		if err != nil {
+			return response.SmartError(err)
 		}
 	} else {
+		// You are only allowed to modify the description for non-custom volumes.
+		// This is a special case because the rootfs devices do not provide a way
+		// to update a non-custom volume's description.
+		if len(req.Config) > 0 {
+			return response.BadRequest(fmt.Errorf("Only description can be modified for volume type %s", volumeTypeName))
+		}
 
-		if req.Restore != "" {
-			ctsUsingVolume, err := storagePoolVolumeUsedByRunningContainersWithProfilesGet(d.State(), poolName, vol.Name, storagePoolVolumeTypeNameCustom, true)
-			if err != nil {
-				return response.InternalError(err)
-			}
-
-			if len(ctsUsingVolume) != 0 {
-				return response.BadRequest(fmt.Errorf("Cannot restore custom volume used by running containers"))
-			}
-
-			err = storagePoolVolumeRestore(d.State(), poolName, volumeName, volumeType, req.Restore)
-			if err != nil {
-				return response.SmartError(err)
-			}
-		} else {
-			// Validate the configuration
-			err = storagePools.VolumeValidateConfig(volumeName, req.Config, poolRow)
-			if err != nil {
-				return response.BadRequest(err)
-			}
+		// There is a bug in the lxc client (lxc/storage_volume.go#L829-L865) which
+		// means that modifying a snapshot's description gets routed here rather
+		// than the dedicated snapshot editing route. So need to handle snapshot
+		// volumes here too.
 
-			err = storagePoolVolumeUpdate(d.State(), poolName, volumeName, volumeType, req.Description, req.Config)
+		// Update the database if description changed.
+		if req.Description != vol.Description {
+			err = d.cluster.StoragePoolVolumeUpdate(vol.Name, volumeType, pool.ID(), req.Description, vol.Config)
 			if err != nil {
-				return response.SmartError(err)
+				response.SmartError(err)
 			}
 		}
 	}

From 8a82a953a4429668994305f37d78ef90e361c1e0 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:18:51 +0000
Subject: [PATCH 12/14] lxd/storage/volumes: Removes use of legacy storage from
 storagePoolVolumeTypePatch

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 32 ++++++--------------------------
 1 file changed, 6 insertions(+), 26 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 1b207a960b..61fee49e8e 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -925,8 +925,7 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName strin
 		return response.BadRequest(fmt.Errorf("Invalid storage volume type %s", volumeTypeName))
 	}
 
-	// Get the ID of the storage pool the storage volume is supposed to be attached to.
-	poolID, poolRow, err := d.cluster.StoragePoolGet(poolName)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
 	if err != nil {
 		return response.SmartError(err)
 	}
@@ -936,13 +935,13 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName strin
 		return resp
 	}
 
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), volumeName, volumeType)
 	if resp != nil {
 		return resp
 	}
 
 	// Get the existing storage volume.
-	_, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID)
+	_, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, pool.ID())
 	if err != nil {
 		return response.SmartError(err)
 	}
@@ -972,28 +971,9 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName strin
 		}
 	}
 
-	// Check if we can load new storage layer for pool driver type.
-	pool, err := storagePools.GetPoolByName(d.State(), poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		err = pool.UpdateCustomVolume(vol.Name, req.Description, req.Config, nil)
-		if err != nil {
-			return response.SmartError(err)
-		}
-	} else {
-		// Validate the configuration.
-		err = storagePools.VolumeValidateConfig(volumeName, req.Config, poolRow)
-		if err != nil {
-			return response.BadRequest(err)
-		}
-
-		err = storagePoolVolumeUpdate(d.State(), poolName, volumeName, volumeType, req.Description, req.Config)
-		if err != nil {
-			return response.SmartError(err)
-		}
+	err = pool.UpdateCustomVolume(vol.Name, req.Description, req.Config, nil)
+	if err != nil {
+		return response.SmartError(err)
 	}
 
 	return response.EmptySyncResponse

From 1c411db85c7d3356ca30ae99b4bb4f2c50839710 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:20:26 +0000
Subject: [PATCH 13/14] lxd/storage/volumes: Removes use of legacy storage from
 storagePoolVolumeTypeDelete

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes.go | 77 +++++++-----------------------------------
 1 file changed, 13 insertions(+), 64 deletions(-)

diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 61fee49e8e..e6a8d106f7 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -16,7 +16,6 @@ import (
 	"github.com/lxc/lxd/lxd/response"
 	"github.com/lxc/lxd/lxd/state"
 	storagePools "github.com/lxc/lxd/lxd/storage"
-	storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -1021,12 +1020,12 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
 		return resp
 	}
 
-	poolID, _, err := d.cluster.StoragePoolGet(poolName)
+	pool, err := storagePools.GetPoolByName(d.State(), poolName)
 	if err != nil {
 		return response.SmartError(err)
 	}
 
-	resp = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
+	resp = ForwardedResponseIfVolumeIsRemote(d, r, pool.ID(), volumeName, volumeType)
 	if resp != nil {
 		return resp
 	}
@@ -1046,71 +1045,21 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
 	}
 
 	if len(volumeUsedBy) > 0 {
-		if len(volumeUsedBy) != 1 ||
-			volumeType != storagePoolVolumeTypeImage ||
-			volumeUsedBy[0] != fmt.Sprintf(
-				"/%s/images/%s",
-				version.APIVersion,
-				volumeName) {
+		if len(volumeUsedBy) != 1 || volumeType != storagePoolVolumeTypeImage || volumeUsedBy[0] != fmt.Sprintf("/%s/images/%s", version.APIVersion, volumeName) {
 			return response.BadRequest(fmt.Errorf("The storage volume is still in use"))
 		}
 	}
 
-	// Check if we can load new storage layer for pool driver type.
-	pool, err := storagePools.GetPoolByName(d.State(), poolName)
-	if err != storageDrivers.ErrUnknownDriver {
-		if err != nil {
-			return response.SmartError(err)
-		}
-
-		switch volumeType {
-		case storagePoolVolumeTypeCustom:
-			err = pool.DeleteCustomVolume(volumeName, nil)
-		case storagePoolVolumeTypeImage:
-			err = pool.DeleteImage(volumeName, nil)
-		default:
-			return response.BadRequest(fmt.Errorf(`Storage volumes of type "%s" cannot be deleted with the storage api`, volumeTypeName))
-		}
-		if err != nil {
-			return response.SmartError(err)
-		}
-	} else {
-		s, err := storagePoolVolumeInit(d.State(), project, poolName, volumeName, volumeType)
-		if err != nil {
-			return response.NotFound(err)
-		}
-
-		switch volumeType {
-		case storagePoolVolumeTypeCustom:
-			var snapshots []db.StorageVolumeArgs
-
-			// Delete storage volume snapshots
-			snapshots, err = d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName, volumeType, poolID)
-			if err != nil {
-				return response.SmartError(err)
-			}
-
-			for _, snapshot := range snapshots {
-				s, err := storagePoolVolumeInit(d.State(), project, poolName, snapshot.Name, volumeType)
-				if err != nil {
-					return response.NotFound(err)
-				}
-
-				err = s.StoragePoolVolumeSnapshotDelete()
-				if err != nil {
-					return response.SmartError(err)
-				}
-			}
-
-			err = s.StoragePoolVolumeDelete()
-		case storagePoolVolumeTypeImage:
-			err = s.ImageDelete(volumeName)
-		default:
-			return response.BadRequest(fmt.Errorf(`Storage volumes of type "%s" cannot be deleted with the storage api`, volumeTypeName))
-		}
-		if err != nil {
-			return response.SmartError(err)
-		}
+	switch volumeType {
+	case storagePoolVolumeTypeCustom:
+		err = pool.DeleteCustomVolume(volumeName, nil)
+	case storagePoolVolumeTypeImage:
+		err = pool.DeleteImage(volumeName, nil)
+	default:
+		return response.BadRequest(fmt.Errorf(`Storage volumes of type "%s" cannot be deleted with the storage api`, volumeTypeName))
+	}
+	if err != nil {
+		return response.SmartError(err)
 	}
 
 	return response.EmptySyncResponse

From 2436ba2dbd97f2ee4ce8fd31a9e7b24228663cba Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 09:42:03 +0000
Subject: [PATCH 14/14] lxd/storage/volumes/utils: Removes unused legacy
 storage funtions

To appease static analysis.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes_utils.go | 271 -----------------------------------
 1 file changed, 271 deletions(-)

diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index ab7791e742..0456c3899b 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -3,7 +3,6 @@ package main
 import (
 	"fmt"
 	"path/filepath"
-	"strings"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
@@ -69,144 +68,6 @@ func storagePoolVolumeTypeToAPIEndpoint(volumeType int) (string, error) {
 	return "", fmt.Errorf("invalid storage volume type")
 }
 
-func storagePoolVolumeRestore(state *state.State, poolName string, volumeName string, volumeType int, snapshotName string) error {
-	s, err := storagePoolVolumeInit(state, "default", poolName,
-		fmt.Sprintf("%s/%s", volumeName, snapshotName), volumeType)
-	if err != nil {
-		return err
-	}
-
-	snapshotWritable := s.GetStoragePoolVolumeWritable()
-	snapshotWritable.Restore = snapshotName
-
-	s, err = storagePoolVolumeInit(state, "default", poolName, volumeName, volumeType)
-	if err != nil {
-		return err
-	}
-
-	err = s.StoragePoolVolumeUpdate(&snapshotWritable, nil)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName string, volumeType int, newDescription string, newConfig map[string]string) error {
-	s, err := storagePoolVolumeInit(state, "default", poolName, volumeName, volumeType)
-	if err != nil {
-		return err
-	}
-
-	oldWritable := s.GetStoragePoolVolumeWritable()
-	newWritable := oldWritable
-
-	// Backup the current state
-	oldDescription := oldWritable.Description
-	oldConfig := map[string]string{}
-	err = shared.DeepCopy(&oldWritable.Config, &oldConfig)
-	if err != nil {
-		return err
-	}
-
-	// Define a function which reverts everything.  Defer this function
-	// so that it doesn't need to be explicitly called in every failing
-	// return path. Track whether or not we want to undo the changes
-	// using a closure.
-	undoChanges := true
-	defer func() {
-		if undoChanges {
-			s.SetStoragePoolVolumeWritable(&oldWritable)
-		}
-	}()
-
-	// Diff the configurations
-	changedConfig := []string{}
-	userOnly := true
-	for key := range oldConfig {
-		if oldConfig[key] != newConfig[key] {
-			if !strings.HasPrefix(key, "user.") {
-				userOnly = false
-			}
-
-			if !shared.StringInSlice(key, changedConfig) {
-				changedConfig = append(changedConfig, key)
-			}
-		}
-	}
-
-	for key := range newConfig {
-		if oldConfig[key] != newConfig[key] {
-			if !strings.HasPrefix(key, "user.") {
-				userOnly = false
-			}
-
-			if !shared.StringInSlice(key, changedConfig) {
-				changedConfig = append(changedConfig, key)
-			}
-		}
-	}
-
-	// Apply config changes if there are any
-	if len(changedConfig) != 0 {
-		newWritable.Description = newDescription
-		newWritable.Config = newConfig
-
-		// Update the storage pool
-		if !userOnly {
-			err = s.StoragePoolVolumeUpdate(&newWritable, changedConfig)
-			if err != nil {
-				return err
-			}
-		}
-
-		// Apply the new configuration
-		s.SetStoragePoolVolumeWritable(&newWritable)
-	}
-
-	// Check that security.unmapped and security.shifted aren't set together
-	if shared.IsTrue(newConfig["security.unmapped"]) && shared.IsTrue(newConfig["security.shifted"]) {
-		return fmt.Errorf("security.unmapped and security.shifted are mutually exclusive")
-	}
-
-	// Confirm that no containers are running when changing shifted state
-	if newConfig["security.shifted"] != oldConfig["security.shifted"] {
-		ctsUsingVolume, err := storagePoolVolumeUsedByRunningContainersWithProfilesGet(state, poolName, volumeName, storagePoolVolumeTypeNameCustom, true)
-		if err != nil {
-			return err
-		}
-
-		if len(ctsUsingVolume) != 0 {
-			return fmt.Errorf("Cannot modify shifting with running containers using the volume")
-		}
-	}
-
-	// Unset idmap keys if volume is unmapped
-	if shared.IsTrue(newConfig["security.unmapped"]) {
-		delete(newConfig, "volatile.idmap.last")
-		delete(newConfig, "volatile.idmap.next")
-	}
-
-	// Get the pool ID
-	poolID, err := state.Cluster.StoragePoolGetID(poolName)
-	if err != nil {
-		return err
-	}
-
-	// Update the database if something changed
-	if len(changedConfig) != 0 || newDescription != oldDescription {
-		err = state.Cluster.StoragePoolVolumeUpdate(volumeName, volumeType, poolID, newDescription, newConfig)
-		if err != nil {
-			return err
-		}
-	}
-
-	// Success, update the closure to mark that the changes should be kept.
-	undoChanges = false
-
-	return nil
-}
-
 func storagePoolVolumeUsedByContainersGet(s *state.State, project, poolName string, volumeName string) ([]string, error) {
 	insts, err := instanceLoadByProject(s, project)
 	if err != nil {
@@ -494,138 +355,6 @@ func profilesUsingPoolVolumeGetNames(db *db.Cluster, volumeName string, volumeTy
 	return usedBy, nil
 }
 
-func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol *api.StorageVolumesPost) (storage, error) {
-	volumeName := vol.Name
-	volumeDescription := vol.Description
-	volumeTypeName := vol.Type
-	volumeConfig := vol.Config
-
-	if vol.Source.Name != "" {
-		// Initialize instance of new pool to translate properties
-		// between storage drivers.
-		s, err := storagePoolInit(state, poolName)
-		if err != nil {
-			return nil, err
-		}
-
-		driver := s.GetStorageTypeName()
-		newConfig, err := storagePools.VolumePropertiesTranslate(vol.Config, driver)
-		if err != nil {
-			return nil, err
-		}
-
-		vol.Config = newConfig
-		volumeConfig = newConfig
-	}
-
-	// Create database entry for new storage volume.
-	err := storagePools.VolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, false, volumeConfig)
-	if err != nil {
-		return nil, err
-	}
-
-	// Convert the volume type name to our internal integer representation.
-	poolID, err := state.Cluster.StoragePoolGetID(poolName)
-	if err != nil {
-		return nil, err
-	}
-
-	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
-	if err != nil {
-		state.Cluster.StoragePoolVolumeDelete("default", volumeName, volumeType, poolID)
-		return nil, err
-	}
-
-	// Initialize new storage volume on the target storage pool.
-	s, err := storagePoolVolumeInit(state, "default", poolName, volumeName, volumeType)
-	if err != nil {
-		state.Cluster.StoragePoolVolumeDelete("default", volumeName, volumeType, poolID)
-		return nil, err
-	}
-
-	return s, nil
-}
-
-func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *api.StorageVolumesPost) error {
-	s, err := storagePoolVolumeDBCreateInternal(state, poolName, vol)
-	if err != nil {
-		return err
-	}
-
-	volumeType, err1 := storagePools.VolumeTypeNameToType(vol.Type)
-	poolID, _, _ := s.GetContainerPoolInfo()
-	revert := true
-
-	defer func() {
-		if revert && err1 == nil {
-			state.Cluster.StoragePoolVolumeDelete("default", vol.Name, volumeType, poolID)
-		}
-	}()
-
-	if vol.Source.Name == "" {
-		err = s.StoragePoolVolumeCreate()
-	} else {
-		if !vol.Source.VolumeOnly {
-			snapshots, err := storagePools.VolumeSnapshotsGet(state, vol.Source.Pool, vol.Source.Name, volumeType)
-			if err != nil {
-				return err
-			}
-
-			for _, snap := range snapshots {
-				_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
-				_, err := storagePoolVolumeSnapshotCopyInternal(state, poolName, vol, snapName)
-				if err != nil {
-					return err
-				}
-			}
-		}
-
-		err = s.StoragePoolVolumeCopy(&vol.Source)
-	}
-	if err != nil {
-		return err
-	}
-
-	revert = false
-
-	return nil
-}
-
-func storagePoolVolumeSnapshotCopyInternal(state *state.State, poolName string, vol *api.StorageVolumesPost, snapshotName string) (storage, error) {
-	volumeType, err := storagePools.VolumeTypeNameToType(vol.Type)
-	if err != nil {
-		return nil, err
-	}
-
-	fullSnapshotName := fmt.Sprintf("%s/%s", vol.Name, snapshotName)
-
-	sourcePoolID, err := state.Cluster.StoragePoolGetID(vol.Source.Pool)
-	if err != nil {
-		return nil, err
-	}
-
-	volumeID, err := state.Cluster.StoragePoolNodeVolumeGetTypeID(vol.Source.Name, volumeType, sourcePoolID)
-	if err != nil {
-		return nil, err
-	}
-
-	volumeDescription, err := state.Cluster.StorageVolumeDescriptionGet(volumeID)
-	if err != nil {
-		return nil, err
-	}
-
-	dbArgs := &db.StorageVolumeArgs{
-		Name:        fullSnapshotName,
-		PoolName:    poolName,
-		TypeName:    vol.Type,
-		Snapshot:    true,
-		Config:      vol.Config,
-		Description: volumeDescription,
-	}
-
-	return storagePoolVolumeSnapshotDBCreateInternal(state, dbArgs)
-}
-
 func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.StorageVolumeArgs) (storage, error) {
 	// Create database entry for new storage volume.
 	err := storagePools.VolumeDBCreate(state, dbArgs.PoolName, dbArgs.Name, dbArgs.Description, dbArgs.TypeName, true, dbArgs.Config)


More information about the lxc-devel mailing list