diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-06-13 23:58:56 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-06-13 23:58:56 +0000 |
| commit | acda8b374169742257c098fa99220d7c823ff5ee (patch) | |
| tree | 52d587d78dd4f23bc889a0abd8a30a6f5c735be5 | |
| parent | 0882a1505168e4a020d52f478eebdd3874d98ab1 (diff) | |
| parent | b53f83eaf106bcf37551dac3393c1a3e4a7ac938 (diff) | |
| download | nova-acda8b374169742257c098fa99220d7c823ff5ee.tar.gz nova-acda8b374169742257c098fa99220d7c823ff5ee.tar.xz nova-acda8b374169742257c098fa99220d7c823ff5ee.zip | |
Merge "Make sync_power_state routines use InstanceList"
| -rw-r--r-- | nova/compute/api.py | 8 | ||||
| -rwxr-xr-x | nova/compute/manager.py | 25 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 76 |
3 files changed, 87 insertions, 22 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index 91f3a60ef..001342822 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -49,7 +49,6 @@ from nova import network from nova.network.security_group import openstack_driver from nova.network.security_group import security_group_base from nova import notifications -from nova.objects import instance as instance_obj from nova.openstack.common import excutils from nova.openstack.common import jsonutils from nova.openstack.common import log as logging @@ -1385,13 +1384,6 @@ class API(base.Base): """Stop an instance.""" LOG.debug(_("Going to try to stop instance"), instance=instance) - # NOTE(danms): Temporary transition to objects. Remove after - # compute/manager.py _sync_instance_power_state() is migrated. - if isinstance(instance, dict): - instance = instance_obj.Instance._from_db_object( - instance_obj.Instance(), instance) - instance._context = context - instance.task_state = task_states.POWERING_OFF instance.progress = 0 instance.save(expected_task_state=None) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 62e8fedee..393e96073 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -620,7 +620,7 @@ class ComputeManager(manager.SchedulerDependentManager): {'state': event.get_transition(), 'uuid': event.get_instance_uuid()}) context = nova.context.get_admin_context() - instance = self.conductor_api.instance_get_by_uuid( + instance = instance_obj.Instance.get_by_uuid( context, event.get_instance_uuid()) vm_power_state = None if event.get_transition() == virtevent.EVENT_LIFECYCLE_STOPPED: @@ -3908,8 +3908,8 @@ class ComputeManager(manager.SchedulerDependentManager): loop, one database record at a time, checking if the hypervisor has the same power state as is in the database. """ - db_instances = self.conductor_api.instance_get_all_by_host( - context, self.host, columns_to_join=[]) + db_instances = instance_obj.InstanceList.get_by_host(context, + self.host) num_vm_instances = self.driver.get_num_instances() num_db_instances = len(db_instances) @@ -3946,13 +3946,11 @@ class ComputeManager(manager.SchedulerDependentManager): # We re-query the DB to get the latest instance info to minimize # (not eliminate) race condition. - u = self.conductor_api.instance_get_by_uuid(context, - db_instance['uuid'], - columns_to_join=[]) - db_power_state = u["power_state"] - vm_state = u['vm_state'] + db_instance.refresh() + db_power_state = db_instance.power_state + vm_state = db_instance.vm_state - if self.host != u['host']: + if self.host != db_instance.host: # on the sending end of nova-compute _sync_power_state # may have yielded to the greenthread performing a live # migration; this in turn has changed the resident-host @@ -3964,10 +3962,10 @@ class ComputeManager(manager.SchedulerDependentManager): "instance has moved from " "host %(src)s to host %(dst)s") % {'src': self.host, - 'dst': u['host']}, + 'dst': db_instance.host}, instance=db_instance) return - elif u['task_state'] is not None: + elif db_instance.task_state is not None: # on the receiving end of nova-compute, it could happen # that the DB instance already report the new resident # but the actual VM has not showed up on the hypervisor @@ -3979,9 +3977,8 @@ class ComputeManager(manager.SchedulerDependentManager): if vm_power_state != db_power_state: # power_state is always updated from hypervisor to db - self._instance_update(context, - db_instance['uuid'], - power_state=vm_power_state) + db_instance.power_state = vm_power_state + db_instance.save() db_power_state = vm_power_state # Note(maoy): Now resolve the discrepancy between vm_state and diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 04da9b9dd..be332beb0 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -5156,6 +5156,82 @@ class ComputeTestCase(BaseTestCase): self.compute._reclaim_queued_deletes(ctxt) + def test_sync_power_states(self): + ctxt = self.context.elevated() + self._create_fake_instance({'host': self.compute.host}) + self._create_fake_instance({'host': self.compute.host}) + self.mox.StubOutWithMock(self.compute.driver, 'get_info') + self.mox.StubOutWithMock(self.compute, '_sync_instance_power_state') + self.compute.driver.get_info(mox.IgnoreArg()).AndReturn( + {'state': power_state.RUNNING}) + self.compute._sync_instance_power_state(ctxt, mox.IgnoreArg(), + power_state.RUNNING) + self.compute.driver.get_info(mox.IgnoreArg()).AndReturn( + {'state': power_state.SHUTDOWN}) + self.compute._sync_instance_power_state(ctxt, mox.IgnoreArg(), + power_state.SHUTDOWN) + self.mox.ReplayAll() + self.compute._sync_power_states(ctxt) + + def _get_sync_instance(self, power_state, vm_state, task_state=None): + instance = instance_obj.Instance() + instance.uuid = 'fake-uuid' + instance.power_state = power_state + instance.vm_state = vm_state + instance.host = self.compute.host + instance.task_state = task_state + self.mox.StubOutWithMock(instance, 'refresh') + self.mox.StubOutWithMock(instance, 'save') + return instance + + def test_sync_instance_power_state_match(self): + instance = self._get_sync_instance(power_state.RUNNING, + vm_states.ACTIVE) + instance.refresh() + self.mox.ReplayAll() + self.compute._sync_instance_power_state(self.context, instance, + power_state.RUNNING) + + def test_sync_instance_power_state_running_stopped(self): + instance = self._get_sync_instance(power_state.RUNNING, + vm_states.ACTIVE) + instance.refresh() + instance.save() + self.mox.ReplayAll() + self.compute._sync_instance_power_state(self.context, instance, + power_state.SHUTDOWN) + self.assertEqual(instance.power_state, power_state.SHUTDOWN) + + def _test_sync_to_stop(self, power_state, vm_state, driver_power_state, + stop=True): + instance = self._get_sync_instance(power_state, vm_state) + instance.refresh() + instance.save() + self.mox.StubOutWithMock(self.compute.conductor_api, 'compute_stop') + if stop: + self.compute.conductor_api.compute_stop(self.context, instance) + self.mox.ReplayAll() + self.compute._sync_instance_power_state(self.context, instance, + driver_power_state) + self.mox.VerifyAll() + self.mox.UnsetStubs() + + def test_sync_instance_power_state_to_stop(self): + for ps in (power_state.SHUTDOWN, power_state.CRASHED, + power_state.SUSPENDED): + self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps) + self._test_sync_to_stop(power_state.SHUTDOWN, vm_states.STOPPED, + power_state.RUNNING) + + def test_sync_instance_power_state_to_no_stop(self): + for ps in (power_state.PAUSED, power_state.NOSTATE): + self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps, + stop=False) + for vs in (vm_states.SOFT_DELETED, vm_states.DELETED): + for ps in (power_state.NOSTATE, power_state.SHUTDOWN): + self._test_sync_to_stop(power_state.RUNNING, vs, ps, + stop=False) + class ComputeAPITestCase(BaseTestCase): |
