[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