summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-06-13 23:58:56 +0000
committerGerrit Code Review <review@openstack.org>2013-06-13 23:58:56 +0000
commitacda8b374169742257c098fa99220d7c823ff5ee (patch)
tree52d587d78dd4f23bc889a0abd8a30a6f5c735be5
parent0882a1505168e4a020d52f478eebdd3874d98ab1 (diff)
parentb53f83eaf106bcf37551dac3393c1a3e4a7ac938 (diff)
downloadnova-acda8b374169742257c098fa99220d7c823ff5ee.tar.gz
nova-acda8b374169742257c098fa99220d7c823ff5ee.tar.xz
nova-acda8b374169742257c098fa99220d7c823ff5ee.zip
Merge "Make sync_power_state routines use InstanceList"
-rw-r--r--nova/compute/api.py8
-rwxr-xr-xnova/compute/manager.py25
-rw-r--r--nova/tests/compute/test_compute.py76
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):