[lxc-devel] [lxd/master] Storage volumes snapshots table
freeekanayaka on Github
lxc-bot at linuxcontainers.org
Tue Feb 18 16:10:26 UTC 2020
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/20200218/49db3bd0/attachment-0001.bin>
-------------- next part --------------
From 8d34e3adcbbbcc507f3b93330b9edc5145438d7a Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 11:37:38 +0000
Subject: [PATCH 01/38] lxd/db: un-export StorageVolumeNodeGet
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
lxd/db/storage_volumes.go | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 3dcc8e6a16..3ccd6ade3e 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -828,7 +828,7 @@ func (c *Cluster) StoragePoolVolumeGetType(project string, volumeName string, vo
return -1, nil, err
}
- volumeNode, err := c.StorageVolumeNodeGet(volumeID)
+ volumeNode, err := c.storageVolumeNodeGet(volumeID)
if err != nil {
return -1, nil, err
}
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index b377d7a630..4ef0e08c1b 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -85,8 +85,8 @@ SELECT nodes.id, nodes.address
return addresses, nil
}
-// StorageVolumeNodeGet returns the name of the node a storage volume is on.
-func (c *Cluster) StorageVolumeNodeGet(volumeID int64) (string, error) {
+// Return the name of the node a storage volume is on.
+func (c *Cluster) storageVolumeNodeGet(volumeID int64) (string, error) {
name := ""
query := `
SELECT nodes.name FROM storage_volumes
From c0958a973b8c3578ca435da093f04563a61205a9 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 12:15:35 +0000
Subject: [PATCH 02/38] lxd/db: un-export StoragePoolVolumesGetType
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 3ccd6ade3e..60f8db160e 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -730,7 +730,7 @@ func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, vo
// pool.
result := []*api.StorageVolume{}
for _, volumeType := range volumeTypes {
- volumeNames, err := c.StoragePoolVolumesGetType(project, volumeType, poolID, nodeID)
+ volumeNames, err := c.storagePoolVolumesGetType(project, volumeType, poolID, nodeID)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "failed to fetch volume types")
}
@@ -750,9 +750,9 @@ func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, vo
return result, nil
}
-// StoragePoolVolumesGetType get all storage volumes attached to a given
-// storage pool of a given volume type, on the given node.
-func (c *Cluster) StoragePoolVolumesGetType(project string, volumeType int, poolID, nodeID int64) ([]string, error) {
+// Get all storage volumes attached to a given storage pool of a given volume
+// type, on the given node.
+func (c *Cluster) storagePoolVolumesGetType(project string, volumeType int, poolID, nodeID int64) ([]string, error) {
var poolName string
query := `
SELECT storage_volumes.name
@@ -811,7 +811,7 @@ func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeTyp
// StoragePoolNodeVolumesGetType returns all storage volumes attached to a
// given storage pool of a given volume type, on the current node.
func (c *Cluster) StoragePoolNodeVolumesGetType(volumeType int, poolID int64) ([]string, error) {
- return c.StoragePoolVolumesGetType("default", volumeType, poolID, c.nodeID)
+ return c.storagePoolVolumesGetType("default", volumeType, poolID, c.nodeID)
}
// StoragePoolVolumeGetType returns a single storage volume attached to a
From 0958ad0c1d304b651e41f1eae0dd6e83210017dc Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 12:56:21 +0000
Subject: [PATCH 03/38] lxd/db: un-export StoragePoolVolumeGetTypeID
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 60f8db160e..2dac1f632c 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -823,7 +823,7 @@ func (c *Cluster) StoragePoolVolumeGetType(project string, volumeName string, vo
project = "default"
}
- volumeID, err := c.StoragePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
+ volumeID, err := c.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
if err != nil {
return -1, nil, err
}
@@ -1018,9 +1018,9 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, des
return thisVolumeID, err
}
-// StoragePoolVolumeGetTypeID returns the ID of a storage volume on a given
-// storage pool of a given storage volume type, on the given node.
-func (c *Cluster) StoragePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
+// Return the ID of a storage volume on a given storage pool of a given storage
+// volume type, on the given node.
+func (c *Cluster) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
volumeID := int64(-1)
query := `SELECT storage_volumes.id
FROM storage_volumes
@@ -1045,13 +1045,13 @@ AND storage_volumes.name=? AND storage_volumes.type=?`
// StoragePoolNodeVolumeGetTypeID get the ID of a storage volume on a given
// storage pool of a given storage volume type, on the current node.
func (c *Cluster) StoragePoolNodeVolumeGetTypeID(volumeName string, volumeType int, poolID int64) (int64, error) {
- return c.StoragePoolVolumeGetTypeID("default", volumeName, volumeType, poolID, c.nodeID)
+ return c.storagePoolVolumeGetTypeID("default", volumeName, volumeType, poolID, c.nodeID)
}
// StoragePoolNodeVolumeGetTypeIDByProject gets the ID of a storage volume on a given storage pool
// of a given storage volume type and project, on the current node.
func (c *Cluster) StoragePoolNodeVolumeGetTypeIDByProject(project, volumeName string, volumeType int, poolID int64) (int64, error) {
- return c.StoragePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, c.nodeID)
+ return c.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, c.nodeID)
}
// XXX: this was extracted from lxd/storage_volume_utils.go, we find a way to
From d3f2a5d718363dfdf0ac72e8a6da6accea887e70 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 13:03:33 +0000
Subject: [PATCH 04/38] lxd/db: un-export StoragePoolVolumeGetType
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 10 +++++-----
lxd/db/storage_pools_export_test.go | 9 +++++++++
2 files changed, 14 insertions(+), 5 deletions(-)
create mode 100644 lxd/db/storage_pools_export_test.go
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 2dac1f632c..7a7ccc7afd 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -735,7 +735,7 @@ func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, vo
return nil, errors.Wrap(err, "failed to fetch volume types")
}
for _, volumeName := range volumeNames {
- _, volume, err := c.StoragePoolVolumeGetType(project, volumeName, volumeType, poolID, nodeID)
+ _, volume, err := c.storagePoolVolumeGetType(project, volumeName, volumeType, poolID, nodeID)
if err != nil {
return nil, errors.Wrap(err, "failed to fetch volume type")
}
@@ -814,9 +814,9 @@ func (c *Cluster) StoragePoolNodeVolumesGetType(volumeType int, poolID int64) ([
return c.storagePoolVolumesGetType("default", volumeType, poolID, c.nodeID)
}
-// StoragePoolVolumeGetType returns a single storage volume attached to a
-// given storage pool of a given type, on the node with the given ID.
-func (c *Cluster) StoragePoolVolumeGetType(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, *api.StorageVolume, error) {
+// Return a single storage volume attached to a given storage pool of a given
+// type, on the node with the given ID.
+func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, *api.StorageVolume, error) {
// Custom volumes are "global", i.e. they are associated with the
// default project.
if volumeType == StoragePoolVolumeTypeCustom {
@@ -868,7 +868,7 @@ func (c *Cluster) StoragePoolNodeVolumeGetType(volumeName string, volumeType int
// StoragePoolNodeVolumeGetTypeByProject gets a single storage volume attached to a
// given storage pool of a given type, on the current node in the given project.
func (c *Cluster) StoragePoolNodeVolumeGetTypeByProject(project, volumeName string, volumeType int, poolID int64) (int64, *api.StorageVolume, error) {
- return c.StoragePoolVolumeGetType(project, volumeName, volumeType, poolID, c.nodeID)
+ return c.storagePoolVolumeGetType(project, volumeName, volumeType, poolID, c.nodeID)
}
// StoragePoolVolumeUpdateByProject updates the storage volume attached to a given storage pool.
diff --git a/lxd/db/storage_pools_export_test.go b/lxd/db/storage_pools_export_test.go
new file mode 100644
index 0000000000..6a83c10bc3
--- /dev/null
+++ b/lxd/db/storage_pools_export_test.go
@@ -0,0 +1,9 @@
+// +build linux,cgo,!agent
+
+package db
+
+import "github.com/lxc/lxd/shared/api"
+
+func (c *Cluster) StoragePoolVolumeGetType(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, *api.StorageVolume, error) {
+ return c.storagePoolVolumeGetType(project, volumeName, volumeType, poolID, nodeID)
+}
From 86cc9457d84726851b6ff0ed9bf9a62f4b660d6f Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 13:04:54 +0000
Subject: [PATCH 05/38] lxd/db: un-export StorageVolumeConfigGet
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
lxd/db/storage_volumes.go | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 7a7ccc7afd..ad48a44dee 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -833,7 +833,7 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo
return -1, nil, err
}
- volumeConfig, err := c.StorageVolumeConfigGet(volumeID)
+ volumeConfig, err := c.storageVolumeConfigGet(volumeID)
if err != nil {
return -1, nil, err
}
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 4ef0e08c1b..342bea8870 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -108,8 +108,8 @@ SELECT nodes.name FROM storage_volumes
return name, nil
}
-// StorageVolumeConfigGet gets the config of a storage volume.
-func (c *Cluster) StorageVolumeConfigGet(volumeID int64) (map[string]string, error) {
+// Get the config of a storage volume.
+func (c *Cluster) storageVolumeConfigGet(volumeID int64) (map[string]string, error) {
var key, value string
query := "SELECT key, value FROM storage_volumes_config WHERE storage_volume_id=?"
inargs := []interface{}{volumeID}
From a1f9334fd881805f84bafca3d89fc389e53a2fe8 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 13:05:54 +0000
Subject: [PATCH 06/38] lxd/db: un-export StoragePoolVolumeTypeToName
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index ad48a44dee..ac31cbb950 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -843,7 +843,7 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo
return -1, nil, err
}
- volumeTypeName, err := StoragePoolVolumeTypeToName(volumeType)
+ volumeTypeName, err := storagePoolVolumeTypeToName(volumeType)
if err != nil {
return -1, nil, err
}
@@ -1084,9 +1084,8 @@ var StoragePoolNodeConfigKeys = []string{
"lvm.vg_name",
}
-// StoragePoolVolumeTypeToName converts a volume integer type code to its
-// human-readable name.
-func StoragePoolVolumeTypeToName(volumeType int) (string, error) {
+// Convert a volume integer type code to its human-readable name.
+func storagePoolVolumeTypeToName(volumeType int) (string, error) {
switch volumeType {
case StoragePoolVolumeTypeContainer:
return StoragePoolVolumeTypeNameContainer, nil
From 2a043c44a07d8c5b950b790d16e5c91d44183a35 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 13:53:05 +0000
Subject: [PATCH 07/38] lxd/db: un-export StorageVolumeDescriptionUpdate
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
lxd/db/storage_volumes.go | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index ac31cbb950..138141df3e 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -890,7 +890,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
return err
}
- return StorageVolumeDescriptionUpdate(tx.tx, volumeID, volumeDescription)
+ return storageVolumeDescriptionUpdate(tx.tx, volumeID, volumeDescription)
})
if err != nil {
return err
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 342bea8870..3ae17e0d4a 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -251,8 +251,8 @@ func (c *Cluster) StorageVolumeIsAvailable(pool, volume string) (bool, error) {
return isAvailable, nil
}
-// StorageVolumeDescriptionUpdate updates the description of a storage volume.
-func StorageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string) error {
+// Updates the description of a storage volume.
+func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string) error {
_, err := tx.Exec("UPDATE storage_volumes SET description=? WHERE id=?", description, volumeID)
return err
}
From b6a033d79c6a95c38f59fda91963c4cf9e5f44c2 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:28:55 +0000
Subject: [PATCH 08/38] lxd/db: un-export StorageVolumeConfigAdd
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 4 ++--
lxd/db/storage_volumes.go | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 138141df3e..ff4e5fa2ea 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -885,7 +885,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
return err
}
- err = StorageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
+ err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
if err != nil {
return err
}
@@ -1003,7 +1003,7 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, des
thisVolumeID = volumeID
}
- err = StorageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
+ err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
if err != nil {
tx.tx.Rollback()
return err
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 3ae17e0d4a..f009023ed0 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -257,8 +257,8 @@ func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description stri
return err
}
-// StorageVolumeConfigAdd adds a new storage volume config into database.
-func StorageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string) error {
+// Add a new storage volume config into database.
+func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string) error {
str := "INSERT INTO storage_volumes_config (storage_volume_id, key, value) VALUES(?, ?, ?)"
stmt, err := tx.Prepare(str)
defer stmt.Close()
From 396135330b508ff2d947f27d891bdeb21fb1a7cb Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:33:42 +0000
Subject: [PATCH 09/38] lxd/db: un-export StorageVolumeConfigClear
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
lxd/db/storage_volumes.go | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index ff4e5fa2ea..5a30af09b0 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -880,7 +880,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
err = c.Transaction(func(tx *ClusterTx) error {
err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
- err = StorageVolumeConfigClear(tx.tx, volumeID)
+ err = storageVolumeConfigClear(tx.tx, volumeID)
if err != nil {
return err
}
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index f009023ed0..df77a1835f 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -280,8 +280,8 @@ func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]
return nil
}
-// StorageVolumeConfigClear deletes storage volume config.
-func StorageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
+// Delete storage volume config.
+func storageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
_, err := tx.Exec("DELETE FROM storage_volumes_config WHERE storage_volume_id=?", volumeID)
if err != nil {
return err
From 47b481e79b4c93fa836adbb96e5dbc6003a207a6 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 09:44:03 +0000
Subject: [PATCH 10/38] lxd/db/cluster: add new storage volume snapshots table
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/cluster/schema.go | 19 ++++++++++++++++++-
lxd/db/cluster/update.go | 29 +++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 02f2057d10..677f23a013 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -494,6 +494,23 @@ CREATE TABLE storage_volumes_config (
UNIQUE (storage_volume_id, key),
FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
);
+CREATE TABLE storage_volumes_snapshots (
+ id INTEGER NOT NULL,
+ storage_volume_id INTEGER NOT NULL,
+ name TEXT NOT NULL,
+ description TEXT,
+ UNIQUE (id),
+ UNIQUE (storage_volume_id, name),
+ FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
+);
+CREATE TABLE storage_volumes_snapshots_config (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ storage_volume_snapshot_id INTEGER NOT NULL,
+ key TEXT NOT NULL,
+ value TEXT,
+ FOREIGN KEY (storage_volume_snapshot_id) REFERENCES storage_volumes_snapshots (id) ON DELETE CASCADE,
+ UNIQUE (storage_volume_snapshot_id, key)
+);
-INSERT INTO schema (version, updated_at) VALUES (24, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (25, strftime("%s"))
`
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index 7b9763a238..ec584f5c52 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -60,6 +60,35 @@ var updates = map[int]schema.Update{
22: updateFromV21,
23: updateFromV22,
24: updateFromV23,
+ 25: updateFromV24,
+}
+
+// Create new storage snapshot tables and migrate data to them.
+func updateFromV24(tx *sql.Tx) error {
+ stmts := `
+CREATE TABLE storage_volumes_snapshots (
+ id INTEGER NOT NULL,
+ storage_volume_id INTEGER NOT NULL,
+ name TEXT NOT NULL,
+ description TEXT,
+ UNIQUE (id),
+ UNIQUE (storage_volume_id, name),
+ FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
+);
+CREATE TABLE storage_volumes_snapshots_config (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ storage_volume_snapshot_id INTEGER NOT NULL,
+ key TEXT NOT NULL,
+ value TEXT,
+ FOREIGN KEY (storage_volume_snapshot_id) REFERENCES storage_volumes_snapshots (id) ON DELETE CASCADE,
+ UNIQUE (storage_volume_snapshot_id, key)
+);
+`
+ _, err := tx.Exec(stmts)
+ if err != nil {
+ return errors.Wrap(err, "Failed to create storage snapshots tables")
+ }
+ return nil
}
// The lvm.vg_name config key is required for LVM to function.
From 6d6cf0d4099ddf0297efc1148ad4553b9e61f7fa Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 10:05:02 +0000
Subject: [PATCH 11/38] lxd/db/cluster: drop snapshot column from
storage_volumes table
This also migrates the data of all non-snapshot storage volumes. Data migration
for snapshot storage volumes will come in a follow-up commit.
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/cluster/schema.go | 1 -
lxd/db/cluster/update.go | 31 +++++++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 677f23a013..df7ab1e364 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -479,7 +479,6 @@ CREATE TABLE "storage_volumes" (
node_id INTEGER NOT NULL,
type INTEGER NOT NULL,
description TEXT,
- snapshot INTEGER NOT NULL DEFAULT 0,
project_id INTEGER NOT NULL,
UNIQUE (storage_pool_id, node_id, project_id, name, type),
FOREIGN KEY (storage_pool_id) REFERENCES storage_pools (id) ON DELETE CASCADE,
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index ec584f5c52..3e6ca346a2 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -66,6 +66,37 @@ var updates = map[int]schema.Update{
// Create new storage snapshot tables and migrate data to them.
func updateFromV24(tx *sql.Tx) error {
stmts := `
+ALTER TABLE storage_volumes RENAME TO old_storage_volumes;
+CREATE TABLE "storage_volumes" (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ name TEXT NOT NULL,
+ storage_pool_id INTEGER NOT NULL,
+ node_id INTEGER NOT NULL,
+ type INTEGER NOT NULL,
+ description TEXT,
+ project_id INTEGER NOT NULL,
+ UNIQUE (storage_pool_id, node_id, project_id, name, type),
+ FOREIGN KEY (storage_pool_id) REFERENCES storage_pools (id) ON DELETE CASCADE,
+ FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE,
+ FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
+);
+ALTER TABLE storage_volumes_config RENAME TO old_storage_volumes_config;
+CREATE TABLE storage_volumes_config (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ storage_volume_id INTEGER NOT NULL,
+ key TEXT NOT NULL,
+ value TEXT,
+ UNIQUE (storage_volume_id, key),
+ FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
+);
+INSERT INTO storage_volumes(id, name, storage_pool_id, node_id, type, description, project_id)
+ SELECT id, name, storage_pool_id, node_id, type, description, project_id FROM old_storage_volumes
+ WHERE snapshot=0;
+INSERT INTO storage_volumes_config
+ SELECT * FROM old_storage_volumes_config
+ WHERE storage_volume_id IN (SELECT id FROM storage_volumes);
+DROP TABLE old_storage_volumes;
+DROP TABLE old_storage_volumes_config;
CREATE TABLE storage_volumes_snapshots (
id INTEGER NOT NULL,
storage_volume_id INTEGER NOT NULL,
From adc57351c41956d229b98dee717718e3be64125f Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 12:30:00 +0000
Subject: [PATCH 12/38] lxd/db/cluster: add storage_volumes_all view
This lists both regular volumes and shapshots, and is virtually equivalent to
the old storage_volumes table.
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/cluster/schema.go | 27 +++++++++++++++++++++++++++
lxd/db/cluster/update.go | 25 +++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index df7ab1e364..903512c6a2 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -485,6 +485,33 @@ CREATE TABLE "storage_volumes" (
FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE,
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
);
+CREATE VIEW storage_volumes_all (
+ id,
+ name,
+ storage_pool_id,
+ node_id,
+ type,
+ description,
+ project_id) AS
+ SELECT id,
+ name,
+ storage_pool_id,
+ node_id,
+ type,
+ description,
+ project_id
+ FROM storage_volumes UNION
+ SELECT storage_volumes_snapshots.id,
+ printf('%s/%s',
+ storage_volumes.name,
+ storage_volumes_snapshots.name),
+ storage_volumes.storage_pool_id,
+ storage_volumes.node_id,
+ storage_volumes.type,
+ storage_volumes_snapshots.description,
+ storage_volumes.project_id
+ FROM storage_volumes
+ JOIN storage_volumes_snapshots ON storage_volumes.id = storage_volumes_snapshots.storage_volume_id;
CREATE TABLE storage_volumes_config (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
storage_volume_id INTEGER NOT NULL,
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index 3e6ca346a2..ab02b7cbc5 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -114,6 +114,31 @@ CREATE TABLE storage_volumes_snapshots_config (
FOREIGN KEY (storage_volume_snapshot_id) REFERENCES storage_volumes_snapshots (id) ON DELETE CASCADE,
UNIQUE (storage_volume_snapshot_id, key)
);
+CREATE VIEW storage_volumes_all (
+ id,
+ name,
+ storage_pool_id,
+ node_id,
+ type,
+ description,
+ project_id) AS
+ SELECT id,
+ name,
+ storage_pool_id,
+ node_id,
+ type,
+ description,
+ project_id
+ FROM storage_volumes UNION
+ SELECT storage_volumes_snapshots.id,
+ printf('%s/%s', storage_volumes.name, storage_volumes_snapshots.name),
+ storage_volumes.storage_pool_id,
+ storage_volumes.node_id,
+ storage_volumes.type,
+ storage_volumes_snapshots.description,
+ storage_volumes.project_id
+ FROM storage_volumes
+ JOIN storage_volumes_snapshots ON storage_volumes.id = storage_volumes_snapshots.storage_volume_id;
`
_, err := tx.Exec(stmts)
if err != nil {
From 8773c85517757edc32309d6cdf763efe7d139bba Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:02:15 +0000
Subject: [PATCH 13/38] lxd/db/schema: include triggers when generating SQL for
fresh schemas
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/schema/query.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/db/schema/query.go b/lxd/db/schema/query.go
index 6672cdd140..f0e1eed8f0 100644
--- a/lxd/db/schema/query.go
+++ b/lxd/db/schema/query.go
@@ -50,7 +50,7 @@ SELECT version FROM schema ORDER BY version
func selectTablesSQL(tx *sql.Tx) ([]string, error) {
statement := `
SELECT sql FROM sqlite_master WHERE
- type IN ('table', 'index', 'view') AND
+ type IN ('table', 'index', 'view', 'trigger') AND
name != 'schema' AND
name NOT LIKE 'sqlite_%'
ORDER BY name
From c2868fcd534be1f54db4a29e71f9bfc56be63208 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:03:47 +0000
Subject: [PATCH 14/38] lxd/db/cluster: add triggers to check that volume IDs
don't overlap
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/cluster/schema.go | 14 ++++++++++++++
lxd/db/cluster/update.go | 12 ++++++++++++
2 files changed, 26 insertions(+)
diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 903512c6a2..f0f5563101 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -512,6 +512,13 @@ CREATE VIEW storage_volumes_all (
storage_volumes.project_id
FROM storage_volumes
JOIN storage_volumes_snapshots ON storage_volumes.id = storage_volumes_snapshots.storage_volume_id;
+CREATE TRIGGER storage_volumes_check_id
+ BEFORE INSERT ON storage_volumes
+ WHEN NEW.id IN (SELECT id FROM storage_volumes_snapshots)
+ BEGIN
+ SELECT RAISE(FAIL,
+ "invalid ID");
+ END;
CREATE TABLE storage_volumes_config (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
storage_volume_id INTEGER NOT NULL,
@@ -529,6 +536,13 @@ CREATE TABLE storage_volumes_snapshots (
UNIQUE (storage_volume_id, name),
FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
);
+CREATE TRIGGER storage_volumes_snapshots_check_id
+ BEFORE INSERT ON storage_volumes_snapshots
+ WHEN NEW.id IN (SELECT id FROM storage_volumes)
+ BEGIN
+ SELECT RAISE(FAIL,
+ "invalid ID");
+ END;
CREATE TABLE storage_volumes_snapshots_config (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
storage_volume_snapshot_id INTEGER NOT NULL,
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index ab02b7cbc5..5febf383ef 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -106,6 +106,18 @@ CREATE TABLE storage_volumes_snapshots (
UNIQUE (storage_volume_id, name),
FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
);
+CREATE TRIGGER storage_volumes_check_id
+ BEFORE INSERT ON storage_volumes
+ WHEN NEW.id IN (SELECT id FROM storage_volumes_snapshots)
+ BEGIN
+ SELECT RAISE(FAIL, "invalid ID");
+ END;
+CREATE TRIGGER storage_volumes_snapshots_check_id
+ BEFORE INSERT ON storage_volumes_snapshots
+ WHEN NEW.id IN (SELECT id FROM storage_volumes)
+ BEGIN
+ SELECT RAISE(FAIL, "invalid ID");
+ END;
CREATE TABLE storage_volumes_snapshots_config (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
storage_volume_snapshot_id INTEGER NOT NULL,
From 22a6c9ae4312b5f4a2d316fddc767f16eab24b37 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 10:36:42 +0000
Subject: [PATCH 15/38] lxd/db: change StoragePoolVolumeSnapshotsGetType to
query the snapshots table
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 5a30af09b0..07cfc90475 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -781,15 +781,21 @@ SELECT storage_volumes.name
// Returns snapshots slice ordered by when they were created, oldest first.
func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) {
result := []StorageVolumeArgs{}
- regexp := volumeName + shared.SnapshotDelimiter
- length := len(regexp)
// 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}
+ query := `
+SELECT storage_volumes_snapshots.name, storage_volumes_snapshots.description FROM storage_volumes_snapshots
+ JOIN storage_volumes ON storage_volumes_snapshots.storage_volume_id = storage_volumes.id
+ WHERE storage_volumes.storage_pool_id=?
+ AND storage_volumes.node_id=?
+ AND storage_volumes.type=?
+ AND storage_volumes.name=?
+ ORDER BY id
+`
+ inargs := []interface{}{poolID, c.nodeID, volumeType, 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)
@@ -799,7 +805,7 @@ func (c *Cluster) StoragePoolVolumeSnapshotsGetType(volumeName string, volumeTyp
for _, r := range dbResults {
row := StorageVolumeArgs{
- Name: r[0].(string),
+ Name: volumeName + shared.SnapshotDelimiter + r[0].(string),
Description: r[1].(string),
}
result = append(result, row)
From 5d9bb60a59506288add74dc496e773eb082897e6 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 13:51:47 +0000
Subject: [PATCH 16/38] lxd/db: change StorageVolumeNextSnapshot to query the
snapshot table
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index df77a1835f..80b85db918 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -9,7 +9,6 @@ import (
"time"
"github.com/lxc/lxd/lxd/db/query"
- "github.com/lxc/lxd/shared"
"github.com/pkg/errors"
)
@@ -150,17 +149,23 @@ func (c *Cluster) StorageVolumeDescriptionGet(volumeID int64) (string, error) {
return description.String, nil
}
-// StorageVolumeNextSnapshot returns the index the next snapshot of the storage
+// StorageVolumeNextSnapshot returns the index of the next snapshot of the storage
// volume with the given name should have.
//
// Note, the code below doesn't deal with snapshots of snapshots.
// To do that, we'll need to weed out based on # slashes in names
func (c *Cluster) StorageVolumeNextSnapshot(name string, typ int) int {
- base := name + shared.SnapshotDelimiter + "snap"
+ base := "snap"
length := len(base)
- q := fmt.Sprintf("SELECT name FROM storage_volumes WHERE type=? AND snapshot=? AND SUBSTR(name,1,?)=?")
+ q := fmt.Sprintf(`
+SELECT storage_volumes_snapshots.name FROM storage_volumes_snapshots
+ JOIN storage_volumes ON storage_volumes_snapshots.storage_volume_id=storage_volumes.id
+ WHERE storage_volumes.type=?
+ AND storage_volumes.name=?
+ AND SUBSTR(storage_volumes_snapshots.name,1,?)=?
+`)
var numstr string
- inargs := []interface{}{typ, true, length, base}
+ inargs := []interface{}{typ, name, length, base}
outfmt := []interface{}{numstr}
results, err := queryScan(c.db, q, inargs, outfmt)
if err != nil {
@@ -169,11 +174,7 @@ func (c *Cluster) StorageVolumeNextSnapshot(name string, typ int) int {
max := 0
for _, r := range results {
- numstr = r[0].(string)
- if len(numstr) <= length {
- continue
- }
- substr := numstr[length:]
+ substr := r[0].(string)
var num int
count, err := fmt.Sscanf(substr, "%d", &num)
if err != nil || count != 1 {
From cd96100d804e3c68b6114bcd7db5727f7ac3e11c Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Fri, 14 Feb 2020 12:34:30 +0000
Subject: [PATCH 17/38] lxd/db: update StorageVolumeNodeAddresses to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 80b85db918..6662050c82 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -35,6 +35,8 @@ type StorageVolumeArgs struct {
// StorageVolumeNodeAddresses returns the addresses of all nodes on which the
// volume with the given name if defined.
//
+// The volume name can be either a regular name or a volume snapshot name.
+//
// The empty string is used in place of the address of the current node.
func (c *ClusterTx) StorageVolumeNodeAddresses(poolID int64, project, name string, typ int) ([]string, error) {
nodes := []struct {
@@ -52,9 +54,12 @@ func (c *ClusterTx) StorageVolumeNodeAddresses(poolID int64, project, name strin
sql := `
SELECT nodes.id, nodes.address
FROM nodes
- JOIN storage_volumes ON storage_volumes.node_id=nodes.id
- JOIN projects ON projects.id = storage_volumes.project_id
- WHERE storage_volumes.storage_pool_id=? AND projects.name=? AND storage_volumes.name=? AND storage_volumes.type=?
+ JOIN storage_volumes_all ON storage_volumes_all.node_id=nodes.id
+ JOIN projects ON projects.id = storage_volumes_all.project_id
+ WHERE storage_volumes_all.storage_pool_id=?
+ AND projects.name=?
+ AND storage_volumes_all.name=?
+ AND storage_volumes_all.type=?
`
stmt, err := c.tx.Prepare(sql)
if err != nil {
From 25c9ebaba9067eb4cc165629c22f1f85496591ac Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 12:31:29 +0000
Subject: [PATCH 18/38] lxd/db: update storagePoolVolumeGetTypeID to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 07cfc90475..4de793afe2 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -1028,12 +1028,12 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, des
// volume type, on the given node.
func (c *Cluster) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
volumeID := int64(-1)
- query := `SELECT storage_volumes.id
-FROM storage_volumes
-JOIN storage_pools ON storage_volumes.storage_pool_id = storage_pools.id
-JOIN projects ON storage_volumes.project_id = projects.id
-WHERE projects.name=? AND storage_volumes.storage_pool_id=? AND storage_volumes.node_id=?
-AND storage_volumes.name=? AND storage_volumes.type=?`
+ query := `SELECT storage_volumes_all.id
+FROM storage_volumes_all
+JOIN storage_pools ON storage_volumes_all.storage_pool_id = storage_pools.id
+JOIN projects ON storage_volumes_all.project_id = projects.id
+WHERE projects.name=? AND storage_volumes_all.storage_pool_id=? AND storage_volumes_all.node_id=?
+AND storage_volumes_all.name=? AND storage_volumes_all.type=?`
inargs := []interface{}{project, poolID, nodeID, volumeName, volumeType}
outargs := []interface{}{&volumeID}
From 21130a84e99b2d741a5b3398841dbdb68cbde41c Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 12:36:53 +0000
Subject: [PATCH 19/38] lxd/db: update storageVolumeNodeGet to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 6662050c82..d7e39c88b6 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -93,9 +93,9 @@ SELECT nodes.id, nodes.address
func (c *Cluster) storageVolumeNodeGet(volumeID int64) (string, error) {
name := ""
query := `
-SELECT nodes.name FROM storage_volumes
- JOIN nodes ON nodes.id=storage_volumes.node_id
- WHERE storage_volumes.id=?
+SELECT nodes.name FROM storage_volumes_all
+ JOIN nodes ON nodes.id=storage_volumes_all.node_id
+ WHERE storage_volumes_all.id=?
`
inargs := []interface{}{volumeID}
outargs := []interface{}{&name}
From b60deea15973b7ba2e24e4415487002237dbc165 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 12:37:01 +0000
Subject: [PATCH 20/38] lxd/db: update StorageVolumeDescriptionGet to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index d7e39c88b6..6779dfcbc9 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -139,7 +139,7 @@ func (c *Cluster) storageVolumeConfigGet(volumeID int64) (map[string]string, err
// StorageVolumeDescriptionGet gets the description of a storage volume.
func (c *Cluster) StorageVolumeDescriptionGet(volumeID int64) (string, error) {
description := sql.NullString{}
- query := "SELECT description FROM storage_volumes WHERE id=?"
+ query := "SELECT description FROM storage_volumes_all WHERE id=?"
inargs := []interface{}{volumeID}
outargs := []interface{}{&description}
From 5c5bff5959349f26813fc276b265cc138e402bb0 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:40:02 +0000
Subject: [PATCH 21/38] lxd/db: update storageVolumeIDsGet to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 6779dfcbc9..2a04d01190 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -300,10 +300,13 @@ func storageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
// given pool, regardless of their node_id column.
func storageVolumeIDsGet(tx *sql.Tx, project, volumeName string, volumeType int, poolID int64) ([]int64, error) {
ids, err := query.SelectIntegers(tx, `
-SELECT storage_volumes.id
- FROM storage_volumes
- JOIN projects ON projects.id = storage_volumes.project_id
- WHERE projects.name=? AND storage_volumes.name=? AND storage_volumes.type=? AND storage_pool_id=?
+SELECT storage_volumes_all.id
+ FROM storage_volumes_all
+ JOIN projects ON projects.id = storage_volumes_all.project_id
+ WHERE projects.name=?
+ AND storage_volumes_all.name=?
+ AND storage_volumes_all.type=?
+ AND storage_volumes_all.storage_pool_id=?
`, project, volumeName, volumeType, poolID)
if err != nil {
return nil, err
From 475cde01d9a93526c8552940fb26c12153f74039 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:50:59 +0000
Subject: [PATCH 22/38] lxd/db: update StoragePoolVolumesGetNames to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 4de793afe2..4fae34a6b9 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -669,7 +669,7 @@ func (c *Cluster) StoragePoolDelete(poolName string) (*api.StoragePool, error) {
// a given storage pool.
func (c *Cluster) StoragePoolVolumesGetNames(poolID int64) ([]string, error) {
var volumeName string
- query := "SELECT name FROM storage_volumes WHERE storage_pool_id=? AND node_id=?"
+ query := "SELECT name FROM storage_volumes_all WHERE storage_pool_id=? AND node_id=?"
inargs := []interface{}{poolID, c.nodeID}
outargs := []interface{}{volumeName}
From 69b907b878f0031c4a6d4bb806633e194f4a8f23 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:52:02 +0000
Subject: [PATCH 23/38] lxd/db: update StoragePoolVolumesGet to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 4fae34a6b9..02784cfd3b 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -696,9 +696,9 @@ func (c *Cluster) StoragePoolVolumesGet(project string, poolID int64, volumeType
var err error
nodeIDs, err = query.SelectIntegers(tx.tx, `
SELECT DISTINCT node_id
- FROM storage_volumes
- JOIN projects ON projects.id = storage_volumes.project_id
- WHERE (projects.name=? OR storage_volumes.type=?) AND storage_pool_id=?
+ FROM storage_volumes_all
+ JOIN projects ON projects.id = storage_volumes_all.project_id
+ WHERE (projects.name=? OR storage_volumes_all.type=?) AND storage_volumes_all.storage_pool_id=?
`, project, StoragePoolVolumeTypeCustom, poolID)
return err
})
From 3ed52bd61a82aacf64397d36ea2466755554b583 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:53:53 +0000
Subject: [PATCH 24/38] lxd/db: update storagePoolVolumesGetType to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 02784cfd3b..ea91896582 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -755,10 +755,13 @@ func (c *Cluster) storagePoolVolumesGet(project string, poolID, nodeID int64, vo
func (c *Cluster) storagePoolVolumesGetType(project string, volumeType int, poolID, nodeID int64) ([]string, error) {
var poolName string
query := `
-SELECT storage_volumes.name
- FROM storage_volumes
- JOIN projects ON projects.id=storage_volumes.project_id
- WHERE (projects.name=? OR storage_volumes.type=?) AND storage_pool_id=? AND node_id=? AND type=?
+SELECT storage_volumes_all.name
+ FROM storage_volumes_all
+ JOIN projects ON projects.id=storage_volumes_all.project_id
+ WHERE (projects.name=? OR storage_volumes_all.type=?)
+ AND storage_volumes_all.storage_pool_id=?
+ AND storage_volumes_all.node_id=?
+ AND storage_volumes_all.type=?
`
inargs := []interface{}{project, StoragePoolVolumeTypeCustom, poolID, nodeID, volumeType}
outargs := []interface{}{poolName}
From 992bbdf7fec809f34b987051559e6b400223faf9 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 15:19:06 +0000
Subject: [PATCH 25/38] lxd/db: update InstancePool to use storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/containers.go | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index 7f0864fce2..c8686db828 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -1096,10 +1096,13 @@ func (c *ClusterTx) InstancePool(project, instanceName string) (string, error) {
poolName := ""
query := `
SELECT storage_pools.name FROM storage_pools
- JOIN storage_volumes ON storage_pools.id=storage_volumes.storage_pool_id
- JOIN instances ON instances.name=storage_volumes.name
+ JOIN storage_volumes_all ON storage_pools.id=storage_volumes_all.storage_pool_id
+ JOIN instances ON instances.name=storage_volumes_all.name
JOIN projects ON projects.id=instances.project_id
- WHERE projects.name=? AND storage_volumes.node_id=? AND storage_volumes.name=? AND storage_volumes.type IN(?,?)
+ WHERE projects.name=?
+ AND storage_volumes_all.node_id=?
+ AND storage_volumes_all.name=?
+ AND storage_volumes_all.type IN(?,?)
`
inargs := []interface{}{project, c.nodeID, instanceName, StoragePoolVolumeTypeContainer, StoragePoolVolumeTypeVM}
outargs := []interface{}{&poolName}
From 14daaee3ca71b3b502af33ec2a8ec6ca47d85084 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 15:20:12 +0000
Subject: [PATCH 26/38] lxd/db: update instancePoolSnapshot to use
storage_volumes_all
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/containers.go | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index c8686db828..6523d2d407 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -1123,9 +1123,12 @@ func (c *ClusterTx) instancePoolSnapshot(project, fullName string) (string, erro
poolName := ""
query := `
SELECT storage_pools.name FROM storage_pools
- JOIN storage_volumes ON storage_pools.id=storage_volumes.storage_pool_id
- JOIN projects ON projects.id=storage_volumes.project_id
- WHERE projects.name=? AND storage_volumes.node_id=? AND storage_volumes.name=? AND storage_volumes.type IN(?,?)
+ JOIN storage_volumes_all ON storage_pools.id=storage_volumes_all.storage_pool_id
+ JOIN projects ON projects.id=storage_volumes_all.project_id
+ WHERE projects.name=?
+ AND storage_volumes_all.node_id=?
+ AND storage_volumes_all.name=?
+ AND storage_volumes_all.type IN(?,?)
`
inargs := []interface{}{project, c.nodeID, fullName, StoragePoolVolumeTypeContainer, StoragePoolVolumeTypeVM}
outargs := []interface{}{&poolName}
From f1d4aacd9b5a864794d30753d02bb2d774fa8cec Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:57:38 +0000
Subject: [PATCH 27/38] lxd/db: make StoragePoolVolumeDelete differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index ea91896582..5c26a28e67 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -918,9 +918,17 @@ func (c *Cluster) StoragePoolVolumeDelete(project, volumeName string, volumeType
return err
}
+ isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)
+ var stmt string
+ if isSnapshot {
+ stmt = "DELETE FROM storage_volumes_snapshots WHERE id=?"
+ } else {
+ stmt = "DELETE FROM storage_volumes WHERE id=?"
+ }
+
err = c.Transaction(func(tx *ClusterTx) error {
err := storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
- _, err := tx.tx.Exec("DELETE FROM storage_volumes WHERE id=?", volumeID)
+ _, err := tx.tx.Exec(stmt, volumeID)
return err
})
return err
From b3169414cec511adabf27599529f91dc1bced004 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:18:38 +0000
Subject: [PATCH 28/38] lxd/db: make storageVolumeConfigGet differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 4 +++-
lxd/db/storage_volumes.go | 9 +++++++--
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 5c26a28e67..7f34b578c5 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -832,6 +832,8 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo
project = "default"
}
+ isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)
+
volumeID, err := c.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
if err != nil {
return -1, nil, err
@@ -842,7 +844,7 @@ func (c *Cluster) storagePoolVolumeGetType(project string, volumeName string, vo
return -1, nil, err
}
- volumeConfig, err := c.storageVolumeConfigGet(volumeID)
+ volumeConfig, err := c.storageVolumeConfigGet(volumeID, isSnapshot)
if err != nil {
return -1, nil, err
}
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 2a04d01190..e173bfae69 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -113,9 +113,14 @@ SELECT nodes.name FROM storage_volumes_all
}
// Get the config of a storage volume.
-func (c *Cluster) storageVolumeConfigGet(volumeID int64) (map[string]string, error) {
+func (c *Cluster) storageVolumeConfigGet(volumeID int64, isSnapshot bool) (map[string]string, error) {
var key, value string
- query := "SELECT key, value FROM storage_volumes_config WHERE storage_volume_id=?"
+ var query string
+ if isSnapshot {
+ query = "SELECT key, value FROM storage_volumes_snapshots_config WHERE storage_volume_snapshot_id=?"
+ } else {
+ query = "SELECT key, value FROM storage_volumes_config WHERE storage_volume_id=?"
+ }
inargs := []interface{}{volumeID}
outargs := []interface{}{key, value}
From 6e552278f06ec70884a44c3e88d5e835894915e9 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:26:53 +0000
Subject: [PATCH 29/38] lxd/db: make storageVolumeDescriptionUpdate
differentiate between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 4 +++-
lxd/db/storage_volumes.go | 11 +++++++++--
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 7f34b578c5..54883f0655 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -889,6 +889,8 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
return err
}
+ isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter)
+
err = c.Transaction(func(tx *ClusterTx) error {
err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
err = storageVolumeConfigClear(tx.tx, volumeID)
@@ -901,7 +903,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
return err
}
- return storageVolumeDescriptionUpdate(tx.tx, volumeID, volumeDescription)
+ return storageVolumeDescriptionUpdate(tx.tx, volumeID, volumeDescription, isSnapshot)
})
if err != nil {
return err
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index e173bfae69..8b8565a688 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -263,8 +263,15 @@ func (c *Cluster) StorageVolumeIsAvailable(pool, volume string) (bool, error) {
}
// Updates the description of a storage volume.
-func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string) error {
- _, err := tx.Exec("UPDATE storage_volumes SET description=? WHERE id=?", description, volumeID)
+func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string, isSnapshot bool) error {
+ var table string
+ if isSnapshot {
+ table = "storage_volumes_snapshots"
+ } else {
+ table = "storage_volumes"
+ }
+ stmt := fmt.Sprintf("UPDATE %s SET description=? WHERE id=?", table)
+ _, err := tx.Exec(stmt, description, volumeID)
return err
}
From ad4789df96988c345f51b181116f95f1e636e734 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:32:23 +0000
Subject: [PATCH 30/38] lxd/db: make storageVolumeConfigAdd differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 4 ++--
lxd/db/storage_volumes.go | 9 +++++++--
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 54883f0655..4d0ca4e6b2 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -898,7 +898,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
return err
}
- err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
+ err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig, isSnapshot)
if err != nil {
return err
}
@@ -1024,7 +1024,7 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, des
thisVolumeID = volumeID
}
- err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig)
+ err = storageVolumeConfigAdd(tx.tx, volumeID, volumeConfig, snapshot)
if err != nil {
tx.tx.Rollback()
return err
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 8b8565a688..9016a31f37 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -276,8 +276,13 @@ func storageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description stri
}
// Add a new storage volume config into database.
-func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string) error {
- str := "INSERT INTO storage_volumes_config (storage_volume_id, key, value) VALUES(?, ?, ?)"
+func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string, isSnapshot bool) error {
+ var str string
+ if isSnapshot {
+ str = "INSERT INTO storage_volumes_snapshots_config (storage_volume_snapshot_id, key, value) VALUES(?, ?, ?)"
+ } else {
+ str = "INSERT INTO storage_volumes_config (storage_volume_id, key, value) VALUES(?, ?, ?)"
+ }
stmt, err := tx.Prepare(str)
defer stmt.Close()
if err != nil {
From 3c7636ef3716310e532cbaee24b590537963beb9 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:36:38 +0000
Subject: [PATCH 31/38] lxd/db: make storageVolumeConfigClear differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 2 +-
lxd/db/storage_volumes.go | 10 ++++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 4d0ca4e6b2..734d0aa22a 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -893,7 +893,7 @@ func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, v
err = c.Transaction(func(tx *ClusterTx) error {
err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error {
- err = storageVolumeConfigClear(tx.tx, volumeID)
+ err = storageVolumeConfigClear(tx.tx, volumeID, isSnapshot)
if err != nil {
return err
}
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index 9016a31f37..c143827334 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -304,8 +304,14 @@ func storageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]
}
// Delete storage volume config.
-func storageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
- _, err := tx.Exec("DELETE FROM storage_volumes_config WHERE storage_volume_id=?", volumeID)
+func storageVolumeConfigClear(tx *sql.Tx, volumeID int64, isSnapshot bool) error {
+ var stmt string
+ if isSnapshot {
+ stmt = "DELETE FROM storage_volumes_snapshots_config WHERE storage_volume_snapshot_id=?"
+ } else {
+ stmt = "DELETE FROM storage_volumes_config WHERE storage_volume_id=?"
+ }
+ _, err := tx.Exec(stmt, volumeID)
if err != nil {
return err
}
From 61675a451eac6076bb816b92637a5e69bad61964 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 15:00:38 +0000
Subject: [PATCH 32/38] lxd/db: make StoragePoolVolumeRename differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index 734d0aa22a..f3c3dff375 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -948,9 +948,19 @@ func (c *Cluster) StoragePoolVolumeRename(project, oldVolumeName string, newVolu
return err
}
+ isSnapshot := strings.Contains(oldVolumeName, shared.SnapshotDelimiter)
+ var stmt string
+ if isSnapshot {
+ parts := strings.Split(newVolumeName, shared.SnapshotDelimiter)
+ newVolumeName = parts[1]
+ stmt = "UPDATE storage_volumes_snapshots SET name=? WHERE id=?"
+ } else {
+ stmt = "UPDATE storage_volumes SET name=? WHERE id=?"
+ }
+
err = c.Transaction(func(tx *ClusterTx) error {
err := storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, oldVolumeName, volumeType, poolID, func(volumeID int64) error {
- _, err := tx.tx.Exec("UPDATE storage_volumes SET name=? WHERE id=? AND type=?", newVolumeName, volumeID, volumeType)
+ _, err := tx.tx.Exec(stmt, newVolumeName, volumeID)
return err
})
return err
From d58515084168f4aee31c728997ee405ef8b491e4 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:42:50 +0000
Subject: [PATCH 33/38] lxd/db: consider snapshots in
StorageVolumeMoveToLVMThinPoolNameKey
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_volumes.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go
index c143827334..314d2fef68 100644
--- a/lxd/db/storage_volumes.go
+++ b/lxd/db/storage_volumes.go
@@ -366,6 +366,10 @@ func (c *Cluster) StorageVolumeMoveToLVMThinPoolNameKey() error {
if err != nil {
return err
}
+ err = exec(c.db, "DELETE FROM storage_volumes_snapshots_config WHERE key='lvm.thinpool_name';")
+ if err != nil {
+ return err
+ }
return nil
}
From dfd38d908468fa7fb478d0922bff35a1816357ad Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 18 Feb 2020 13:25:07 +0000
Subject: [PATCH 34/38] lxd/db: add ClusterTx.storagePoolVolumeGetTypeID()
method
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 42 +++++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index f3c3dff375..c60a3fefce 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -1052,25 +1052,39 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, des
// Return the ID of a storage volume on a given storage pool of a given storage
// volume type, on the given node.
func (c *Cluster) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
- volumeID := int64(-1)
- query := `SELECT storage_volumes_all.id
-FROM storage_volumes_all
-JOIN storage_pools ON storage_volumes_all.storage_pool_id = storage_pools.id
-JOIN projects ON storage_volumes_all.project_id = projects.id
-WHERE projects.name=? AND storage_volumes_all.storage_pool_id=? AND storage_volumes_all.node_id=?
-AND storage_volumes_all.name=? AND storage_volumes_all.type=?`
- inargs := []interface{}{project, poolID, nodeID, volumeName, volumeType}
- outargs := []interface{}{&volumeID}
+ var id int64
+ err := c.Transaction(func(tx *ClusterTx) error {
+ var err error
+ id, err = tx.storagePoolVolumeGetTypeID(project, volumeName, volumeType, poolID, nodeID)
+ return err
+ })
+ if err != nil {
+ return -1, err
+ }
+ return id, nil
+}
+
+func (c *ClusterTx) storagePoolVolumeGetTypeID(project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) {
+ result, err := query.SelectIntegers(c.tx, `
+SELECT storage_volumes_all.id
+ FROM storage_volumes_all
+ JOIN storage_pools ON storage_volumes_all.storage_pool_id = storage_pools.id
+ JOIN projects ON storage_volumes_all.project_id = projects.id
+ WHERE projects.name=?
+ AND storage_volumes_all.storage_pool_id=?
+ AND storage_volumes_all.node_id=?
+ AND storage_volumes_all.name=?
+ AND storage_volumes_all.type=?`, project, poolID, nodeID, volumeName, volumeType)
- err := dbQueryRowScan(c.db, query, inargs, outargs)
if err != nil {
- if err == sql.ErrNoRows {
- return -1, ErrNoSuchObject
- }
return -1, err
}
- return volumeID, nil
+ if len(result) == 0 {
+ return -1, ErrNoSuchObject
+ }
+
+ return int64(result[0]), nil
}
// StoragePoolNodeVolumeGetTypeID get the ID of a storage volume on a given
From 32df5a1c655aa26cd7fe1e700705291ed907abb6 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 15:11:29 +0000
Subject: [PATCH 35/38] lxd/db: make StoragePoolVolumeCreate differentiate
between regular volumes and snapshots
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index c60a3fefce..f30350ab55 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -1002,6 +1002,13 @@ func storagePoolVolumeReplicateIfCeph(tx *sql.Tx, volumeID int64, project, volum
func (c *Cluster) StoragePoolVolumeCreate(project, volumeName, volumeDescription string, volumeType int, snapshot bool, poolID int64, volumeConfig map[string]string) (int64, error) {
var thisVolumeID int64
+ var snapshotName string
+ if snapshot {
+ parts := strings.Split(volumeName, shared.SnapshotDelimiter)
+ volumeName = parts[0]
+ snapshotName = parts[1]
+ }
+
err := c.Transaction(func(tx *ClusterTx) error {
nodeIDs := []int{int(c.nodeID)}
driver, err := storagePoolDriverGet(tx.tx, poolID)
@@ -1017,10 +1024,34 @@ func (c *Cluster) StoragePoolVolumeCreate(project, volumeName, volumeDescription
}
for _, nodeID := range nodeIDs {
- result, err := tx.tx.Exec(`
-INSERT INTO storage_volumes (storage_pool_id, node_id, type, snapshot, name, description, project_id) VALUES (?, ?, ?, ?, ?, ?, (SELECT id FROM projects WHERE name = ?))
+ var result sql.Result
+ // If we are creating a snapshot, figure out the volume
+ // ID of the parent.
+ if snapshot {
+ parentID, err := tx.storagePoolVolumeGetTypeID(
+ project, volumeName, volumeType, poolID, int64(nodeID))
+ if err != nil {
+ return errors.Wrap(err, "Find parent volume")
+ }
+ _, err = tx.tx.Exec(`
+UPDATE sqlite_sequence SET seq = seq + 1 WHERE name = 'storage_volumes'
+`)
+ if err != nil {
+ return errors.Wrap(err, "Increment storage volumes sequence")
+ }
+ result, err = tx.tx.Exec(`
+INSERT INTO storage_volumes_snapshots (id, storage_volume_id, name, description)
+ VALUES ((SELECT seq FROM sqlite_sequence WHERE name = 'storage_volumes' LIMIT 1), ?, ?, ?)
`,
- poolID, nodeID, volumeType, snapshot, volumeName, volumeDescription, project)
+ parentID, snapshotName, volumeDescription)
+ } else {
+
+ result, err = tx.tx.Exec(`
+INSERT INTO storage_volumes (storage_pool_id, node_id, type, name, description, project_id)
+ VALUES (?, ?, ?, ?, ?, (SELECT id FROM projects WHERE name = ?))
+`,
+ poolID, nodeID, volumeType, volumeName, volumeDescription, project)
+ }
if err != nil {
return err
}
From 05fb1147845c1c5c0aa6ea52f59f11fd48f1ddc5 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 15:17:04 +0000
Subject: [PATCH 36/38] lxd/db: no need to update snapshot names in
ContainerNodeMove
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/containers.go | 23 +----------------------
1 file changed, 1 insertion(+), 22 deletions(-)
diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index 6523d2d407..6e855dfda6 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -467,10 +467,6 @@ func (c *ClusterTx) ContainerNodeMove(project, oldName, newName, newNode string)
if err != nil {
return errors.Wrap(err, "failed to get container's ID")
}
- snapshots, err := c.snapshotIDsAndNames(project, oldName)
- if err != nil {
- return errors.Wrap(err, "failed to get container's snapshots")
- }
node, err := c.NodeByName(newNode)
if err != nil {
return errors.Wrap(err, "failed to get new node's info")
@@ -493,7 +489,7 @@ func (c *ClusterTx) ContainerNodeMove(project, oldName, newName, newNode string)
return nil
}
- // Update the container's and snapshots' storage volume name (since this is ceph,
+ // Update the instance's storage volume name (since this is ceph,
// there's a clone of the volume for each node).
count, err := c.NodesCount()
if err != nil {
@@ -511,23 +507,6 @@ func (c *ClusterTx) ContainerNodeMove(project, oldName, newName, newNode string)
if n != int64(count) {
return fmt.Errorf("unexpected number of updated rows in volumes table: %d", n)
}
- for _, snapshotName := range snapshots {
- oldSnapshotName := oldName + shared.SnapshotDelimiter + snapshotName
- newSnapshotName := newName + shared.SnapshotDelimiter + snapshotName
- stmt := "UPDATE storage_volumes SET name=? WHERE name=? AND storage_pool_id=? AND type=?"
- result, err := c.tx.Exec(
- stmt, newSnapshotName, oldSnapshotName, poolID, StoragePoolVolumeTypeContainer)
- if err != nil {
- return errors.Wrap(err, "failed to update snapshot volume")
- }
- n, err = result.RowsAffected()
- if err != nil {
- return errors.Wrap(err, "failed to get rows affected by snapshot volume update")
- }
- if n != int64(count) {
- return fmt.Errorf("unexpected number of updated snapshots in volumes table: %d", n)
- }
- }
return nil
}
From 68907d21989d5e82a1db180f982d5f18abf1fdd6 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 17 Feb 2020 14:49:30 +0000
Subject: [PATCH 37/38] lxd/db: copy volume snapshots in
StoragePoolNodeJoinCeph
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/db/storage_pools.go | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index f30350ab55..1995b6cdc0 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -161,6 +161,7 @@ SELECT id FROM storage_volumes WHERE storage_pool_id=? AND node_id=?
return fmt.Errorf("not all ceph volumes were copied")
}
for i, otherVolumeID := range otherVolumeIDs {
+ volumeID := volumeIDs[i]
config, err := query.SelectConfig(
c.tx, "storage_volumes_config", "storage_volume_id=?", otherVolumeID)
if err != nil {
@@ -169,11 +170,46 @@ SELECT id FROM storage_volumes WHERE storage_pool_id=? AND node_id=?
for key, value := range config {
_, err := c.tx.Exec(`
INSERT INTO storage_volumes_config(storage_volume_id, key, value) VALUES(?, ?, ?)
-`, volumeIDs[i], key, value)
+`, volumeID, key, value)
if err != nil {
return errors.Wrap(err, "failed to copy volume config")
}
}
+
+ // Copy volume snapshots as well.
+ otherSnapshotIDs, err := query.SelectIntegers(c.tx,
+ "SELECT id FROM storage_volumes_snapshots WHERE storage_volume_id = ?",
+ otherVolumeID)
+
+ for _, otherSnapshotID := range otherSnapshotIDs {
+ _, err := c.tx.Exec("UPDATE sqlite_sequence SET seq = seq + 1 WHERE name = 'storage_volumes")
+ if err != nil {
+ return errors.Wrap(err, "Increment storage volumes sequence")
+ }
+
+ result, err := c.tx.Exec(`
+INSERT INTO storage_volumes_snapshots (id, storage_volume_id, name, description)
+SELECT (SELECT seq FROM sqlite_sequence WHERE name = 'storage_volumes' LIMIT 1), ?, name, description
+ FROM storage_volumes_snapshots WHERE id=?
+`, volumeID, otherSnapshotID)
+ if err != nil {
+ return errors.Wrap(err, "Copy volume snapshot")
+ }
+ snapshotID, err := result.LastInsertId()
+ if err != nil {
+ return err
+ }
+
+ _, err = c.tx.Exec(`
+INSERT INTO storage_volumes_snapshots_config (storage_volume_snapshot_id, key, value)
+SELECT ?, key, value
+ FROM storage_volumes_snapshots_config
+ WHERE storage_volume_snapshot_id=?
+`, snapshotID, otherSnapshotID)
+ if err != nil {
+ return errors.Wrap(err, "Copy volume snapshot config")
+ }
+ }
}
return nil
From 1803e53a897a63c68ab30ccc27480512e08ac7a1 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 18 Feb 2020 16:07:25 +0000
Subject: [PATCH 38/38] lxd: no need to rename snapshot volumes when renaming a
container
Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
lxd/container_lxc.go | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 361ff52d6e..c7ec0200e9 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3681,28 +3681,6 @@ func (c *containerLXC) Rename(newName string) error {
poolID, _, _ := c.storage.GetContainerPoolInfo()
- if !c.IsSnapshot() {
- // Rename all the snapshot volumes.
- results, err := c.state.Cluster.ContainerGetSnapshots(c.project, oldName)
- if err != nil {
- logger.Error("Failed to get container snapshots", ctxMap)
- return err
- }
-
- for _, sname := range results {
- // Rename the snapshot volume.
- baseSnapName := filepath.Base(sname)
- newSnapshotName := newName + shared.SnapshotDelimiter + baseSnapName
-
- // Rename storage volume for the snapshot.
- err = c.state.Cluster.StoragePoolVolumeRename(c.project, sname, newSnapshotName, storagePoolVolumeTypeContainer, poolID)
- if err != nil {
- logger.Error("Failed renaming storage volume", ctxMap)
- return err
- }
- }
- }
-
// Rename storage volume for the container.
err = c.state.Cluster.StoragePoolVolumeRename(c.project, oldName, newName, storagePoolVolumeTypeContainer, poolID)
if err != nil {
More information about the lxc-devel
mailing list