Add support for classic queries
[ganeti-local] / lib / errors.py
index f03d659..ca3050f 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 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
@@ -43,30 +43,38 @@ ECODE_FAULT = "internal_error"
 # environment error (e.g. node disk error)
 ECODE_ENVIRON = "environment_error"
 
+#: List of all failure types
+ECODE_ALL = frozenset([
+  ECODE_RESOLVER,
+  ECODE_NORES,
+  ECODE_INVAL,
+  ECODE_STATE,
+  ECODE_NOENT,
+  ECODE_EXISTS,
+  ECODE_NOTUNIQUE,
+  ECODE_FAULT,
+  ECODE_ENVIRON,
+  ])
+
 
 class GenericError(Exception):
   """Base exception for Ganeti.
 
   """
-  pass
 
 
-class LVMError(GenericError):
-  """LVM-related exception.
+class LockError(GenericError):
+  """Lock error exception.
 
-  This exception codifies problems with LVM setup.
+  This signifies problems in the locking subsystem.
 
   """
-  pass
 
 
-class LockError(GenericError):
-  """Lock error exception.
-
-  This signifies problems in the locking subsystem.
+class PidFileLockError(LockError):
+  """PID file is already locked by another process.
 
   """
-  pass
 
 
 class HypervisorError(GenericError):
@@ -76,7 +84,6 @@ class HypervisorError(GenericError):
   properly.
 
   """
-  pass
 
 
 class ProgrammerError(GenericError):
@@ -87,7 +94,6 @@ class ProgrammerError(GenericError):
   parts of our code. It signifies a real programming bug.
 
   """
-  pass
 
 
 class BlockDeviceError(GenericError):
@@ -97,7 +103,6 @@ class BlockDeviceError(GenericError):
   properly.
 
   """
-  pass
 
 
 class ConfigurationError(GenericError):
@@ -107,7 +112,15 @@ class ConfigurationError(GenericError):
   exist in the config or such raise this exception.
 
   """
-  pass
+
+
+class ConfigVersionMismatch(ConfigurationError):
+  """Version mismatch in the configuration file.
+
+  The error has two arguments: the expected and the actual found
+  version.
+
+  """
 
 
 class ReservationError(GenericError):
@@ -123,7 +136,6 @@ class RemoteError(GenericError):
   remote node.  It usually signifies a real programming bug.
 
   """
-  pass
 
 
 class SignatureError(GenericError):
@@ -134,7 +146,6 @@ class SignatureError(GenericError):
   because of spurious traffic.
 
   """
-  pass
 
 
 class ParameterError(GenericError):
@@ -147,7 +158,12 @@ class ParameterError(GenericError):
   The argument to this exception should be the parameter name.
 
   """
-  pass
+
+
+class ResultValidationError(GenericError):
+  """The iallocation results fails validation.
+
+  """
 
 
 class OpPrereqError(GenericError):
@@ -166,6 +182,12 @@ class OpExecError(GenericError):
   """
 
 
+class OpResultError(GenericError):
+  """Issue with OpCode result.
+
+  """
+
+
 class OpCodeUnknown(GenericError):
   """Unknown opcode submitted.
 
@@ -242,8 +264,10 @@ class TypeEnforcementError(GenericError):
   """
 
 
-class SshKeyError(GenericError):
-  """Invalid SSH key.
+class X509CertError(GenericError):
+  """Invalid X509 certificate.
+
+  This error has two arguments: the certificate filename and the error cause.
 
   """
 
@@ -275,7 +299,7 @@ class InotifyError(GenericError):
 
 
 class QuitGanetiException(Exception):
-  """Signal that Ganeti that it must quit.
+  """Signal Ganeti that it must quit.
 
   This is not necessarily an error (and thus not a subclass of
   GenericError), but it's an exceptional circumstance and it is thus
@@ -319,15 +343,6 @@ class JobQueueFull(JobQueueError):
   """
 
 
-class ConfdRequestError(GenericError):
-  """A request error in Ganeti confd.
-
-  Events that should make confd abort the current request and proceed serving
-  different ones.
-
-  """
-
-
 class ConfdMagicError(GenericError):
   """A magic fourcc error in Ganeti confd.
 
@@ -356,6 +371,48 @@ class NoCtypesError(GenericError):
   """
 
 
+class IPAddressError(GenericError):
+  """Generic IP address error.
+
+  """
+
+
+class LuxiError(GenericError):
+  """LUXI error.
+
+  """
+
+
+class QueryFilterParseError(ParseError):
+  """Error while parsing query filter.
+
+  """
+  def GetDetails(self):
+    """Returns a list of strings with details about the error.
+
+    """
+    try:
+      (_, inner) = self.args
+    except IndexError:
+      return None
+
+    return [str(inner.line),
+            (" " * (inner.column - 1)) + "^",
+            str(inner)]
+
+
+class RapiTestResult(GenericError):
+  """Exception containing results from RAPI test utilities.
+
+  """
+
+
+class FileStoragePathError(GenericError):
+  """Error from file storage path validation.
+
+  """
+
+
 # errors should be added above
 
 
@@ -394,17 +451,34 @@ def EncodeException(err):
   return (err.__class__.__name__, err.args)
 
 
-def MaybeRaise(result):
-  """If this looks like an encoded Ganeti exception, raise it.
+def GetEncodedError(result):
+  """If this looks like an encoded Ganeti exception, return it.
 
   This function tries to parse the passed argument and if it looks
-  like an encoding done by EncodeException, it will re-raise it.
+  like an encoding done by EncodeException, it will return the class
+  object and arguments.
 
   """
   tlt = (tuple, list)
   if (isinstance(result, tlt) and len(result) == 2 and
       isinstance(result[1], tlt)):
     # custom ganeti errors
-    err_class = GetErrorClass(result[0])
-    if err_class is not None:
-      raise err_class, tuple(result[1])
+    errcls = GetErrorClass(result[0])
+    if errcls:
+      return (errcls, tuple(result[1]))
+
+  return None
+
+
+def MaybeRaise(result):
+  """If this looks like an encoded Ganeti exception, raise it.
+
+  This function tries to parse the passed argument and if it looks
+  like an encoding done by EncodeException, it will re-raise it.
+
+  """
+  error = GetEncodedError(result)
+  if error:
+    (errcls, args) = error
+    # pylint: disable=W0142
+    raise errcls(*args)