diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-05-02 22:50:49 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-05-02 22:50:49 +0000 |
| commit | fba02baf8dbf6d3d9a7ed58a498670157004bce5 (patch) | |
| tree | d6de55dd04f058e074f2472916f0a74a05af0fac | |
| parent | b841b6af4e7b66be5add0d5346fbae68cfde682e (diff) | |
| parent | 29dc47bd5045853d83a2343ec88c36ea89db188d (diff) | |
| download | nova-fba02baf8dbf6d3d9a7ed58a498670157004bce5.tar.gz nova-fba02baf8dbf6d3d9a7ed58a498670157004bce5.tar.xz nova-fba02baf8dbf6d3d9a7ed58a498670157004bce5.zip | |
Merge "Use save_and_reraise_exception() from common."
| -rw-r--r-- | nova/compute/manager.py | 23 | ||||
| -rw-r--r-- | nova/openstack/common/excutils.py | 49 | ||||
| -rw-r--r-- | nova/rpc/amqp.py | 5 | ||||
| -rw-r--r-- | nova/scheduler/manager.py | 8 | ||||
| -rw-r--r-- | nova/utils.py | 33 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 3 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 7 | ||||
| -rw-r--r-- | nova/volume/manager.py | 9 | ||||
| -rw-r--r-- | openstack-common.conf | 2 |
9 files changed, 84 insertions, 55 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 71f7e817b..3bb5797ce 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -62,6 +62,7 @@ from nova import network from nova.network import model as network_model from nova.notifier import api as notifier from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova.openstack.common import importutils from nova import rpc from nova import utils @@ -187,7 +188,7 @@ def wrap_instance_fault(function): except exception.InstanceNotFound: raise except Exception, e: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.add_instance_fault_from_exc(context, instance_uuid, e, sys.exc_info()) @@ -433,7 +434,7 @@ class ComputeManager(manager.SchedulerDependentManager): network_info, block_device_info, injected_files, admin_password) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._deallocate_network(context, instance) if (is_first_time and not instance['access_ip_v4'] @@ -445,7 +446,7 @@ class ComputeManager(manager.SchedulerDependentManager): except exception.InstanceNotFound: LOG.warn(_("Instance not found."), instance_uuid=instance_uuid) except Exception as e: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._set_instance_error_state(context, instance_uuid) def _update_access_ip(self, context, instance, nw_info): @@ -1335,7 +1336,7 @@ class ComputeManager(manager.SchedulerDependentManager): context, instance_ref, migration_ref['dest_host'], instance_type_ref, self._legacy_nw_info(network_info)) except Exception, error: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): LOG.error(_('%s. Setting instance vm_state to ERROR') % error, instance=instance_ref) self._set_instance_error_state(context, instance_uuid) @@ -1425,7 +1426,7 @@ class ComputeManager(manager.SchedulerDependentManager): self._finish_resize(context, instance_ref, migration_ref, disk_info, image) except Exception, error: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): LOG.error(_('%s. Setting instance vm_state to ERROR') % error, instance=instance_ref) self._set_instance_error_state(context, instance_ref.uuid) @@ -1719,7 +1720,7 @@ class ComputeManager(manager.SchedulerDependentManager): volume, connector) except Exception: # pylint: disable=W0702 - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): msg = _("Failed to connect to volume %(volume_id)s " "while attaching at %(mountpoint)s") LOG.exception(msg % locals(), context=context, @@ -1730,7 +1731,7 @@ class ComputeManager(manager.SchedulerDependentManager): instance_ref['name'], mountpoint) except Exception: # pylint: disable=W0702 - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): msg = _("Failed to attach volume %(volume_id)s " "at %(mountpoint)s") LOG.exception(msg % locals(), context=context, @@ -1975,7 +1976,7 @@ class ComputeManager(manager.SchedulerDependentManager): 'disk': disk}}) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): instance_uuid = instance_ref['uuid'] LOG.exception(_('Pre live migration failed at %(dest)s'), locals(), instance=instance_ref) @@ -2506,7 +2507,7 @@ class ComputeManager(manager.SchedulerDependentManager): try: yield except Exception, error: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): msg = _('%s. Setting instance vm_state to ERROR') LOG.error(msg % error, instance_uuid=instance_uuid) self._set_instance_error_state(context, instance_uuid) @@ -2518,7 +2519,7 @@ class ComputeManager(manager.SchedulerDependentManager): try: self.driver.add_to_aggregate(context, aggregate, host, **kwargs) except exception.AggregateError: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._undo_aggregate_operation(context, self.db.aggregate_host_delete, aggregate.id, host) @@ -2532,7 +2533,7 @@ class ComputeManager(manager.SchedulerDependentManager): aggregate, host, **kwargs) except (exception.AggregateError, exception.InvalidAggregateAction) as e: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._undo_aggregate_operation( context, self.db.aggregate_host_add, aggregate.id, host, diff --git a/nova/openstack/common/excutils.py b/nova/openstack/common/excutils.py new file mode 100644 index 000000000..3cb678e9d --- /dev/null +++ b/nova/openstack/common/excutils.py @@ -0,0 +1,49 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# Copyright 2012, Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Exception related utilities. +""" + +import contextlib +import logging +import sys +import traceback + + +@contextlib.contextmanager +def save_and_reraise_exception(): + """Save current exception, run some code and then re-raise. + + In some cases the exception context can be cleared, resulting in None + being attempted to be reraised after an exception handler is run. This + can happen when eventlet switches greenthreads or when running an + exception handler, code raises and catches an exception. In both + cases the exception context will be cleared. + + To work around this, we save the exception state, run handler code, and + then re-raise the original exception. If another exception occurs, the + saved exception is logged and the new exception is reraised. + """ + type_, value, tb = sys.exc_info() + try: + yield + except Exception: + logging.error('Original exception being dropped: %s' % + (traceback.format_exception(type_, value, tb))) + raise + raise type_, value, tb diff --git a/nova/rpc/amqp.py b/nova/rpc/amqp.py index 37f8758b5..798a5f36e 100644 --- a/nova/rpc/amqp.py +++ b/nova/rpc/amqp.py @@ -36,9 +36,10 @@ from eventlet import semaphore from nova import context from nova import exception from nova import log as logging +from nova.openstack.common import excutils from nova.openstack.common import local import nova.rpc.common as rpc_common -from nova import utils + LOG = logging.getLogger(__name__) @@ -312,7 +313,7 @@ class MulticallWaiter(object): try: self._iterator.next() except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.done() if self._got_ending: self.done() diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index 959c91583..adea730e9 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -31,8 +31,8 @@ from nova import log as logging from nova import manager from nova.notifier import api as notifier from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova.openstack.common import importutils -from nova import utils LOG = logging.getLogger(__name__) @@ -92,7 +92,7 @@ class SchedulerManager(manager.Manager): try: return driver_method(*args, **kwargs) except Exception as ex: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._set_vm_state_and_notify(method, {'vm_state': vm_states.ERROR}, context, ex, *args, **kwargs) @@ -110,7 +110,7 @@ class SchedulerManager(manager.Manager): {'vm_state': vm_states.ERROR}, context, ex, *args, **kwargs) except Exception as ex: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._set_vm_state_and_notify('run_instance', {'vm_state': vm_states.ERROR}, context, ex, *args, **kwargs) @@ -129,7 +129,7 @@ class SchedulerManager(manager.Manager): 'task_state': None}, context, ex, *args, **kwargs) except Exception as ex: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self._set_vm_state_and_notify('prep_resize', {'vm_state': vm_states.ERROR}, context, ex, *args, **kwargs) diff --git a/nova/utils.py b/nova/utils.py index 71e734e8b..c57833c54 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -57,6 +57,7 @@ from nova import exception from nova import flags from nova import log as logging from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova.openstack.common import importutils @@ -1258,32 +1259,6 @@ def generate_glance_url(): @contextlib.contextmanager -def save_and_reraise_exception(): - """Save current exception, run some code and then re-raise. - - In some cases the exception context can be cleared, resulting in None - being attempted to be reraised after an exception handler is run. This - can happen when eventlet switches greenthreads or when running an - exception handler, code raises and catches an exception. In both - cases the exception context will be cleared. - - To work around this, we save the exception state, run handler code, and - then re-raise the original exception. If another exception occurs, the - saved exception is logged and the new exception is reraised. - """ - type_, value, traceback = sys.exc_info() - try: - yield - except Exception: - # NOTE(jkoelker): Using LOG.error here since it accepts exc_info - # as a kwargs. - LOG.error(_('Original exception being dropped'), - exc_info=(type_, value, traceback)) - raise - raise type_, value, traceback - - -@contextlib.contextmanager def logging_error(message): """Catches exception, write message to the log, re-raise. This is a common refinement of save_and_reraise that writes a specific @@ -1292,7 +1267,7 @@ def logging_error(message): try: yield except Exception as error: - with save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): LOG.exception(message) @@ -1304,7 +1279,7 @@ def remove_path_on_error(path): try: yield except Exception: - with save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): delete_if_exists(path) @@ -1671,7 +1646,7 @@ class UndoManager(object): .. note:: (sirp) This should only be called within an exception handler. """ - with save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): if msg: LOG.exception(msg, **kwargs) diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 42b6cbdbd..6d97ce170 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -64,6 +64,7 @@ from nova import flags import nova.image from nova import log as logging from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova.openstack.common import importutils from nova import utils from nova.virt import driver @@ -2220,7 +2221,7 @@ class LibvirtConnection(driver.ComputeDriver): FLAGS.live_migration_bandwidth) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): recover_method(ctxt, instance_ref, dest, block_migration) # Waiting for completion of live_migration. diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 9c478afab..540a144c8 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -35,14 +35,15 @@ from xml.parsers import expat from eventlet import greenthread +from nova.compute import instance_types +from nova.compute import power_state from nova import exception from nova import flags from nova.image import glance from nova import log as logging from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova import utils -from nova.compute import instance_types -from nova.compute import power_state from nova.virt.disk import api as disk from nova.virt import xenapi from nova.virt.xenapi import volume_utils @@ -558,7 +559,7 @@ class VMHelper(xenapi.HelperBase): cls.create_vbd(session, vm_ref, vdi_ref, userdevice, bootable=False) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): cls.destroy_vdi(session, vdi_ref) @classmethod diff --git a/nova/volume/manager.py b/nova/volume/manager.py index dc9f6d27c..2e9f21e2a 100644 --- a/nova/volume/manager.py +++ b/nova/volume/manager.py @@ -44,6 +44,7 @@ from nova import flags from nova import log as logging from nova import manager from nova.openstack.common import cfg +from nova.openstack.common import excutils from nova.openstack.common import importutils from nova import rpc from nova import utils @@ -134,7 +135,7 @@ class VolumeManager(manager.SchedulerDependentManager): if model_update: self.db.volume_update(context, volume_ref['id'], model_update) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.db.volume_update(context, volume_ref['id'], {'status': 'error'}) @@ -168,7 +169,7 @@ class VolumeManager(manager.SchedulerDependentManager): {'status': 'available'}) return True except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.db.volume_update(context, volume_ref['id'], {'status': 'error_deleting'}) @@ -192,7 +193,7 @@ class VolumeManager(manager.SchedulerDependentManager): model_update) except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.db.snapshot_update(context, snapshot_ref['id'], {'status': 'error'}) @@ -218,7 +219,7 @@ class VolumeManager(manager.SchedulerDependentManager): {'status': 'available'}) return True except Exception: - with utils.save_and_reraise_exception(): + with excutils.save_and_reraise_exception(): self.db.snapshot_update(context, snapshot_ref['id'], {'status': 'error_deleting'}) diff --git a/openstack-common.conf b/openstack-common.conf index 61850d238..e39e5d468 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -1,7 +1,7 @@ [DEFAULT] # The list of modules to copy from openstack-common -modules=cfg,local,importutils,iniparser +modules=cfg,excutils,local,importutils,iniparser # The base module to hold the copy of openstack.common base=nova |
