[lxc-devel] [lxd/master] Network: Adds project_id column to networks table

tomponline on Github lxc-bot at linuxcontainers.org
Mon Aug 24 10:32:19 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 368 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200824/47a63d90/attachment.bin>
-------------- next part --------------
From 713106b8d885ab4c7470b8be5176b3e30a78482b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 15:46:38 +0100
Subject: [PATCH 1/6] lxd/db/projects: go imports order

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/db/projects.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lxd/db/projects.go b/lxd/db/projects.go
index df19a9601b..3158c5e906 100644
--- a/lxd/db/projects.go
+++ b/lxd/db/projects.go
@@ -6,10 +6,11 @@ import (
 	"database/sql"
 	"fmt"
 
+	"github.com/pkg/errors"
+
 	"github.com/lxc/lxd/lxd/db/query"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
-	"github.com/pkg/errors"
 )
 
 // Code generation directives.

From 06e22fc3b4a23f69dfc3b470d3f54542af60b37b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 15:46:47 +0100
Subject: [PATCH 2/6] lxd/db/projects: Removes unnecessary whitespace

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/db/projects.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/db/projects.go b/lxd/db/projects.go
index 3158c5e906..cf03765ea5 100644
--- a/lxd/db/projects.go
+++ b/lxd/db/projects.go
@@ -184,7 +184,7 @@ func (c *ClusterTx) InitProjectWithoutImages(project string) error {
 	if err != nil {
 		return errors.Wrap(err, "Fetch project ID")
 	}
-	stmt := `INSERT INTO images_profiles (image_id, profile_id) 
+	stmt := `INSERT INTO images_profiles (image_id, profile_id)
 	SELECT images.id, ? FROM images WHERE project_id=1`
 	_, err = c.tx.Exec(stmt, defaultProfileID)
 	return err

From 3ae4e7b57583a8cf21cbca8a237f624e81ffc42b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 15:28:42 +0100
Subject: [PATCH 3/6] lxd/db/cluster: Adds patch for adding project_id to
 networks table

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/db/cluster/schema.go | 15 +++++-----
 lxd/db/cluster/update.go | 61 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 701847d41a..e3e49f09ff 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -276,30 +276,31 @@ CREATE VIEW instances_snapshots_devices_ref (
      JOIN instances ON instances.id=instances_snapshots.instance_id
      JOIN projects ON projects.id=instances.project_id
      JOIN instances_snapshots ON instances_snapshots.id=instances_snapshots_devices.instance_snapshot_id;
-CREATE TABLE networks (
+CREATE TABLE "networks" (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    project_id INTEGER NOT NULL,
     name TEXT NOT NULL,
     description TEXT,
     state INTEGER NOT NULL DEFAULT 0,
     type INTEGER NOT NULL DEFAULT 0,
-    UNIQUE (name)
+    UNIQUE (project_id, name)
 );
-CREATE TABLE networks_config (
+CREATE TABLE "networks_config" (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     network_id INTEGER NOT NULL,
     node_id INTEGER,
     key TEXT NOT NULL,
     value TEXT,
     UNIQUE (network_id, node_id, key),
-    FOREIGN KEY (network_id) REFERENCES networks (id) ON DELETE CASCADE,
+    FOREIGN KEY (network_id) REFERENCES "networks" (id) ON DELETE CASCADE,
     FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
 );
-CREATE TABLE networks_nodes (
+CREATE TABLE "networks_nodes" (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     network_id INTEGER NOT NULL,
     node_id INTEGER NOT NULL,
     UNIQUE (network_id, node_id),
-    FOREIGN KEY (network_id) REFERENCES networks (id) ON DELETE CASCADE,
+    FOREIGN KEY (network_id) REFERENCES "networks" (id) ON DELETE CASCADE,
     FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
 );
 CREATE TABLE nodes (
@@ -572,5 +573,5 @@ CREATE TABLE storage_volumes_snapshots_config (
     UNIQUE (storage_volume_snapshot_id, key)
 );
 
-INSERT INTO schema (version, updated_at) VALUES (33, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (34, strftime("%s"))
 `
diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index c6fd84cbfb..a7f371e94e 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -70,6 +70,67 @@ var updates = map[int]schema.Update{
 	31: updateFromV30,
 	32: updateFromV31,
 	33: updateFromV32,
+	34: updateFromV33,
+}
+
+// Add project_id field to networks, add unique index across project_id and name,
+// and set existing networks to project_id 1.
+// This is made a lot more complex because it requires re-creating the referenced tables as there is no way to
+// disable foreign keys temporarily within a transaction.
+func updateFromV33(tx *sql.Tx) error {
+	_, err := tx.Exec(`
+CREATE TABLE networks_new (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    project_id INTEGER NOT NULL,
+    name TEXT NOT NULL,
+    description TEXT,
+    state INTEGER NOT NULL DEFAULT 0,
+    type INTEGER NOT NULL DEFAULT 0,
+    UNIQUE (project_id, name)
+);
+
+INSERT INTO networks_new (id, project_id, name, description, state, type)
+    SELECT id, 1, name, description, state, type FROM networks;
+
+CREATE TABLE networks_nodes_new (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    network_id INTEGER NOT NULL,
+    node_id INTEGER NOT NULL,
+    UNIQUE (network_id, node_id),
+    FOREIGN KEY (network_id) REFERENCES networks_new (id) ON DELETE CASCADE,
+    FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
+);
+
+INSERT INTO networks_nodes_new (id, network_id, node_id)
+    SELECT id, network_id, node_id FROM networks_nodes;
+
+CREATE TABLE networks_config_new (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    network_id INTEGER NOT NULL,
+    node_id INTEGER,
+    key TEXT NOT NULL,
+    value TEXT,
+    UNIQUE (network_id, node_id, key),
+    FOREIGN KEY (network_id) REFERENCES networks_new (id) ON DELETE CASCADE,
+    FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
+);
+
+INSERT INTO networks_config_new (id, network_id, node_id, key, value)
+    SELECT id, network_id, node_id, key, value FROM networks_config;
+
+DROP TABLE networks;
+DROP TABLE networks_nodes;
+DROP TABLE networks_config;
+
+ALTER TABLE networks_new RENAME TO networks;
+ALTER TABLE networks_nodes_new RENAME TO networks_nodes;
+ALTER TABLE networks_config_new RENAME TO networks_config;
+	`)
+	if err != nil {
+		return errors.Wrap(err, "Failed to add project_id column to networks table")
+	}
+
+	return nil
 }
 
 // Add type field to networks.

From 2f1848147bd33908571660c2bf129ac0e75e38f5 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 15:47:19 +0100
Subject: [PATCH 4/6] lxd/db/networks: Adds project support to
 CreatePendingNetwork

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

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index 6290f30f4f..e72bcc35c6 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -7,6 +7,8 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/pkg/errors"
+
 	"github.com/lxc/lxd/lxd/db/query"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -209,7 +211,7 @@ WHERE networks.id = ? AND networks.state = ?
 }
 
 // CreatePendingNetwork creates a new pending network on the node with the given name.
