summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Bryant <rbryant@redhat.com>2013-03-01 18:10:16 -0500
committerRussell Bryant <rbryant@redhat.com>2013-03-01 18:23:35 -0500
commitfbeb552175c9f9d6d444ac5cc0606a5dceb39ef7 (patch)
tree2daea4fb0a6425abb9126945dedf468addbc9770
parent11764e5250dc2ea4a92cf7402271e7d4e407113f (diff)
downloadnova-fbeb552175c9f9d6d444ac5cc0606a5dceb39ef7.tar.gz
nova-fbeb552175c9f9d6d444ac5cc0606a5dceb39ef7.tar.xz
nova-fbeb552175c9f9d6d444ac5cc0606a5dceb39ef7.zip
Set vm_state to ERROR on net deallocate failure.
If deallocate_network_for_instance from network.api fails while trying to terminate an instance, set the vm_state to ERROR. Previously it still completely failed at this point, but the instance vm_state was still ACTIVE but the task_state was stuck in deleting. Now it will be ERROR/deleting. Fix bug 1110221. Change-Id: I181a11c8de667fa462e1a2cb75b2c8ae41410273
-rwxr-xr-xnova/compute/manager.py10
-rw-r--r--nova/tests/compute/test_compute.py23
2 files changed, 31 insertions, 2 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 9ca00bd9b..b4ac89a49 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1160,8 +1160,14 @@ class ComputeManager(manager.SchedulerDependentManager):
except exception.NetworkNotFound:
network_info = network_model.NetworkInfo()
- # tear down allocated network structure
- self._deallocate_network(context, instance)
+ try:
+ # tear down allocated network structure
+ self._deallocate_network(context, instance)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ LOG.error(_('Failed to deallocate network for instance.'),
+ instance=instance)
+ self._set_instance_error_state(context, instance['uuid'])
# NOTE(vish) get bdms before destroying the instance
vol_bdms = self._get_volume_bdms(bdms)
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 98eba5570..20813cb56 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -850,6 +850,29 @@ class ComputeTestCase(BaseTestCase):
self.assert_(instance['launched_at'] < terminate)
self.assert_(instance['deleted_at'] > terminate)
+ def test_run_terminate_deallocate_net_failure_sets_error_state(self):
+ instance = jsonutils.to_primitive(self._create_fake_instance())
+
+ self.compute.run_instance(self.context, instance=instance)
+
+ instances = db.instance_get_all(self.context)
+ LOG.info(_("Running instances: %s"), instances)
+ self.assertEqual(len(instances), 1)
+
+ def _fake_deallocate_network(*args, **kwargs):
+ raise Exception()
+
+ self.stubs.Set(self.compute, '_deallocate_network',
+ _fake_deallocate_network)
+
+ try:
+ self.compute.terminate_instance(self.context, instance=instance)
+ except Exception:
+ pass
+
+ instance = db.instance_get_by_uuid(self.context, instance['uuid'])
+ self.assertEqual(instance['vm_state'], vm_states.ERROR)
+
def test_stop(self):
# Ensure instance can be stopped.
instance = jsonutils.to_primitive(self._create_fake_instance())