Skip to content

Commit ff8bf96

Browse files
committed
Insure resource tracker updated for deleted instances
Instances left in a deleted state at compute manager startup were not being explicitly cleaned up in the resoruce tracker. To address this _update_resource_tracker is now called from solely the _complete_deletion method. That method is called both by the _init_instance and _delete_instance code paths, both of which should be doing cleanup in the resource tracker when the vm is DELETED. Note that this change does mean that if _delete_instance has an exception, _update_resource_tracker will not be called. This is considered okay because we cannot guarantee at which stage the exception happened and the state of the resources involved. For safety it is better to err on the side of "in use". Change-Id: I586c0305ea0e20d98697bc9173ca0f89dc2b228c Related-Bug: #1227925
1 parent 848de1f commit ff8bf96

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

nova/compute/manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ def _complete_deletion(self, context, instance, bdms,
918918
for bdm in bdms:
919919
bdm.destroy()
920920

921+
self._update_resource_tracker(context, instance)
921922
self._notify_about_instance_usage(context, instance, "delete.end",
922923
system_metadata=system_meta)
923924

@@ -2433,7 +2434,6 @@ def _delete_instance(self, context, instance, bdms, quotas):
24332434
instance.power_state = power_state.NOSTATE
24342435
instance.terminated_at = timeutils.utcnow()
24352436
instance.save()
2436-
self._update_resource_tracker(context, instance)
24372437
system_meta = instance.system_metadata
24382438
instance.destroy()
24392439
except Exception:

nova/tests/unit/compute/test_compute.py

+40
Original file line numberDiff line numberDiff line change
@@ -6817,6 +6817,46 @@ def fake_destroy():
68176817

68186818
self.assertNotEqual(0, instance.deleted)
68196819

6820+
def test_terminate_instance_updates_tracker(self):
6821+
rt = self.compute._get_resource_tracker(NODENAME)
6822+
admin_context = context.get_admin_context()
6823+
6824+
self.assertEqual(0, rt.compute_node.vcpus_used)
6825+
instance = self._create_fake_instance_obj()
6826+
instance.vcpus = 1
6827+
6828+
rt.instance_claim(admin_context, instance)
6829+
self.assertEqual(1, rt.compute_node.vcpus_used)
6830+
6831+
self.compute.terminate_instance(admin_context, instance, [], [])
6832+
self.assertEqual(0, rt.compute_node.vcpus_used)
6833+
6834+
@mock.patch('nova.compute.manager.ComputeManager'
6835+
'._notify_about_instance_usage')
6836+
@mock.patch('nova.objects.Quotas.reserve')
6837+
# NOTE(cdent): At least in this test destroy() on the instance sets it
6838+
# state back to active, meaning the resource tracker won't
6839+
# update properly.
6840+
@mock.patch('nova.objects.Instance.destroy')
6841+
def test_init_deleted_instance_updates_tracker(self, noop1, noop2, noop3):
6842+
rt = self.compute._get_resource_tracker(NODENAME)
6843+
admin_context = context.get_admin_context()
6844+
6845+
self.assertEqual(0, rt.compute_node.vcpus_used)
6846+
instance = self._create_fake_instance_obj()
6847+
instance.vcpus = 1
6848+
6849+
self.assertEqual(0, rt.compute_node.vcpus_used)
6850+
6851+
rt.instance_claim(admin_context, instance)
6852+
self.compute._init_instance(admin_context, instance)
6853+
self.assertEqual(1, rt.compute_node.vcpus_used)
6854+
6855+
instance.vm_state = vm_states.DELETED
6856+
self.compute._init_instance(admin_context, instance)
6857+
6858+
self.assertEqual(0, rt.compute_node.vcpus_used)
6859+
68206860
def test_init_instance_for_partial_deletion(self):
68216861
admin_context = context.get_admin_context()
68226862
instance = objects.Instance(admin_context)

0 commit comments

Comments
 (0)