From c27558518800322bd13de5d6bd58bffba4e1a92f Mon Sep 17 00:00:00 2001 From: Jason Kölker Date: Fri, 19 Oct 2012 12:47:55 -0500 Subject: Deallocate network if instance is deleted in spawn If the instance is deleted while the virt driver is spawning, an InstanceNotFound exception is raised and caught in compute to prevent it from being rescheduled. This also deallocates the network to prevent leaking interfaces/mac/ips. * Fixes LP1068716 Change-Id: I991f5956facf7b105faea137d4a5b48897e68ae6 --- nova/compute/manager.py | 8 +++++++- nova/tests/compute/test_compute.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 6088cbf30..e7fd0b090 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -497,7 +497,13 @@ class ComputeManager(manager.SchedulerDependentManager): injected_files, admin_password) except exception.InstanceNotFound: - raise # the instance got deleted during the spawn + # the instance got deleted during the spawn + try: + self._deallocate_network(context, instance) + except Exception: + msg = _('Failed to dealloc network for deleted instance') + LOG.exception(msg, instance=instance) + raise except Exception: # try to re-schedule instance: self._reschedule_or_reraise(context, instance, diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 6fc317775..5205ed799 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -568,6 +568,25 @@ class ComputeTestCase(BaseTestCase): self._assert_state({'vm_state': vm_states.ERROR, 'task_state': None}) + def test_run_instance_dealloc_network_instance_not_found(self): + """ spawn network deallocate test. + + Make sure that when an instance is not found during spawn + that the network is deallocated""" + instance = self._create_instance() + + def fake(*args, **kwargs): + raise exception.InstanceNotFound() + + self.stubs.Set(self.compute.driver, 'spawn', fake) + self.mox.StubOutWithMock(self.compute, '_deallocate_network') + self.compute._deallocate_network(mox.IgnoreArg(), mox.IgnoreArg()) + self.mox.ReplayAll() + + self.assertRaises(exception.InstanceNotFound, + self.compute.run_instance, + self.context, instance=instance) + def test_can_terminate_on_error_state(self): """Make sure that the instance can be terminated in ERROR state""" elevated = context.get_admin_context() -- cgit