From 1a11790f2d26ec92858a3ffa100388310912fae1 Mon Sep 17 00:00:00 2001 From: Michael Still Date: Fri, 3 May 2013 10:47:39 +1000 Subject: [PATCH] Convert to using oslo's execute() method. There are some small warts (mostly around other execute() like methods which reuse the exception). I will fix these warts in later reviews. Change-Id: Ice9cdbdc5f3e5a9f8365f5d99acf1863a9fe3e7a --- nova/cmd/baremetal_deploy_helper.py | 4 +- nova/console/xvp.py | 6 +- nova/crypto.py | 7 +- nova/exception.py | 19 --- nova/image/s3.py | 3 +- nova/network/floating_ips.py | 5 +- nova/network/linux_net.py | 7 +- nova/openstack/common/processutils.py | 6 + nova/storage/linuxscsi.py | 4 +- .../baremetal/test_virtual_power_driver.py | 7 +- nova/tests/fake_utils.py | 4 +- nova/tests/network/test_manager.py | 3 +- nova/tests/test_crypto.py | 3 +- nova/tests/test_powervm.py | 4 +- nova/tests/test_utils.py | 86 +----------- nova/utils.py | 123 ++---------------- nova/virt/baremetal/tilera_pdu.py | 5 +- nova/virt/baremetal/virtual_power_driver.py | 3 +- nova/virt/baremetal/volume_driver.py | 7 +- nova/virt/disk/api.py | 3 +- nova/virt/hyperv/vmops.py | 3 +- nova/virt/libvirt/driver.py | 5 +- nova/virt/libvirt/utils.py | 6 +- nova/virt/libvirt/vif.py | 5 +- nova/virt/libvirt/volume.py | 13 +- nova/virt/powervm/common.py | 15 ++- nova/virt/powervm/operator.py | 4 +- nova/virt/xenapi/vm_utils.py | 5 +- 28 files changed, 97 insertions(+), 268 deletions(-) diff --git a/nova/cmd/baremetal_deploy_helper.py b/nova/cmd/baremetal_deploy_helper.py index 365451b6b6ea..dd8c652ffe78 100644 --- a/nova/cmd/baremetal_deploy_helper.py +++ b/nova/cmd/baremetal_deploy_helper.py @@ -32,8 +32,8 @@ from wsgiref import simple_server from nova import config from nova import context as nova_context -from nova import exception from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.baremetal import baremetal_states from nova.virt.baremetal import db @@ -201,7 +201,7 @@ def deploy(address, port, iqn, lun, image_path, pxe_config_path, login_iscsi(address, port, iqn) try: root_uuid = work_on_disk(dev, root_mb, swap_mb, image_path) - except exception.ProcessExecutionError, err: + except processutils.ProcessExecutionError, err: # Log output if there was a error LOG.error("Cmd : %s" % err.cmd) LOG.error("StdOut : %s" % err.stdout) diff --git a/nova/console/xvp.py b/nova/console/xvp.py index 1e9fbcb5dbdd..be3a41c1dc2d 100644 --- a/nova/console/xvp.py +++ b/nova/console/xvp.py @@ -25,9 +25,9 @@ from oslo.config import cfg from nova import context from nova import db -from nova import exception from nova.openstack.common import excutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import paths from nova import utils @@ -143,7 +143,7 @@ class XVPConsoleProxy(object): '-p', CONF.console_xvp_pid, '-c', CONF.console_xvp_conf, '-l', CONF.console_xvp_log) - except exception.ProcessExecutionError, err: + except processutils.ProcessExecutionError, err: LOG.error(_('Error starting xvp: %s') % err) def _xvp_restart(self): @@ -200,5 +200,5 @@ class XVPConsoleProxy(object): password = password[:maxlen] out, err = utils.execute('xvp', flag, process_input=password) if err: - raise exception.ProcessExecutionError(_("Failed to run xvp.")) + raise processutils.ProcessExecutionError(_("Failed to run xvp.")) return out.strip() diff --git a/nova/crypto.py b/nova/crypto.py index 736e999617c0..aaf102d8a5a7 100644 --- a/nova/crypto.py +++ b/nova/crypto.py @@ -41,6 +41,7 @@ from nova import exception from nova.openstack.common import excutils from nova.openstack.common import fileutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova.openstack.common import timeutils from nova import paths from nova import utils @@ -138,7 +139,7 @@ def generate_fingerprint(public_key): with open(pubfile, 'w') as f: f.write(public_key) return _generate_fingerprint(pubfile) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: raise exception.InvalidKeypair() @@ -184,7 +185,7 @@ def decrypt_text(project_id, text): '-inkey', '%s' % private_key, process_input=text) return dec - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: raise exception.DecryptionFailure(reason=exc.stderr) @@ -267,7 +268,7 @@ def ssh_encrypt_text(ssh_public_key, text): '-keyform', 'PEM', process_input=text) return enc - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: raise exception.EncryptionFailure(reason=exc.stderr) diff --git a/nova/exception.py b/nova/exception.py index c81362dcf898..a9afe37a7eeb 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -53,25 +53,6 @@ class ConvertedException(webob.exc.WSGIHTTPException): super(ConvertedException, self).__init__() -class ProcessExecutionError(IOError): - def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, - description=None): - self.exit_code = exit_code - self.stderr = stderr - self.stdout = stdout - self.cmd = cmd - self.description = description - - if description is None: - description = _('Unexpected error while running command.') - if exit_code is None: - exit_code = '-' - message = _('%(description)s\nCommand: %(cmd)s\n' - 'Exit code: %(exit_code)s\nStdout: %(stdout)r\n' - 'Stderr: %(stderr)r') % locals() - IOError.__init__(self, message) - - def _cleanse_dict(original): """Strip all admin_password, new_pass, rescue_pass keys from a dict.""" return dict((k, v) for k, v in original.iteritems() if not "_pass" in k) diff --git a/nova/image/s3.py b/nova/image/s3.py index 563864b91610..f08cbcdcbd19 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -35,6 +35,7 @@ import nova.cert.rpcapi from nova import exception from nova.image import glance from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils @@ -409,7 +410,7 @@ class S3ImageService(object): '-K', '%s' % (key,), '-iv', '%s' % (iv,), '-out', '%s' % (decrypted_filename,)) - except exception.ProcessExecutionError, exc: + except processutils.ProcessExecutionError, exc: raise exception.NovaException(_('Failed to decrypt image file ' '%(image_file)s: %(err)s') % {'image_file': encrypted_filename, diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py index bc8c05d2610d..8ba1533587c5 100644 --- a/nova/network/floating_ips.py +++ b/nova/network/floating_ips.py @@ -28,6 +28,7 @@ from nova.openstack.common import importutils from nova.openstack.common import lockutils from nova.openstack.common import log as logging from nova.openstack.common.notifier import api as notifier +from nova.openstack.common import processutils from nova.openstack.common.rpc import common as rpc_common from nova.openstack.common import uuidutils from nova import quota @@ -93,7 +94,7 @@ class FloatingIP(object): fixed_ip['address'], interface, fixed_ip['network']) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.debug(_('Interface %(interface)s not found'), locals()) raise exception.NoFloatingIpInterface(interface=interface) @@ -367,7 +368,7 @@ class FloatingIP(object): # gogo driver time self.l3driver.add_floating_ip(floating_address, fixed_address, interface, fixed['network']) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: self.db.floating_ip_disassociate(context, floating_address) if "Cannot find device" in str(e): LOG.error(_('Interface %(interface)s not found'), locals()) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index fad51dbe13bc..7a1f562e5662 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -35,6 +35,7 @@ from nova.openstack.common import importutils from nova.openstack.common import jsonutils from nova.openstack.common import lockutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova.openstack.common import timeutils from nova import paths from nova import utils @@ -771,7 +772,7 @@ def clean_conntrack(fixed_ip): try: _execute('conntrack', '-D', '-r', fixed_ip, run_as_root=True, check_exit_code=[0, 1]) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_('Error deleting conntrack entries for %s'), fixed_ip) @@ -1260,7 +1261,7 @@ def create_tap_dev(dev, mac_address=None): # First, try with 'ip' utils.execute('ip', 'tuntap', 'add', dev, 'mode', 'tap', run_as_root=True, check_exit_code=[0, 2, 254]) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: # Second option: tunctl utils.execute('tunctl', '-b', '-t', dev, run_as_root=True) if mac_address: @@ -1277,7 +1278,7 @@ def delete_net_dev(dev): utils.execute('ip', 'link', 'delete', dev, run_as_root=True, check_exit_code=[0, 2, 254]) LOG.debug(_("Net device removed: '%s'"), dev) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.error(_("Failed removing net device: '%s'"), dev) diff --git a/nova/openstack/common/processutils.py b/nova/openstack/common/processutils.py index fbd2c6ff21c9..45a5bf963c3f 100644 --- a/nova/openstack/common/processutils.py +++ b/nova/openstack/common/processutils.py @@ -42,6 +42,12 @@ class UnknownArgumentError(Exception): class ProcessExecutionError(Exception): def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, description=None): + self.exit_code = exit_code + self.stderr = stderr + self.stdout = stdout + self.cmd = cmd + self.description = description + if description is None: description = "Unexpected error while running command." if exit_code is None: diff --git a/nova/storage/linuxscsi.py b/nova/storage/linuxscsi.py index fb093b08a199..66cb9c0eab4d 100644 --- a/nova/storage/linuxscsi.py +++ b/nova/storage/linuxscsi.py @@ -16,9 +16,9 @@ """Generic linux scsi subsystem utilities.""" -from nova import exception from nova.openstack.common import log as logging from nova.openstack.common import loopingcall +from nova.openstack.common import processutils from nova import utils LOG = logging.getLogger(__name__) @@ -97,7 +97,7 @@ def find_multipath_device(device): try: (out, err) = utils.execute('multipath', '-l', device, run_as_root=True) - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: LOG.warn(_("Multipath call failed exit (%(code)s)") % {'code': exc.exit_code}) return None diff --git a/nova/tests/baremetal/test_virtual_power_driver.py b/nova/tests/baremetal/test_virtual_power_driver.py index b98ef51824c0..4cac0a3ba011 100644 --- a/nova/tests/baremetal/test_virtual_power_driver.py +++ b/nova/tests/baremetal/test_virtual_power_driver.py @@ -22,6 +22,7 @@ import mox from oslo.config import cfg from nova import exception +from nova.openstack.common import processutils from nova.tests.baremetal.db import base as bm_db_base from nova.tests.baremetal.db import utils as bm_db_utils from nova.tests.image import fake as fake_image @@ -371,7 +372,7 @@ class VPDClassMethodsTestCase(BareMetalVPDTestCase): self.pm._set_connection().AndReturn(True) nutils.ssh_execute(None, '/usr/bin/VBoxManage test return', check_exit_code=True).\ - AndRaise(exception.ProcessExecutionError) + AndRaise(processutils.ProcessExecutionError) self.mox.ReplayAll() result = self.pm._run_command("test return") @@ -389,10 +390,10 @@ class VPDClassMethodsTestCase(BareMetalVPDTestCase): self.pm._check_for_node().AndReturn(['"testNode"']) nutils.ssh_execute('test', '/usr/bin/VBoxManage startvm ', check_exit_code=True).\ - AndRaise(exception.ProcessExecutionError) + AndRaise(processutils.ProcessExecutionError) nutils.ssh_execute('test', '/usr/bin/VBoxManage list runningvms', check_exit_code=True).\ - AndRaise(exception.ProcessExecutionError) + AndRaise(processutils.ProcessExecutionError) self.mox.ReplayAll() self.pm._connection = 'test' diff --git a/nova/tests/fake_utils.py b/nova/tests/fake_utils.py index 08a84e73ffcc..6a295b43b246 100644 --- a/nova/tests/fake_utils.py +++ b/nova/tests/fake_utils.py @@ -20,8 +20,8 @@ import re from eventlet import greenthread -from nova import exception from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils LOG = logging.getLogger(__name__) @@ -92,7 +92,7 @@ def fake_execute(*cmd_parts, **kwargs): attempts=attempts, run_as_root=run_as_root, check_exit_code=check_exit_code) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: LOG.debug(_('Faked command raised an exception %s'), e) raise diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index def993f62daf..b8d7115a9115 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -32,6 +32,7 @@ from nova.network import model as net_model from nova.openstack.common.db import exception as db_exc from nova.openstack.common import importutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova.openstack.common import rpc from nova.openstack.common.rpc import common as rpc_common from nova import quota @@ -763,7 +764,7 @@ class VlanNetworkTestCase(test.TestCase): self.local = True def fake8(*args, **kwargs): - raise exception.ProcessExecutionError('', + raise processutils.ProcessExecutionError('', 'Cannot find device "em0"\n') def fake9(*args, **kwargs): diff --git a/nova/tests/test_crypto.py b/nova/tests/test_crypto.py index e328babfef38..2264273d70cc 100644 --- a/nova/tests/test_crypto.py +++ b/nova/tests/test_crypto.py @@ -23,6 +23,7 @@ import mox from nova import crypto from nova import db from nova import exception +from nova.openstack.common import processutils from nova import test from nova import utils @@ -200,7 +201,7 @@ e6fCXWECgYEAqgpGvva5kJ1ISgNwnJbwiNw0sOT9BMOsdNZBElf0kJIIy6FMPvap '-inkey', sshkey, process_input=text) return dec - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: raise exception.DecryptionFailure(reason=exc.stderr) def test_ssh_encrypt_decrypt_text(self): diff --git a/nova/tests/test_powervm.py b/nova/tests/test_powervm.py index 96954269ef7d..73299f23ade4 100644 --- a/nova/tests/test_powervm.py +++ b/nova/tests/test_powervm.py @@ -22,13 +22,13 @@ import contextlib from nova import context from nova import db -from nova import exception as nova_exception from nova import test from nova.compute import instance_types from nova.compute import power_state from nova.compute import task_states from nova.network import model as network_model +from nova.openstack.common import processutils from nova.tests import fake_network_cache_model from nova.tests.image import fake from nova.virt import images @@ -227,7 +227,7 @@ class PowerVMDriverTestCase(test.TestCase): self.powervm_connection._powervm, 'get_host_stats', lambda *x, **y: raise_( - (nova_exception.ProcessExecutionError('instance_name')))) + (processutils.ProcessExecutionError('instance_name')))) fake_net_info = network_model.NetworkInfo([ fake_network_cache_model.new_vif()]) self.assertRaises(exception.PowerVMLPARCreationFailed, diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index af6a9b9aa01e..6b7af48fcaa3 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -30,6 +30,7 @@ from oslo.config import cfg import nova from nova import exception +from nova.openstack.common import processutils from nova.openstack.common import timeutils from nova import test from nova import utils @@ -72,89 +73,6 @@ class ByteConversionTest(test.TestCase): self.assertRaises(TypeError, utils.to_bytes, v) -class ExecuteTestCase(test.TestCase): - - def test_retry_on_failure(self): - fd, tmpfilename = tempfile.mkstemp() - _, tmpfilename2 = tempfile.mkstemp() - try: - fp = os.fdopen(fd, 'w+') - fp.write('''#!/bin/sh -# If stdin fails to get passed during one of the runs, make a note. -if ! grep -q foo -then - echo 'failure' > "$1" -fi -# If stdin has failed to get passed during this or a previous run, exit early. -if grep failure "$1" -then - exit 1 -fi -runs="$(cat $1)" -if [ -z "$runs" ] -then - runs=0 -fi -runs=$(($runs + 1)) -echo $runs > "$1" -exit 1 -''') - fp.close() - os.chmod(tmpfilename, 0755) - self.assertRaises(exception.ProcessExecutionError, - utils.execute, - tmpfilename, tmpfilename2, attempts=10, - process_input='foo', - delay_on_retry=False) - fp = open(tmpfilename2, 'r') - runs = fp.read() - fp.close() - self.assertNotEquals(runs.strip(), 'failure', 'stdin did not ' - 'always get passed ' - 'correctly') - runs = int(runs.strip()) - self.assertEquals(runs, 10, - 'Ran %d times instead of 10.' % (runs,)) - finally: - os.unlink(tmpfilename) - os.unlink(tmpfilename2) - - def test_unknown_kwargs_raises_error(self): - self.assertRaises(exception.NovaException, - utils.execute, - '/usr/bin/env', 'true', - this_is_not_a_valid_kwarg=True) - - def test_check_exit_code_boolean(self): - utils.execute('/usr/bin/env', 'false', check_exit_code=False) - self.assertRaises(exception.ProcessExecutionError, - utils.execute, - '/usr/bin/env', 'false', check_exit_code=True) - - def test_no_retry_on_success(self): - fd, tmpfilename = tempfile.mkstemp() - _, tmpfilename2 = tempfile.mkstemp() - try: - fp = os.fdopen(fd, 'w+') - fp.write('''#!/bin/sh -# If we've already run, bail out. -grep -q foo "$1" && exit 1 -# Mark that we've run before. -echo foo > "$1" -# Check that stdin gets passed correctly. -grep foo -''') - fp.close() - os.chmod(tmpfilename, 0755) - utils.execute(tmpfilename, - tmpfilename2, - process_input='foo', - attempts=2) - finally: - os.unlink(tmpfilename) - os.unlink(tmpfilename2) - - class GetFromPathTestCase(test.TestCase): def test_tolerates_nones(self): f = utils.get_from_path @@ -429,7 +347,7 @@ class GenericUtilsTestCase(test.TestCase): def test_read_file_as_root(self): def fake_execute(*args, **kwargs): if args[1] == 'bad': - raise exception.ProcessExecutionError + raise processutils.ProcessExecutionError return 'fakecontents', None self.stubs.Set(utils, 'execute', fake_execute) diff --git a/nova/utils.py b/nova/utils.py index bb002b9e7ba5..64606f4f8138 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -30,7 +30,6 @@ import pyclbr import random import re import shutil -import signal import socket import struct import sys @@ -38,8 +37,6 @@ import tempfile import time from xml.sax import saxutils -from eventlet.green import subprocess -from eventlet import greenthread import netaddr from oslo.config import cfg @@ -48,6 +45,7 @@ from nova import exception from nova.openstack.common import excutils from nova.openstack.common import importutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova.openstack.common.rpc import common as rpc_common from nova.openstack.common import timeutils @@ -149,107 +147,11 @@ def vpn_ping(address, port, timeout=0.05, session_id=None): return server_sess -def _subprocess_setup(): - # Python installs a SIGPIPE handler by default. This is usually not what - # non-Python subprocesses expect. - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - - def execute(*cmd, **kwargs): - """Helper method to execute command with optional retry. - - If you add a run_as_root=True command, don't forget to add the - corresponding filter to etc/nova/rootwrap.d ! - - :param cmd: Passed to subprocess.Popen. - :param process_input: Send to opened process. - :param check_exit_code: Single bool, int, or list of allowed exit - codes. Defaults to [0]. Raise - exception.ProcessExecutionError unless - program exits with one of these code. - :param delay_on_retry: True | False. Defaults to True. If set to - True, wait a short amount of time - before retrying. - :param attempts: How many times to retry cmd. - :param run_as_root: True | False. Defaults to False. If set to True, - the command is run with rootwrap. - - :raises exception.NovaException: on receiving unknown arguments - :raises exception.ProcessExecutionError: - - :returns: a tuple, (stdout, stderr) from the spawned process, or None if - the command fails. - """ - process_input = kwargs.pop('process_input', None) - check_exit_code = kwargs.pop('check_exit_code', [0]) - ignore_exit_code = False - if isinstance(check_exit_code, bool): - ignore_exit_code = not check_exit_code - check_exit_code = [0] - elif isinstance(check_exit_code, int): - check_exit_code = [check_exit_code] - delay_on_retry = kwargs.pop('delay_on_retry', True) - attempts = kwargs.pop('attempts', 1) - run_as_root = kwargs.pop('run_as_root', False) - shell = kwargs.pop('shell', False) - - if len(kwargs): - raise exception.NovaException(_('Got unknown keyword args ' - 'to utils.execute: %r') % kwargs) - - if run_as_root and os.geteuid() != 0: - cmd = ['sudo', 'nova-rootwrap', CONF.rootwrap_config] + list(cmd) - - cmd = map(str, cmd) - - while attempts > 0: - attempts -= 1 - try: - LOG.debug(_('Running cmd (subprocess): %s'), ' '.join(cmd)) - _PIPE = subprocess.PIPE # pylint: disable=E1101 - - if os.name == 'nt': - preexec_fn = None - close_fds = False - else: - preexec_fn = _subprocess_setup - close_fds = True - - obj = subprocess.Popen(cmd, - stdin=_PIPE, - stdout=_PIPE, - stderr=_PIPE, - close_fds=close_fds, - preexec_fn=preexec_fn, - shell=shell) - result = None - if process_input is not None: - result = obj.communicate(process_input) - else: - result = obj.communicate() - obj.stdin.close() # pylint: disable=E1101 - _returncode = obj.returncode # pylint: disable=E1101 - LOG.debug(_('Result was %s') % _returncode) - if not ignore_exit_code and _returncode not in check_exit_code: - (stdout, stderr) = result - raise exception.ProcessExecutionError( - exit_code=_returncode, - stdout=stdout, - stderr=stderr, - cmd=' '.join(cmd)) - return result - except exception.ProcessExecutionError: - if not attempts: - raise - else: - LOG.debug(_('%r failed. Retrying.'), cmd) - if delay_on_retry: - greenthread.sleep(random.randint(20, 200) / 100.0) - finally: - # NOTE(termie): this appears to be necessary to let the subprocess - # call clean something up in between calls, without - # it two execute calls in a row hangs the second one - greenthread.sleep(0) + """Convenience wrapper around oslo's execute() method.""" + if 'run_as_root' in kwargs and not 'root_helper' in kwargs: + kwargs['root_helper'] = 'sudo nova-rootwrap %s' % CONF.rootwrap_config + return processutils.execute(*cmd, **kwargs) def trycmd(*args, **kwargs): @@ -269,7 +171,7 @@ def trycmd(*args, **kwargs): try: out, err = execute(*args, **kwargs) failed = False - except exception.ProcessExecutionError, exn: + except processutils.ProcessExecutionError, exn: out, err = '', str(exn) failed = True @@ -309,10 +211,13 @@ def ssh_execute(ssh, cmd, process_input=None, if exit_status != -1: LOG.debug(_('Result was %s') % exit_status) if check_exit_code and exit_status != 0: - raise exception.ProcessExecutionError(exit_code=exit_status, - stdout=stdout, - stderr=stderr, - cmd=cmd) + # TODO(mikal): I know this is a bit odd, but its needed for + # consistency. I will move this method into processutils in a + # later change. + raise processutils.ProcessExecutionError(exit_code=exit_status, + stdout=stdout, + stderr=stderr, + cmd=cmd) return (stdout, stderr) @@ -1066,7 +971,7 @@ def read_file_as_root(file_path): try: out, _err = execute('cat', file_path, run_as_root=True) return out - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: raise exception.FileNotFound(file_path=file_path) diff --git a/nova/virt/baremetal/tilera_pdu.py b/nova/virt/baremetal/tilera_pdu.py index 86e6086aef28..0e491168fe99 100755 --- a/nova/virt/baremetal/tilera_pdu.py +++ b/nova/virt/baremetal/tilera_pdu.py @@ -26,6 +26,7 @@ from oslo.config import cfg from nova import exception from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.baremetal import baremetal_states from nova.virt.baremetal import base @@ -104,7 +105,7 @@ class Pdu(base.PowerManager): utils.execute('ping', '-c1', self.address, check_exit_code=True) return CONF.baremetal.tile_pdu_on - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: return CONF.baremetal.tile_pdu_off else: try: @@ -112,7 +113,7 @@ class Pdu(base.PowerManager): CONF.baremetal.tile_pdu_ip, mode) time.sleep(CONF.baremetal.tile_power_wait) return mode - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_("PDU failed")) def _is_power(self, state): diff --git a/nova/virt/baremetal/virtual_power_driver.py b/nova/virt/baremetal/virtual_power_driver.py index 2e659b8c3c18..22dd815d0c8a 100644 --- a/nova/virt/baremetal/virtual_power_driver.py +++ b/nova/virt/baremetal/virtual_power_driver.py @@ -23,6 +23,7 @@ from nova import context as nova_context from nova import exception from nova.openstack.common import importutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.baremetal import baremetal_states from nova.virt.baremetal import base @@ -233,7 +234,7 @@ class VirtualPowerManager(base.PowerManager): check_exit_code=check_exit_code) result = stdout.strip().splitlines() LOG.debug('Result for run_command: %s' % result) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: result = [] LOG.exception("Error running command: %s" % cmd) return result diff --git a/nova/virt/baremetal/volume_driver.py b/nova/virt/baremetal/volume_driver.py index cc23f90646b6..6cf6b775f504 100644 --- a/nova/virt/baremetal/volume_driver.py +++ b/nova/virt/baremetal/volume_driver.py @@ -24,6 +24,7 @@ from nova import context as nova_context from nova import exception from nova.openstack.common import importutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.baremetal import db as bmdb from nova.virt.libvirt import utils as libvirt_utils @@ -91,7 +92,7 @@ def _delete_iscsi_export_tgtadm(tid): '--tid', tid, '--lun', '1', run_as_root=True) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: pass try: utils.execute('tgtadm', '--lld', 'iscsi', @@ -99,7 +100,7 @@ def _delete_iscsi_export_tgtadm(tid): '--op', 'delete', '--tid', tid, run_as_root=True) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: pass # Check if the tid is deleted, that is, check the tid no longer exists. # If the tid dose not exist, tgtadm returns with exit_code 22. @@ -113,7 +114,7 @@ def _delete_iscsi_export_tgtadm(tid): '--op', 'show', '--tid', tid, run_as_root=True) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: if e.exit_code == 22: # OK, the tid is deleted return diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py index 497e2baaa70a..2c5def4931b5 100755 --- a/nova/virt/disk/api.py +++ b/nova/virt/disk/api.py @@ -37,6 +37,7 @@ from oslo.config import cfg from nova import exception from nova.openstack.common import jsonutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import paths from nova import utils from nova.virt.disk.mount import api as mount @@ -155,7 +156,7 @@ def can_resize_fs(image, size, use_cow=False): # For raw, we can directly inspect the file system try: utils.execute('e2label', image) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: LOG.debug(_('Unable to determine label for image %(image)s with ' 'error %(errror)s. Cannot resize.'), {'image': image, diff --git a/nova/virt/hyperv/vmops.py b/nova/virt/hyperv/vmops.py index 615567c0ddc9..2bda94a354ea 100644 --- a/nova/virt/hyperv/vmops.py +++ b/nova/virt/hyperv/vmops.py @@ -28,6 +28,7 @@ from nova import exception from nova.openstack.common import excutils from nova.openstack.common import importutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt import configdrive from nova.virt.hyperv import constants @@ -229,7 +230,7 @@ class VMOps(object): with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb: try: cdb.make_drive(configdrive_path_iso) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error(_('Creating config drive failed with error: %s'), e, instance=instance) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index e8a0a46ebd9f..a0d2d0a7b917 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -77,6 +77,7 @@ from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.openstack.common import loopingcall from nova.openstack.common.notifier import api as notifier +from nova.openstack.common import processutils from nova import utils from nova import version from nova.virt import configdrive @@ -1871,7 +1872,7 @@ class LibvirtDriver(driver.ComputeDriver): try: cdb.make_drive(configdrive_path) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception(): LOG.error(_('Creating config drive failed ' 'with error: %s'), @@ -3236,7 +3237,7 @@ class LibvirtDriver(driver.ComputeDriver): try: self.plug_vifs(instance, network_info) break - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: if cnt == max_retry - 1: raise else: diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 96f84c194621..07ab447696ef 100755 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -26,8 +26,8 @@ import os from lxml import etree from oslo.config import cfg -from nova import exception from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt import images @@ -64,7 +64,7 @@ def get_fc_hbas(): try: out, err = execute('systool', '-c', 'fc_host', '-v', run_as_root=True) - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: # This handles the case where rootwrap is used # and systool is not installed # 96 = nova.cmd.rootwrap.RC_NOEXECFOUND: @@ -427,7 +427,7 @@ def copy_image(src, dest, host=None): # can fall back to scp, without having run out of space # on the destination for example. execute('rsync', '--sparse', '--compress', '--dry-run', src, dest) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: execute('scp', src, dest) else: execute('rsync', '--sparse', '--compress', src, dest) diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index db7bb96d83f9..28c481cfeb65 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -27,6 +27,7 @@ from nova import exception from nova.network import linux_net from nova.network import model as network_model from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.libvirt import config as vconfig from nova.virt.libvirt import designer @@ -417,7 +418,7 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): network, mapping = vif linux_net.delete_ovs_vif_port(self.get_bridge_name(network), self.get_vif_devname(mapping)) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_("Failed while unplugging vif"), instance=instance) def unplug_ovs_bridge(self, instance, vif): @@ -446,7 +447,7 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver): linux_net.delete_ovs_vif_port(self.get_bridge_name(network), v2_name) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_("Failed while unplugging vif"), instance=instance) def unplug_ovs(self, instance, vif): diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py index 1d226ae83cba..5f8d4bd72dc3 100644 --- a/nova/virt/libvirt/volume.py +++ b/nova/virt/libvirt/volume.py @@ -30,6 +30,7 @@ from nova import exception from nova.openstack.common import lockutils from nova.openstack.common import log as logging from nova.openstack.common import loopingcall +from nova.openstack.common import processutils from nova import paths from nova.storage import linuxscsi from nova import utils @@ -314,7 +315,7 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): # volume is using the same target. try: self._run_iscsiadm(iscsi_properties, ()) - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: # iscsiadm returns 21 for "No records found" after version 2.0-871 if exc.exit_code in [21, 255]: self._run_iscsiadm(iscsi_properties, ('--op', 'new')) @@ -353,7 +354,7 @@ class LibvirtISCSIVolumeDriver(LibvirtBaseVolumeDriver): self._run_iscsiadm(iscsi_properties, ("--login",), check_exit_code=[0, 255]) - except exception.ProcessExecutionError as err: + except processutils.ProcessExecutionError as err: #as this might be one of many paths, #only set successfull logins to startup automatically if err.exit_code in [15]: @@ -484,7 +485,7 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver): try: utils.execute(*nfs_cmd, run_as_root=True) - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: if ensure and 'already mounted' in exc.message: LOG.warn(_("%s is already mounted"), nfs_share) else: @@ -500,7 +501,7 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver): """Check path.""" try: return utils.execute('stat', path, run_as_root=True) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: return False @@ -605,7 +606,7 @@ class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): utils.execute('mount', '-t', 'glusterfs', glusterfs_share, mount_path, run_as_root=True) - except exception.ProcessExecutionError as exc: + except processutils.ProcessExecutionError as exc: if ensure and 'already mounted' in exc.message: LOG.warn(_("%s is already mounted"), glusterfs_share) else: @@ -621,7 +622,7 @@ class LibvirtGlusterfsVolumeDriver(LibvirtBaseVolumeDriver): """Check path.""" try: return utils.execute('stat', path, run_as_root=True) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: return False diff --git a/nova/virt/powervm/common.py b/nova/virt/powervm/common.py index 34658547cb2a..dd6517dcde8e 100644 --- a/nova/virt/powervm/common.py +++ b/nova/virt/powervm/common.py @@ -21,8 +21,8 @@ import uuid import paramiko -from nova import exception as nova_exception from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.powervm import constants from nova.virt.powervm import exception @@ -68,7 +68,7 @@ def ssh_command_as_root(ssh_connection, cmd, check_exit_code=True): :param connection: an active paramiko.SSHClient connection. :param command: string containing the command to run. :returns: Tuple -- a tuple of (stdout, stderr) - :raises: nova.exception.ProcessExecutionError + :raises: processutils.ProcessExecutionError """ LOG.debug(_('Running cmd (SSH-as-root): %s') % cmd) chan = ssh_connection._transport.open_session() @@ -89,10 +89,13 @@ def ssh_command_as_root(ssh_connection, cmd, check_exit_code=True): if exit_status != -1: LOG.debug(_('Result was %s') % exit_status) if check_exit_code and exit_status != 0: - raise nova_exception.ProcessExecutionError(exit_code=exit_status, - stdout=stdout, - stderr=stderr, - cmd=''.join(cmd)) + # TODO(mikal): I know this is weird, but it needs to be consistent + # with processutils.execute. I will move this method to oslo in + # a later commit. + raise processutils.ProcessExecutionError(exit_code=exit_status, + stdout=stdout, + stderr=stderr, + cmd=''.join(cmd)) return (stdout, stderr) diff --git a/nova/virt/powervm/operator.py b/nova/virt/powervm/operator.py index 946835224e7e..b5ead9064600 100644 --- a/nova/virt/powervm/operator.py +++ b/nova/virt/powervm/operator.py @@ -22,9 +22,9 @@ import time from oslo.config import cfg from nova.compute import power_state -from nova import exception as nova_exception from nova.openstack.common import excutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt.powervm import blockdev from nova.virt.powervm import command @@ -199,7 +199,7 @@ class PowerVMOperator(object): # system (1 in 2^28) self._operator.create_lpar(lpar_inst) LOG.debug(_("Creating LPAR instance '%s'") % instance['name']) - except nova_exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_("LPAR instance '%s' creation failed") % instance['name']) raise exception.PowerVMLPARCreationFailed( diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index e569216c8bbe..9832dca84c33 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -44,6 +44,7 @@ from nova import exception from nova.image import glance from nova.openstack.common import excutils from nova.openstack.common import log as logging +from nova.openstack.common import processutils from nova import utils from nova.virt import configdrive from nova.virt.disk import api as disk @@ -1979,7 +1980,7 @@ def _is_vdi_pv(dev): LOG.debug(_("Found Xen kernel %s") % m.group(0)) return True LOG.debug(_("No Xen kernel found. Booting HVM.")) - except exception.ProcessExecutionError: + except processutils.ProcessExecutionError: LOG.exception(_("Error while executing pygrub! Please, ensure the " "binary is installed correctly, and available in your " "PATH; on some Linux distros, pygrub may be installed " @@ -2161,7 +2162,7 @@ def _mount_filesystem(dev_path, dir): _out, err = utils.execute('mount', '-t', 'ext2,ext3,ext4,reiserfs', dev_path, dir, run_as_root=True) - except exception.ProcessExecutionError as e: + except processutils.ProcessExecutionError as e: err = str(e) return err