diff options
| author | Joe Gordon <jogo@cloudscaling.com> | 2012-08-31 00:04:33 +0000 |
|---|---|---|
| committer | Joe Gordon <jogo@cloudscaling.com> | 2012-08-31 02:06:45 +0000 |
| commit | 77dd6a0b37652bc163d4ad3083e29af55f2b9a5d (patch) | |
| tree | d315ddb9f5f641cd9931ba66f29d569de011ceca | |
| parent | 0749ffc3bedc66df7c82af2887c9839d240d0526 (diff) | |
Allow for deleting VMs from down compute nodes.
Fix bug 872899
If compute node service_is_up returns false, just delete the VM from
the database. If compute node recovers, setting
running_deleted_instance_action=reap will clean up the node.
Change-Id: Ibb5f1e22c2e482d304c59a485a04b882ead0c67d
| -rw-r--r-- | nova/compute/api.py | 17 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 25 |
2 files changed, 31 insertions, 11 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index dcc6a7f06..3292d9080 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -855,7 +855,7 @@ class API(base.Base): cores=-instance['vcpus'], ram=-instance['memory_mb']) - if not instance['host']: + if not host: # Just update database, nothing else we can do constraint = self.db.constraint(host=self.db.equal_any(host)) try: @@ -894,7 +894,20 @@ class API(base.Base): host=src_host, cast=False, reservations=downsize_reservations) - self.compute_rpcapi.terminate_instance(context, instance) + services = self.db.service_get_all_compute_by_host( + context.elevated(), instance['host']) + is_up = False + #Note(jogo): db allows for multiple compute services per host + for service in services: + if utils.service_is_up(service): + is_up = True + self.compute_rpcapi.terminate_instance(context, instance) + break + if is_up == False: + # If compute node isn't up, just delete from DB + LOG.warning(_('host for instance is down, deleting from ' + 'database'), instance=instance) + self.db.instance_destroy(context, instance['uuid']) if reservations: QUOTAS.commit(context, reservations) diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 822c23e03..ffedff1b5 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -148,6 +148,8 @@ class BaseTestCase(test.TestCase): inst['architecture'] = 'x86_64' inst['os_type'] = 'Linux' inst.update(params) + _create_service_entries(self.context.elevated(), + {'fake_zone': [inst['host']]}) return db.instance_create(self.context, inst) def _create_instance(self, params=None, type_name='m1.tiny'): @@ -2403,8 +2405,8 @@ class ComputeAPITestCase(BaseTestCase): 'ramdisk_id': 'fake_ramdisk_id'}, } - def _run_instance(self): - instance = jsonutils.to_primitive(self._create_fake_instance()) + def _run_instance(self, params=None): + instance = jsonutils.to_primitive(self._create_fake_instance(params)) instance_uuid = instance['uuid'] self.compute.run_instance(self.context, instance=instance) @@ -2719,7 +2721,8 @@ class ComputeAPITestCase(BaseTestCase): db.instance_destroy(self.context, instance['uuid']) def test_delete(self): - instance, instance_uuid = self._run_instance() + instance, instance_uuid = self._run_instance(params={ + 'host': FLAGS.host}) self.compute_api.delete(self.context, instance) @@ -2742,7 +2745,8 @@ class ComputeAPITestCase(BaseTestCase): self.stubs.Set(QUOTAS, 'commit', fake_commit) - instance, instance_uuid = self._run_instance() + instance, instance_uuid = self._run_instance(params={ + 'host': FLAGS.host}) self.compute_api.delete(self.context, instance) self.compute_api.delete(self.context, instance) @@ -2761,7 +2765,8 @@ class ComputeAPITestCase(BaseTestCase): self.context, instance['uuid']) def test_delete_handles_host_setting_race_condition(self): - instance, instance_uuid = self._run_instance() + instance, instance_uuid = self._run_instance(params={ + 'host': FLAGS.host}) instance['host'] = None # make it think host was never set self.compute_api.delete(self.context, instance) @@ -2771,7 +2776,8 @@ class ComputeAPITestCase(BaseTestCase): db.instance_destroy(self.context, instance['uuid']) def test_delete_fail(self): - instance, instance_uuid = self._run_instance() + instance, instance_uuid = self._run_instance(params={ + 'host': FLAGS.host}) instance = db.instance_update(self.context, instance_uuid, {'disable_terminate': True}) @@ -2806,7 +2812,8 @@ class ComputeAPITestCase(BaseTestCase): def test_force_delete(self): """Ensure instance can be deleted after a soft delete""" - instance = jsonutils.to_primitive(self._create_fake_instance()) + instance = jsonutils.to_primitive(self._create_fake_instance(params={ + 'host': FLAGS.host})) instance_uuid = instance['uuid'] self.compute.run_instance(self.context, instance=instance) @@ -3999,7 +4006,7 @@ class ComputeAPITestCase(BaseTestCase): db.instance_destroy(self.context, i_ref['uuid']) def test_add_remove_fixed_ip(self): - instance = self._create_fake_instance() + instance = self._create_fake_instance(params={'host': FLAGS.host}) self.compute_api.add_fixed_ip(self.context, instance, '1') self.compute_api.remove_fixed_ip(self.context, instance, '192.168.1.1') self.compute_api.delete(self.context, instance) @@ -4097,7 +4104,7 @@ class ComputeAPITestCase(BaseTestCase): self.compute_api.attach_volume(self.context, instance, 1, '/dev/vdb') def test_inject_network_info(self): - instance = self._create_fake_instance() + instance = self._create_fake_instance(params={'host': FLAGS.host}) self.compute.run_instance(self.context, instance=jsonutils.to_primitive(instance)) instance = self.compute_api.get(self.context, instance['uuid']) |
