From 03a8dbdc0c84f0914f11e80c3570d3a8b00c6a58 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sat, 21 Jun 2008 18:49:14 +0000
Subject: [PATCH] Implement handling of luxi errors in cli.py

Currently the generic handling of ganeti errors in cli.py (GenericMain
and FormatError) only handles the core ganeti errors, and not the client
protocol errors (which live in a separate hierarchy).

This patch adds handling of luxi errors too, and also adds another luxi
error for the case when the master is not running. This gives us a nice:

  gnta1:~# gnt-node list
  Cannot communicate with the master daemon.
  Is it running and listening on '/var/run/ganeti-master.sock'?

error message instead of a traceback.

Reviewed-by: amishchenko
---
 lib/cli.py  | 11 ++++++++++-
 lib/luxi.py | 17 +++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/lib/cli.py b/lib/cli.py
index 917b3458c..167f28cb8 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -466,6 +466,15 @@ def FormatError(err):
     obuf.write("Failure: invalid tag(s) given:\n%s" % msg)
   elif isinstance(err, errors.GenericError):
     obuf.write("Unhandled Ganeti error: %s" % msg)
+  elif isinstance(err, luxi.NoMasterError):
+    obuf.write("Cannot communicate with the master daemon.\nIs it running"
+               " and listening on '%s'?" % err.args[0])
+  elif isinstance(err, luxi.TimeoutError):
+    obuf.write("Timeout while talking to the master daemon. Error:\n"
+               "%s" % msg)
+  elif isinstance(err, luxi.ProtocolError):
+    obuf.write("Unhandled protocol error while talking to the master daemon:\n"
+               "%s" % msg)
   else:
     obuf.write("Unhandled exception: %s" % msg)
   return retcode, obuf.getvalue().rstrip('\n')
@@ -517,7 +526,7 @@ def GenericMain(commands, override=None, aliases=None):
 
   try:
     result = func(options, args)
-  except errors.GenericError, err:
+  except (errors.GenericError, luxi.ProtocolError), err:
     result, err_msg = FormatError(err)
     logger.ToStderr(err_msg)
 
diff --git a/lib/luxi.py b/lib/luxi.py
index df9ed89a3..993907d49 100644
--- a/lib/luxi.py
+++ b/lib/luxi.py
@@ -33,6 +33,7 @@ import socket
 import collections
 import simplejson
 import time
+import errno
 
 from ganeti import opcodes
 from ganeti import constants
@@ -80,6 +81,14 @@ class RequestError(ProtocolError):
 
   """
 
+class NoMasterError(ProtocolError):
+  """The master cannot be reached
+
+  This means that the master daemon is not running or the socket has
+  been removed.
+
+  """
+
 
 def SerializeJob(job):
   """Convert a job description to a string format.
@@ -153,9 +162,13 @@ class Transport:
       try:
         self.socket.connect(address)
       except socket.timeout, err:
-        raise TimeoutError("Connection timed out: %s" % str(err))
+        raise TimeoutError("Connect timed out: %s" % str(err))
+      except socket.error, err:
+        if err.args[0] == errno.ENOENT:
+          raise NoMasterError((address,))
+        raise
       self.socket.settimeout(self._rwtimeout)
-    except socket.error:
+    except (socket.error, NoMasterError):
       if self.socket is not None:
         self.socket.close()
       self.socket = None
-- 
GitLab