-func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType, conf map[string]string) error {
+func (c *ClusterTx) CreatePendingNetwork(node string, projectName string, name string, netType NetworkType, conf map[string]string) error {
 	// First check if a network with the given name exists, and, if so, that it's in the pending state.
 	network := struct {
 		id      int64
@@ -243,9 +245,14 @@ func (c *ClusterTx) CreatePendingNetwork(node, name string, netType NetworkType,
 
 	var networkID = network.id
 	if networkID == 0 {
+		projectID, err := c.GetProjectID(projectName)
+		if err != nil {
+			return errors.Wrap(err, "Fetch project ID")
+		}
+
 		// No existing network with the given name was found, let's create one.
-		columns := []string{"name", "type", "description"}
-		values := []interface{}{name, netType, ""}
+		columns := []string{"project_id", "name", "type", "description"}
+		values := []interface{}{projectID, name, netType, ""}
 		networkID, err = query.UpsertObject(c.tx, "networks", columns, values)
 		if err != nil {
 			return err

From 3d75cd2ad2f3950b636815bf6ffd56921f36644f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 15:12:52 +0100
Subject: [PATCH 5/6] lxd/db/networks: Adds project support to CreateNetwork

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

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index e72bcc35c6..c41c06fc3b 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -612,10 +612,11 @@ func (c *Cluster) getNetworkConfig(id int64) (map[string]string, error) {
 }
 
 // CreateNetwork creates a new network.
-func (c *Cluster) CreateNetwork(name, description string, netType NetworkType, config map[string]string) (int64, error) {
+func (c *Cluster) CreateNetwork(projectName string, name string, description string, netType NetworkType, config map[string]string) (int64, error) {
 	var id int64
 	err := c.Transaction(func(tx *ClusterTx) error {
-		result, err := tx.tx.Exec("INSERT INTO networks (name, description, state, type) VALUES (?, ?, ?, ?)", name, description, networkCreated, netType)
+		result, err := tx.tx.Exec("INSERT INTO networks (project_id, name, description, state, type) VALUES ((SELECT id FROM projects WHERE name = ?), ?, ?, ?, ?)",
+			projectName, name, description, networkCreated, netType)
 		if err != nil {
 			return err
 		}

From cd2a5aff8225b9d0eb61b946302201a81a4f14e3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 24 Aug 2020 11:29:42 +0100
Subject: [PATCH 6/6] lxd/networks: Pass project.Default when creating networks

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

diff --git a/lxd/networks.go b/lxd/networks.go
index 7134609948..60bd4a8642 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -163,7 +163,7 @@ func networksPost(d *Daemon, r *http.Request) response.Response {
 		}
 
 		err = d.cluster.Transaction(func(tx *db.ClusterTx) error {
-			return tx.CreatePendingNetwork(targetNode, req.Name, dbNetType, req.Config)
+			return tx.CreatePendingNetwork(targetNode, project.Default, req.Name, dbNetType, req.Config)
 		})
 		if err != nil {
 			if err == db.ErrAlreadyDefined {
@@ -208,7 +208,7 @@ func networksPost(d *Daemon, r *http.Request) response.Response {
 	defer revert.Fail()
 
 	// Create the database entry.
-	_, err = d.cluster.CreateNetwork(req.Name, req.Description, dbNetType, req.Config)
+	_, err = d.cluster.CreateNetwork(project.Default, req.Name, req.Description, dbNetType, req.Config)
 	if err != nil {
 		return response.SmartError(errors.Wrapf(err, "Error inserting %q into database", req.Name))
 	}


More information about the lxc-devel mailing list