diff options
Diffstat (limited to 'nova/utils.py')
-rw-r--r-- | nova/utils.py | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/nova/utils.py b/nova/utils.py index ef8405fc0..011a5cb09 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -38,6 +38,16 @@ from nova import flags FLAGS = flags.FLAGS TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" +class ProcessExecutionError(IOError): + def __init__( self, stdout=None, stderr=None, exit_code=None, cmd=None, + description=None): + if description is None: + description = "Unexpected error while running command." + if exit_code is None: + exit_code = '-' + message = "%s\nCommand: %s\nExit code: %s\nStdout: %r\nStderr: %r" % ( + description, cmd, exit_code, stdout, stderr) + IOError.__init__(self, message) def import_class(import_str): """Returns a class from a string including module and class""" @@ -48,6 +58,14 @@ def import_class(import_str): except (ImportError, ValueError, AttributeError): raise exception.NotFound('Class %s cannot be found' % class_str) +def import_object(import_str): + """Returns an object including a module or module and class""" + try: + __import__(import_str) + return sys.modules[import_str] + except ImportError: + cls = import_class(import_str) + return cls() def fetchfile(url, target): logging.debug("Fetching %s" % url) @@ -61,6 +79,7 @@ def fetchfile(url, target): execute("curl --fail %s -o %s" % (url, target)) def execute(cmd, process_input=None, addl_env=None, check_exit_code=True): + logging.debug("Running cmd: %s", cmd) env = os.environ.copy() if addl_env: env.update(addl_env) @@ -75,8 +94,11 @@ def execute(cmd, process_input=None, addl_env=None, check_exit_code=True): if obj.returncode: logging.debug("Result was %s" % (obj.returncode)) if check_exit_code and obj.returncode <> 0: - raise Exception( "Unexpected exit code: %s. result=%s" - % (obj.returncode, result)) + (stdout, stderr) = result + raise ProcessExecutionError(exit_code=obj.returncode, + stdout=stdout, + stderr=stderr, + cmd=cmd) return result @@ -107,7 +129,7 @@ def runthis(prompt, cmd, check_exit_code = True): exit_code = subprocess.call(cmd.split(" ")) logging.debug(prompt % (exit_code)) if check_exit_code and exit_code <> 0: - raise Exception( "Unexpected exit code: %s from cmd: %s" + raise Exception( "Unexpected exit code: %s from cmd: %s" % (exit_code, cmd)) @@ -127,8 +149,7 @@ def last_octet(address): def get_my_ip(): - ''' returns the actual ip of the local machine. - ''' + """Returns the actual ip of the local machine.""" if getattr(FLAGS, 'fake_tests', None): return '127.0.0.1' try: @@ -152,6 +173,36 @@ def parse_isotime(timestr): return datetime.datetime.strptime(timestr, TIME_FORMAT) +class LazyPluggable(object): + """A pluggable backend loaded lazily based on some value.""" + + def __init__(self, pivot, **backends): + self.__backends = backends + self.__pivot = pivot + self.__backend = None + + def __get_backend(self): + if not self.__backend: + backend_name = self.__pivot.value + if backend_name not in self.__backends: + raise exception.Error('Invalid backend: %s' % backend_name) + + backend = self.__backends[backend_name] + if type(backend) == type(tuple()): + name = backend[0] + fromlist = backend[1] + else: + name = backend + fromlist = backend + + self.__backend = __import__(name, None, None, fromlist) + logging.info('backend %s', self.__backend) + return self.__backend + + def __getattr__(self, key): + backend = self.__get_backend() + return getattr(backend, key) + def deferredToThread(f): def g(*args, **kwargs): return deferToThread(f, *args, **kwargs) |