[lxc-devel] [lxd/master] Make lvm.thinpool_name and lvm.vg_name node-specific

freeekanayaka on Github lxc-bot at linuxcontainers.org
Tue Jul 24 07:51:53 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 361 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180724/9f392533/attachment.bin>
-------------- next part --------------
From 1b67e1cc9a9f4851695c898fbb16bc31b444dfe3 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 24 Jul 2018 07:50:13 +0000
Subject: [PATCH] Make lvm.thinpool_name and lvm.vg_name node-specific

Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
 lxd/db/cluster/schema.go      |  2 +-
 lxd/db/cluster/update.go      | 55 ++++++++++++++++++++++++++++++++++++++++++
 lxd/db/cluster/update_test.go | 56 +++++++++++++++++++++++++++++++++++++++++++
 lxd/db/storage_pools.go       |  2 ++
 4 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index b04281e29..5dc7a7272 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -246,5 +246,5 @@ CREATE TABLE storage_volumes_config (
     FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
 );
 
-INSERT INTO schema (version, updated_at) VALUES (8, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (9, strftime("%s"))
 `
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index f2f9b2306..d53e59e1b 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -38,6 +38,61 @@ var updates = map[int]schema.Update{
 	6: updateFromV5,
 	7: updateFromV6,
 	8: updateFromV7,
+	9: updateFromV8,
+}
+
+// The lvm.thinpool_name and lvm.vg_name config keys are node-specific and need
+// to be linked to nodes.
+func updateFromV8(tx *sql.Tx) error {
+	// Fetch the IDs of all existing nodes.
+	nodeIDs, err := query.SelectIntegers(tx, "SELECT id FROM nodes")
+	if err != nil {
+		return errors.Wrap(err, "failed to get IDs of current nodes")
+	}
+
+	// Fetch the IDs of all existing lvm pools.
+	poolIDs, err := query.SelectIntegers(tx, "SELECT id FROM storage_pools WHERE driver='lvm'")
+	if err != nil {
+		return errors.Wrap(err, "failed to get IDs of current lvm pools")
+	}
+
+	for _, poolID := range poolIDs {
+		// Fetch the config for this lvm pool and check if it has the
+		// lvn.thinpool_name or lvm.vg_name keys.
+		config, err := query.SelectConfig(
+			tx, "storage_pools_config", "storage_pool_id=? AND node_id IS NULL", poolID)
+		if err != nil {
+			return errors.Wrap(err, "failed to fetch of lvm pool config")
+		}
+
+		for _, key := range []string{"lvm.thinpool_name", "lvm.vg_name"} {
+			value, ok := config[key]
+			if !ok {
+				continue
+			}
+
+			// Delete the current key
+			_, err = tx.Exec(`
+DELETE FROM storage_pools_config WHERE key=? AND storage_pool_id=? AND node_id IS NULL
+`, key, poolID)
+			if err != nil {
+				return errors.Wrapf(err, "failed to delete %s config", key)
+			}
+
+			// Add the config entry for each node
+			for _, nodeID := range nodeIDs {
+				_, err := tx.Exec(`
+INSERT INTO storage_pools_config(storage_pool_id, node_id, key, value)
+  VALUES(?, ?, ?, ?)
+`, poolID, nodeID, key, value)
+				if err != nil {
+					return errors.Wrapf(err, "failed to create %s node config", key)
+				}
+			}
+		}
+	}
+
+	return nil
 }
 
 func updateFromV7(tx *sql.Tx) error {
diff --git a/lxd/db/cluster/update_test.go b/lxd/db/cluster/update_test.go
index cc8717b3e..1c9be1adb 100644
--- a/lxd/db/cluster/update_test.go
+++ b/lxd/db/cluster/update_test.go
@@ -346,3 +346,59 @@ INSERT INTO storage_pools_config(storage_pool_id, node_id, key, value)
 	require.NoError(t, err)
 	assert.Equal(t, map[string]string{"zfs.clone_copy": "true"}, config)
 }
+
+func TestUpdateFromV8(t *testing.T) {
+	schema := cluster.Schema()
+	db, err := schema.ExerciseUpdate(9, func(db *sql.DB) {
+		// Create two nodes.
+		_, err := db.Exec(
+			"INSERT INTO nodes VALUES (1, 'n1', '', '1.2.3.4:666', 1, 32, ?, 0)",
+			time.Now())
+		require.NoError(t, err)
+		_, err = db.Exec(
+			"INSERT INTO nodes VALUES (2, 'n2', '', '5.6.7.8:666', 1, 32, ?, 0)",
+			time.Now())
+		require.NoError(t, err)
+
+		// Create a pool p1 of type lvm.
+		_, err = db.Exec("INSERT INTO storage_pools VALUES (1, 'p1', 'lvm', '', 0)")
+		require.NoError(t, err)
+
+		// Create a pool p2 of type lvm.
+		_, err = db.Exec("INSERT INTO storage_pools VALUES (2, 'p2', 'lvm', '', 0)")
+		require.NoError(t, err)
+
+		// Create a lvm.thinpool_name config for p1.
+		_, err = db.Exec(`
+INSERT INTO storage_pools_config(storage_pool_id, node_id, key, value)
+  VALUES(1, NULL, 'lvm.thinpool_name', 'my-pool')
+`)
+		require.NoError(t, err)
+
+		// Create a rsync.bwlimit config for p2.
+		_, err = db.Exec(`
+INSERT INTO storage_pools_config(storage_pool_id, node_id, key, value)
+  VALUES(2, NULL, 'rsync.bwlimit', '64')
+`)
+		require.NoError(t, err)
+	})
+	require.NoError(t, err)
+
+	tx, err := db.Begin()
+	require.NoError(t, err)
+	defer tx.Rollback()
+
+	// Check the lvm.thinpool_name config is now node-specific.
+	for _, nodeID := range []int{1, 2} {
+		config, err := query.SelectConfig(
+			tx, "storage_pools_config", "storage_pool_id=1 AND node_id=?", nodeID)
+		require.NoError(t, err)
+		assert.Equal(t, map[string]string{"lvm.thinpool_name": "my-pool"}, config)
+	}
+
+	// Check the rsync.bwlimit key is still global
+	config, err := query.SelectConfig(
+		tx, "storage_pools_config", "storage_pool_id=2 AND node_id IS NULL")
+	require.NoError(t, err)
+	assert.Equal(t, map[string]string{"rsync.bwlimit": "64"}, config)
+}
diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go
index d977f31cc..4a4f50725 100644
--- a/lxd/db/storage_pools.go
+++ b/lxd/db/storage_pools.go
@@ -1008,6 +1008,8 @@ var StoragePoolNodeConfigKeys = []string{
 	"source",
 	"volatile.initial_source",
 	"zfs.pool_name",
+	"lvm.thinpool",
+	"lvm.vg_name",
 }
 
 // StoragePoolVolumeTypeToName converts a volume integer type code to its


More information about the lxc-devel mailing list