[lxc-devel] [lxd/master] DB StoragePoolVolumeSnapshotsGetType returns more snapshot info
tomponline on Github
lxc-bot at linuxcontainers.org
Tue Oct 22 11:15:48 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 862 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191022/86a3dcec/attachment.bin>
-------------- next part --------------
From 1c404d9fb75f87ee8dd6a5520cd04bd9186c385b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 14 Oct 2019 12:27:34 +0100
Subject: [PATCH 1/3] lxd/db/storage/pools: StoragePoolVolumeSnapshotsGetType
returns StorageVolumeArgs slice
Updates StoragePoolVolumeSnapshotsGetType to return a slice of StorageVolumeArgs with Name and Description populated.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/storage_pools.go | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index c0ed91eed2..75d20fc250 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -776,22 +776,26 @@ SELECT storage_volumes.name
// StoragePoolVolumeSnapshotsGetType get all snapshots of a storage volume
// attached to a given storage pool of a given volume type, on the given node.
-func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeType int, poolID int64) ([]string, error) {
- result := []string{}
+func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) {
+ result := []StorageVolumeArgs{}
regexp := volumeName + shared.SnapshotDelimiter
length := len(regexp)
- query := "SELECT name FROM storage_volumes WHERE storage_pool_id=? AND node_id=? AND type=? AND snapshot=? AND SUBSTR(name,1,?)=?"
+ query := "SELECT name, description FROM storage_volumes WHERE storage_pool_id=? AND node_id=? AND type=? AND snapshot=? AND SUBSTR(name,1,?)=?"
inargs := []interface{}{poolID, c.nodeID, volumeType, true, length, regexp}
- outfmt := []interface{}{volumeName}
-
+ typeGuide := StorageVolumeArgs{} // StorageVolume struct used to guide the types expected.
+ outfmt := []interface{}{typeGuide.Name, typeGuide.Description}
dbResults, err := queryScan(c.db, query, inargs, outfmt)
if err != nil {
return result, err
}
for _, r := range dbResults {
- result = append(result, r[0].(string))
+ row := StorageVolumeArgs{
+ Name: r[0].(string),
+ Description: r[1].(string),
+ }
+ result = append(result, row)
}
return result, nil
From 8f7d9c3e2d0fbaf48e9e1a477df06c5e24bb07a6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 22 Oct 2019 11:51:24 +0100
Subject: [PATCH 2/3] lxd/db/storage/pools: Makes
StoragePoolVolumeSnapshotsGetType return in volume ID order
Adds explicit order by id to SQL statement and comment to add clarity around the expectations of this function's return values.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/db/storage_pools.go | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 75d20fc250..ade8291d1c 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -776,12 +776,17 @@ SELECT storage_volumes.name
// StoragePoolVolumeSnapshotsGetType get all snapshots of a storage volume
// attached to a given storage pool of a given volume type, on the given node.
+// Returns snapshots slice ordered by volume ID (i.e effectively the order they were created).
func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) {
result := []StorageVolumeArgs{}
regexp := volumeName + shared.SnapshotDelimiter
length := len(regexp)
- query := "SELECT name, description FROM storage_volumes WHERE storage_pool_id=? AND node_id=? AND type=? AND snapshot=? AND SUBSTR(name,1,?)=?"
+ // ORDER BY id is important here as the users of this function can expect that the results
+ // will be returned in the order that the snapshots were created. This is specifically used
+ // during migration to ensure that the storage engines can re-create snapshots using the
+ // correct deltas.
+ query := "SELECT name, description FROM storage_volumes WHERE storage_pool_id=? AND node_id=? AND type=? AND snapshot=? AND SUBSTR(name,1,?)=? ORDER BY id"
inargs := []interface{}{poolID, c.nodeID, volumeType, true, length, regexp}
typeGuide := StorageVolumeArgs{} // StorageVolume struct used to guide the types expected.
outfmt := []interface{}{typeGuide.Name, typeGuide.Description}
From 057314a219b8e10eea5250b423a5368a3c3eee5d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 22 Oct 2019 12:12:33 +0100
Subject: [PATCH 3/3] lxd: Updates use of StoragePoolVolumeSnapshotsGetType
return type change
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/migrate_storage_volumes.go | 6 +++---
lxd/storage_btrfs.go | 6 +++---
lxd/storage_ceph.go | 2 +-
lxd/storage_ceph_utils.go | 4 ++--
lxd/storage_cephfs.go | 4 ++--
lxd/storage_dir.go | 4 ++--
lxd/storage_lvm.go | 2 +-
lxd/storage_migration.go | 6 +++---
lxd/storage_volumes.go | 4 ++--
lxd/storage_volumes_snapshot.go | 4 ++--
lxd/storage_volumes_utils.go | 4 ++--
lxd/storage_zfs.go | 4 ++--
12 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 1c492dedb2..57b8428525 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -62,14 +62,14 @@ func (s *migrationSourceWs) DoStorage(migrateOp *operations.Operation) error {
if err == nil {
poolID, err := state.Cluster.StoragePoolGetID(pool.Name)
if err == nil {
- for _, name := range snaps {
- _, snapVolume, err := state.Cluster.StoragePoolNodeVolumeGetType(name, storagePoolVolumeTypeCustom, poolID)
+ for _, snap := range snaps {
+ _, snapVolume, err := state.Cluster.StoragePoolNodeVolumeGetType(snap.Name, storagePoolVolumeTypeCustom, poolID)
if err != nil {
continue
}
snapshots = append(snapshots, volumeSnapshotToProtobuf(snapVolume))
- _, snapName, _ := shared.ContainerGetParentAndSnapshotName(name)
+ _, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
snapshotNames = append(snapshotNames, snapName)
}
}
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 8690f2a8ae..22196a68a7 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -780,7 +780,7 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
}
for _, vol := range volumes {
- _, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(vol)
+ _, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(vol.Name)
oldVolumeName := fmt.Sprintf("%s%s%s", s.volume.Name, shared.SnapshotDelimiter, snapshotName)
newVolumeName := fmt.Sprintf("%s%s%s", newName, shared.SnapshotDelimiter, snapshotName)
@@ -2903,7 +2903,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
}
for _, snap := range snapshots {
- srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, snap)
+ srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, snap.Name)
_, err = rsync.LocalCopy(srcSnapshotMntPoint, destVolumeMntPoint, bwlimit, true)
if err != nil {
@@ -2912,7 +2912,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
}
// create snapshot
- _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
+ _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
err = s.doVolumeSnapshotCreate(s.pool.Name, s.volume.Name, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
if err != nil {
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index b6c4d5e29d..948505f12d 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -428,7 +428,7 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
}
for _, snap := range snapshots {
- err := s.doPoolVolumeSnapshotDelete(snap)
+ err := s.doPoolVolumeSnapshotDelete(snap.Name)
if err != nil {
return err
}
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 2b3d9bed36..10b197346f 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -1949,8 +1949,8 @@ func (s *storageCeph) doCrossPoolVolumeCopy(source *api.StorageVolumeSource) err
if !source.VolumeOnly {
for _, snap := range snapshots {
- _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
- srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
+ _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
+ srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap.Name)
_, err = rsync.LocalCopy(srcSnapshotMntPoint, dstVolumeMntPoint, bwlimit, true)
if err != nil {
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 120a6100b1..e60150b22c 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -805,8 +805,8 @@ func (s *storageCephFs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) e
}
for _, snap := range snapshots {
- _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
- err = s.copyVolume(source.Pool, snap, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
+ _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
+ err = s.copyVolume(source.Pool, snap.Name, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
if err != nil {
return err
}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index da290132c5..b32e6b2c2f 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1403,8 +1403,8 @@ func (s *storageDir) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
}
for _, snap := range snapshots {
- _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
- err = s.copyVolumeSnapshot(source.Pool, snap, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
+ _, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
+ err = s.copyVolumeSnapshot(source.Pool, snap.Name, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
if err != nil {
return err
}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index a3d408f6d2..0bd5337229 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2231,7 +2231,7 @@ func (s *storageLvm) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
}
for _, snap := range snapshots {
- err = s.copyVolumeSnapshot(source.Pool, snap)
+ err = s.copyVolumeSnapshot(source.Pool, snap.Name)
if err != nil {
return err
}
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 7bb005266d..6ae562c309 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -68,10 +68,10 @@ func (s rsyncStorageSourceDriver) SendStorageVolume(conn *websocket.Conn, op *op
}
for _, snap := range snapshots {
- wrapper := StorageProgressReader(op, "fs_progress", snap)
- path := driver.GetStoragePoolVolumeSnapshotMountPoint(pool.Name, snap)
+ wrapper := StorageProgressReader(op, "fs_progress", snap.Name)
+ path := driver.GetStoragePoolVolumeSnapshotMountPoint(pool.Name, snap.Name)
path = shared.AddSlash(path)
- logger.Debugf("Starting to send storage volume snapshot %s on storage pool %s from %s", snap, pool.Name, path)
+ logger.Debugf("Starting to send storage volume snapshot %s on storage pool %s from %s", snap.Name, pool.Name, path)
err = rsync.Send(volume.Name, path, conn, wrapper, s.rsyncFeatures, bwlimit, state.OS.ExecPath)
if err != nil {
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index b3ab72ec23..7cf8c954da 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -1016,7 +1016,7 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
switch volumeType {
case storagePoolVolumeTypeCustom:
- var snapshots []string
+ var snapshots []db.StorageVolumeArgs
// Delete storage volume snapshots
snapshots, err = d.cluster.StoragePoolVolumeSnapshotsGetType(volumeName, volumeType, poolID)
@@ -1025,7 +1025,7 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
}
for _, snapshot := range snapshots {
- s, err := storagePoolVolumeInit(d.State(), project, poolName, snapshot, volumeType)
+ s, err := storagePoolVolumeInit(d.State(), project, poolName, snapshot.Name, volumeType)
if err != nil {
return response.NotFound(err)
}
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index bd77b92bb6..b44e86cdd0 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -201,7 +201,7 @@ func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) response.Resp
resultString := []string{}
resultMap := []*api.StorageVolumeSnapshot{}
for _, volume := range volumes {
- _, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(volume)
+ _, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(volume.Name)
if !recursion {
apiEndpoint, err := storagePoolVolumeTypeToAPIEndpoint(volumeType)
@@ -210,7 +210,7 @@ func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) response.Resp
}
resultString = append(resultString, fmt.Sprintf("/%s/storage-pools/%s/volumes/%s/%s/snapshots/%s", version.APIVersion, poolName, apiEndpoint, volumeName, snapshotName))
} else {
- _, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volume, volumeType, poolID)
+ _, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volume.Name, volumeType, poolID)
if err != nil {
continue
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index aa02763399..ac9fecd908 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -647,7 +647,7 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
}
for _, snap := range snapshots {
- _, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap)
+ _, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
_, err := storagePoolVolumeSnapshotCopyInternal(state, poolName, vol, snapName)
if err != nil {
return err
@@ -731,7 +731,7 @@ func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.St
}
// storagePoolVolumeSnapshotsGet returns a list of snapshots of the form <volume>/<snapshot-name>.
-func storagePoolVolumeSnapshotsGet(s *state.State, pool string, volume string, volType int) ([]string, error) {
+func storagePoolVolumeSnapshotsGet(s *state.State, pool string, volume string, volType int) ([]db.StorageVolumeArgs, error) {
poolID, err := s.Cluster.StoragePoolGetID(pool)
if err != nil {
return nil, err
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index a124173704..0ddead6d96 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -669,7 +669,7 @@ func (s *storageZfs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, cha
return err
}
- if volumes[len(volumes)-1] != fmt.Sprintf("%s/%s", s.volume.Name, writable.Restore) {
+ if volumes[len(volumes)-1].Name != fmt.Sprintf("%s/%s", s.volume.Name, writable.Restore) {
return fmt.Errorf("ZFS can only restore from the latest snapshot. Delete newer snapshots or copy the snapshot into a new volume instead")
}
@@ -2834,7 +2834,7 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
if !source.VolumeOnly {
for _, snap := range snapshots {
- srcMountPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
+ srcMountPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap.Name)
_, err = rsync.LocalCopy(srcMountPoint, dstMountPoint, bwlimit, true)
if err != nil {
More information about the lxc-devel
mailing list