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

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) ===

Signed-off-by: Free Ekanayaka <[email protected]>
From 4bf0346d36c38295488da59813466d285c7664a7 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <[email protected]>
Date: Tue, 21 May 2019 13:48:24 +0200
Subject: [PATCH] Trigger the upgrade script if we detect a dqlite client with
 higher version

Signed-off-by: Free Ekanayaka <[email protected]>
---
 lxd/cluster/gateway.go | 30 ++++++++++++++++++++++++++++++
 lxd/cluster/upgrade.go | 11 ++++++++---
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/lxd/cluster/gateway.go b/lxd/cluster/gateway.go
index c34fdd1c0a..29d3337752 100644
--- a/lxd/cluster/gateway.go
+++ b/lxd/cluster/gateway.go
@@ -98,12 +98,19 @@ type Gateway struct {
        // their version.
        upgradeCh chan struct{}
 
+       // Used to track whether we already triggered an upgrade because we
+       // detected a peer with an higher version.
+       upgradeTriggered bool
+
        // ServerStore wrapper.
        store *dqliteServerStore
 
        lock sync.RWMutex
 }
 
+// Current dqlite protocol version.
+const dqliteVersion = 0
+
 // HandlerFuncs returns the HTTP handlers that should be added to the REST API
 // endpoint in order to handle database-related requests.
 //
@@ -123,6 +130,29 @@ func (g *Gateway) HandlerFuncs() 
map[string]http.HandlerFunc {
                        return
                }
 
+               // Compare the dqlite version of the connecting client
+               // with our own one.
+               versionHeader := r.Header.Get("X-Dqlite-Version")
+               if versionHeader == "" {
+                       // No version header means an old pre dqlite 1.0 client.
+                       versionHeader = "0"
+               }
+               version, err := strconv.Atoi(versionHeader)
+               if err != nil {
+                       http.Error(w, "400 invalid dqlite version", 
http.StatusBadRequest)
+                       return
+               }
+               if version != dqliteVersion {
+                       if !g.upgradeTriggered && version > dqliteVersion {
+                               err = triggerUpdate()
+                               if err == nil {
+                                       g.upgradeTriggered = true
+                               }
+                       }
+                       http.Error(w, "503 dqlite version mismatch", 
http.StatusServiceUnavailable)
+                       return
+               }
+
                // Handle heatbeats.
                if r.Method == "PUT" {
                        var nodes []db.RaftNode
diff --git a/lxd/cluster/upgrade.go b/lxd/cluster/upgrade.go
index c4165343e4..df649da997 100644
--- a/lxd/cluster/upgrade.go
+++ b/lxd/cluster/upgrade.go
@@ -110,19 +110,24 @@ func maybeUpdate(state *state.State) {
                return
        }
 
+       triggerUpdate()
+}
+
+func triggerUpdate() error {
        logger.Infof("Node is out-of-date with respect to other cluster nodes")
 
        updateExecutable := os.Getenv("LXD_CLUSTER_UPDATE")
        if updateExecutable == "" {
                logger.Debug("No LXD_CLUSTER_UPDATE variable set, skipping 
auto-update")
-               return
+               return nil
        }
 
        logger.Infof("Triggering cluster update using: %s", updateExecutable)
 
-       _, err = shared.RunCommand(updateExecutable)
+       _, err := shared.RunCommand(updateExecutable)
        if err != nil {
                logger.Errorf("Cluster upgrade failed: '%v'", err.Error())
-               return
+               return err
        }
+       return nil
 }
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to