[lxc-devel] [lxd/master] lxd/cluster: Fix failure domain updates

stgraber on Github lxc-bot at linuxcontainers.org
Fri Jul 31 20:51:25 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 354 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200731/e900e83e/attachment.bin>
-------------- next part --------------
From 94f8c7dd15daa39b4099007a34b7d81f4ad9eded Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 31 Jul 2020 16:50:43 -0400
Subject: [PATCH] lxd/cluster: Fix failure domain updates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/api_cluster.go | 44 +++++++++++++++++++++-----------------------
 lxd/db/node.go     |  5 +++++
 2 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/lxd/api_cluster.go b/lxd/api_cluster.go
index 15e2ed39b2..0416cc872f 100644
--- a/lxd/api_cluster.go
+++ b/lxd/api_cluster.go
@@ -870,7 +870,7 @@ func clusterNodeGet(d *Daemon, r *http.Request) response.Response {
 
 	for _, node := range nodes {
 		if node.ServerName == name {
-			return response.SyncResponseETag(true, node, node.Roles)
+			return response.SyncResponseETag(true, node, node.ClusterMemberPut)
 		}
 	}
 
@@ -886,32 +886,25 @@ func clusterNodePut(d *Daemon, r *http.Request) response.Response {
 	name := mux.Vars(r)["name"]
 
 	// Find the requested one.
-	var current db.NodeInfo
-	var currentFailureDomain string
-	var err error
-	err = d.cluster.Transaction(func(tx *db.ClusterTx) error {
-		current, err = tx.GetNodeByName(name)
-		if err != nil {
-			return errors.Wrap(err, "Load current node state")
-		}
+	nodes, err := cluster.List(d.State(), d.gateway)
+	if err != nil {
+		return response.SmartError(err)
+	}
 
-		currentFailureDomain, err = tx.GetNodeFailureDomain(current.ID)
-		if err != nil {
-			return errors.Wrap(err, "Load current failure domain")
+	var current *api.ClusterMember
+	for _, node := range nodes {
+		if node.ServerName == name {
+			current = &node
+			break
 		}
+	}
 
-		return nil
-	})
-	if err != nil {
-		return response.SmartError(err)
+	if current == nil {
+		return response.NotFound(fmt.Errorf("Member '%s' not found", name))
 	}
 
 	// Validate the request is fine
-	etag := []interface{}{
-		current.Roles,
-		currentFailureDomain,
-	}
-	err = util.EtagCheck(r, etag)
+	err = util.EtagCheck(r, current.ClusterMemberPut)
 	if err != nil {
 		return response.PreconditionFailed(err)
 	}
@@ -935,17 +928,22 @@ func clusterNodePut(d *Daemon, r *http.Request) response.Response {
 
 	// Update the database
 	err = d.cluster.Transaction(func(tx *db.ClusterTx) error {
+		nodeInfo, err := tx.GetNodeByName(name)
+		if err != nil {
+			return errors.Wrap(err, "Loading node information")
+		}
+
 		dbRoles := []db.ClusterRole{}
 		for _, role := range req.Roles {
 			dbRoles = append(dbRoles, db.ClusterRole(role))
 		}
 
-		err := tx.UpdateNodeRoles(current.ID, dbRoles)
+		err = tx.UpdateNodeRoles(nodeInfo.ID, dbRoles)
 		if err != nil {
 			return errors.Wrap(err, "Update roles")
 		}
 
-		err = tx.UpdateNodeFailureDomain(current.ID, req.FailureDomain)
+		err = tx.UpdateNodeFailureDomain(nodeInfo.ID, req.FailureDomain)
 		if err != nil {
 			return errors.Wrap(err, "Update failure domain")
 		}
diff --git a/lxd/db/node.go b/lxd/db/node.go
index ceb2ee2b8c..3afa6a073c 100644
--- a/lxd/db/node.go
+++ b/lxd/db/node.go
@@ -433,6 +433,11 @@ func (c *ClusterTx) UpdateNodeRoles(id int64, roles []ClusterRole) error {
 	// Translate role names to ids
 	roleIDs := []int{}
 	for _, role := range roles {
+		// Skip internal-only roles.
+		if role == ClusterRoleDatabase {
+			continue
+		}
+
 		roleID, err := getRoleID(role)
 		if err != nil {
 			return err


More information about the lxc-devel mailing list