From 4b63dc7a96890c0a32f218d98b8162cbc7dacd98 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 13 Oct 2010 12:29:26 +0200
Subject: [PATCH] "Fix" handling of old software versions on startup

Currently, masterd startup with old software versions is very confusing
for users: we present two tracebacks, with a message in the middle about
"version mismatch". This can lead to users believing that all that needs
to be done is to fix the config file.

This patch attempts to improve this by handling this case in masterd
itself (not in the child), and showing a more friendly message for this
case.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 daemons/ganeti-masterd | 22 ++++++++++++++++++++++
 lib/config.py          |  5 +----
 lib/errors.py          | 12 +++++++++++-
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/daemons/ganeti-masterd b/daemons/ganeti-masterd
index 6c9471eae..7a86d4614 100755
--- a/daemons/ganeti-masterd
+++ b/daemons/ganeti-masterd
@@ -499,6 +499,28 @@ def CheckMasterd(options, args):
                           (constants.MASTERD_USER, constants.DAEMONS_GROUP))
     sys.exit(constants.EXIT_FAILURE)
 
+  # Check the configuration is sane before anything else
+  try:
+    config.ConfigWriter()
+  except errors.ConfigVersionMismatch, err:
+    v1 = "%s.%s.%s" % constants.SplitVersion(err.args[0])
+    v2 = "%s.%s.%s" % constants.SplitVersion(err.args[1])
+    print >> sys.stderr,  \
+        ("Configuration version mismatch. The current Ganeti software"
+         " expects version %s, but the on-disk configuration file has"
+         " version %s. This is likely the result of upgrading the"
+         " software without running the upgrade procedure. Please contact"
+         " your cluster administrator or complete the upgrade using the"
+         " cfgupgrade utility, after reading the upgrade notes." %
+         (v1, v2))
+    sys.exit(constants.EXIT_FAILURE)
+  except errors.ConfigurationError, err:
+    print >> sys.stderr, \
+        ("Configuration error while opening the configuration file: %s\n"
+         "This might be caused by an incomplete software upgrade or"
+         " by a corrupted configuration file. Until the problem is fixed"
+         " the master daemon cannot start." % str(err))
+    sys.exit(constants.EXIT_FAILURE)
 
   # If CheckMaster didn't fail we believe we are the master, but we have to
   # confirm with the other nodes.
diff --git a/lib/config.py b/lib/config.py
index e81e563ad..9817f1ad3 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -67,10 +67,7 @@ def _ValidateConfig(data):
 
   """
   if data.version != constants.CONFIG_VERSION:
-    raise errors.ConfigurationError("Cluster configuration version"
-                                    " mismatch, got %s instead of %s" %
-                                    (data.version,
-                                     constants.CONFIG_VERSION))
+    raise errors.ConfigVersionMismatch(constants.CONFIG_VERSION, data.version)
 
 
 class TemporaryReservationManager:
diff --git a/lib/errors.py b/lib/errors.py
index e089835a5..ee660c2ad 100644
--- a/lib/errors.py
+++ b/lib/errors.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -110,6 +110,16 @@ class ConfigurationError(GenericError):
   pass
 
 
+class ConfigVersionMismatch(ConfigurationError):
+  """Version mismatch in the configuration file.
+
+  The error has two arguments: the expected and the actual found
+  version.
+
+  """
+  pass
+
+
 class ReservationError(GenericError):
   """Errors reserving a resource.
 
-- 
GitLab