The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6723

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From fd4617adaa58ca9e347cb748071e66cf11f25864 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Thu, 16 Jan 2020 16:05:40 +0000
Subject: [PATCH 1/3] Make cluster.Rebalance fail immediately if not leader

Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
---
 lxd/cluster/membership.go | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lxd/cluster/membership.go b/lxd/cluster/membership.go
index 996a1c64d5..ed08b127da 100644
--- a/lxd/cluster/membership.go
+++ b/lxd/cluster/membership.go
@@ -479,11 +479,18 @@ func notifyNodesUpdate(raftNodes []db.RaftNode, id 
uint64, cert *shared.CertInfo
 // If there's such spare node, return its address as well as the new list of
 // raft nodes.
 func Rebalance(state *state.State, gateway *Gateway) (string, []db.RaftNode, 
error) {
+       // First get the current raft members, since this method should be
+       // called after a node has left.
+       currentRaftNodes, err := gateway.currentRaftNodes()
+       if err != nil {
+               return "", nil, errors.Wrap(err, "failed to get current raft 
nodes")
+       }
+
        // Fetch the nodes from the database, to get their last heartbeat
        // timestamp and check whether they are offline.
        nodesByAddress := map[string]db.NodeInfo{}
        var offlineThreshold time.Duration
-       err := state.Cluster.Transaction(func(tx *db.ClusterTx) error {
+       err = state.Cluster.Transaction(func(tx *db.ClusterTx) error {
                config, err := ConfigLoad(tx)
                if err != nil {
                        return errors.Wrap(err, "failed load cluster 
configuration")
@@ -502,13 +509,6 @@ func Rebalance(state *state.State, gateway *Gateway) 
(string, []db.RaftNode, err
                return "", nil, err
        }
 
-       // First get the current raft members, since this method should be
-       // called after a node has left.
-       currentRaftNodes, err := gateway.currentRaftNodes()
-       if err != nil {
-               return "", nil, errors.Wrap(err, "failed to get current raft 
nodes")
-       }
-
        // Group by role. If a node is offline, we'll try to demote it right
        // away.
        voters := make([]string, 0)

From e6e584d64acab30174fbb1f72bf84e7b9e30f3fc Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Thu, 16 Jan 2020 16:06:19 +0000
Subject: [PATCH 2/3] Export cluster.ErrNotLeader

Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
---
 lxd/cluster/gateway.go   | 8 ++++----
 lxd/cluster/heartbeat.go | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lxd/cluster/gateway.go b/lxd/cluster/gateway.go
index 023593247f..194e9da661 100644
--- a/lxd/cluster/gateway.go
+++ b/lxd/cluster/gateway.go
@@ -723,8 +723,8 @@ func (g *Gateway) isLeader() (bool, error) {
        return leader != nil && leader.ID == g.info.ID, nil
 }
 
-// Internal error signalling that a node not the leader.
-var errNotLeader = fmt.Errorf("Not leader")
+// ErrNotLeader signals that a node not the leader.
+var ErrNotLeader = fmt.Errorf("Not leader")
 
 // Return information about the LXD nodes that a currently part of the raft
 // cluster, as configured in the raft log. It returns an error if this node is
@@ -734,7 +734,7 @@ func (g *Gateway) currentRaftNodes() ([]db.RaftNode, error) 
{
        defer g.lock.RUnlock()
 
        if g.info == nil || g.info.Role != db.RaftVoter {
-               return nil, errNotLeader
+               return nil, ErrNotLeader
        }
 
        isLeader, err := g.isLeader()
@@ -742,7 +742,7 @@ func (g *Gateway) currentRaftNodes() ([]db.RaftNode, error) 
{
                return nil, err
        }
        if !isLeader {
-               return nil, errNotLeader
+               return nil, ErrNotLeader
        }
        client, err := g.getClient()
        if err != nil {
diff --git a/lxd/cluster/heartbeat.go b/lxd/cluster/heartbeat.go
index e00a7e1764..27aeb80767 100644
--- a/lxd/cluster/heartbeat.go
+++ b/lxd/cluster/heartbeat.go
@@ -194,7 +194,7 @@ func (g *Gateway) heartbeat(ctx context.Context, 
initialHeartbeat bool) {
        }
 
        raftNodes, err := g.currentRaftNodes()
-       if err == errNotLeader {
+       if err == ErrNotLeader {
                return
        }
 

From 1bebfb93cfab723d28433fd86b3bcbf7710b74f8 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Thu, 16 Jan 2020 16:10:06 +0000
Subject: [PATCH 3/3] Silence warning about failing to rebalance when not
 leader

Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
---
 lxd/daemon.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index 88b2c1142d..646f1d82df 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -1482,7 +1482,7 @@ func (d *Daemon) NodeRefreshTask(heartbeatData 
*cluster.APIHeartbeat) {
                                d.clusterMembershipMutex.Lock()
                                defer d.clusterMembershipMutex.Unlock()
                                err := rebalanceMemberRoles(d)
-                               if err != nil {
+                               if err != nil && errors.Cause(err) != 
cluster.ErrNotLeader {
                                        logger.Warnf("Could not rebalance 
cluster member roles: %v", err)
                                }
                        }()
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to