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
