From b33e986b29a05988b92cf48a8da99b9601c5671d Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 30 Jul 2008 15:06:01 +0000
Subject: [PATCH] Make gnt-* commands fail nicely on non-masters

This patch adds a check that we are on the master after failing to
connect to the socket, and log nicely the master name.

Reviewed-by: ultrotter
---
 lib/cli.py    | 15 +++++++++++++--
 lib/ssconf.py | 24 +++++++++++++++++-------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/lib/cli.py b/lib/cli.py
index 38c93120f..af05684f7 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -35,6 +35,7 @@ from ganeti import errors
 from ganeti import constants
 from ganeti import opcodes
 from ganeti import luxi
+from ganeti import ssconf
 
 from optparse import (OptionParser, make_option, TitledHelpFormatter,
                       Option, OptionValueError)
@@ -377,7 +378,7 @@ def SubmitOpCode(op, cl=None, feedback_fn=None):
 
   """
   if cl is None:
-    cl = luxi.Client()
+    cl = GetClient()
 
   job_id = cl.SubmitJob([op])
 
@@ -414,7 +415,17 @@ def SubmitOpCode(op, cl=None, feedback_fn=None):
 
 def GetClient():
   # TODO: Cache object?
-  return luxi.Client()
+  try:
+    client = luxi.Client()
+  except luxi.NoMasterError:
+    master, myself = ssconf.GetMasterAndMyself()
+    if master != myself:
+      raise errors.OpPrereqError("This is not the master node, please connect"
+                                 " to node '%s' and rerun the command" %
+                                 master)
+    else:
+      raise
+  return client
 
 
 def FormatError(err):
diff --git a/lib/ssconf.py b/lib/ssconf.py
index a18a55648..fbe2fb15a 100644
--- a/lib/ssconf.py
+++ b/lib/ssconf.py
@@ -201,7 +201,21 @@ class WritableSimpleStore(SimpleStore):
                     uid=0, gid=0, mode=0400)
 
 
-def CheckMaster(debug):
+def GetMasterAndMyself(ss=None):
+  """Get the master node and my own hostname.
+
+  This can be either used for a 'soft' check (compared to CheckMaster,
+  which exits) or just for computing both at the same time.
+
+  The function does not handle any errors, these should be handled in
+  the caller (errors.ConfigurationError, errors.ResolverError).
+
+  """
+  if ss is None:
+    ss = SimpleStore()
+  return ss.GetMasterNode(), utils.HostInfo().name
+
+def CheckMaster(debug, ss=None):
   """Checks the node setup.
 
   If this is the master, the function will return. Otherwise it will
@@ -209,19 +223,15 @@ def CheckMaster(debug):
 
   """
   try:
-    ss = SimpleStore()
-    master_name = ss.GetMasterNode()
+    master_name, myself = GetMasterAndMyself(ss)
   except errors.ConfigurationError, err:
     print "Cluster configuration incomplete: '%s'" % str(err)
     sys.exit(constants.EXIT_NODESETUP_ERROR)
-
-  try:
-    myself = utils.HostInfo()
   except errors.ResolverError, err:
     sys.stderr.write("Cannot resolve my own name (%s)\n" % err.args[0])
     sys.exit(constants.EXIT_NODESETUP_ERROR)
 
-  if myself.name != master_name:
+  if myself != master_name:
     if debug:
       sys.stderr.write("Not master, exiting.\n")
     sys.exit(constants.EXIT_NOTMASTER)
-- 
GitLab