summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorDan Smith <danms@us.ibm.com>2013-05-22 17:30:36 -0700
committerDan Smith <danms@us.ibm.com>2013-06-07 11:43:37 -0700
commit6fcf4133b49cfefa77151937dec4db097a85c349 (patch)
tree07436a73fb8f9ff6b154ffde59aaba52c3078072 /nova/compute
parente86d5b063bbb741d411bf4b50b5cc8a9829960db (diff)
Use Instance Objects for Start/Stop
This patch makes the start and stop operations use the Instance object instead of passing SQLA-derived dicts over RPC. Until something more sophisticated is needed (and developed), it also adds a nova.object.register_all() function which just triggers imports of all the object models so that they are registered. When adding a new object type, that register function should be updated appropriately. Related to bp/unified-object-model Change-Id: I3c8d9cba07d34097a279502062906de802d19d1f
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py20
-rwxr-xr-xnova/compute/manager.py52
-rw-r--r--nova/compute/rpcapi.py19
3 files changed, 62 insertions, 29 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index f676c9797..9ef81ef2b 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -49,6 +49,7 @@ 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
@@ -1343,10 +1344,16 @@ class API(base.Base):
"""Stop an instance."""
LOG.debug(_("Going to try to stop instance"), instance=instance)
- instance = self.update(context, instance,
- task_state=task_states.POWERING_OFF,
- expected_task_state=None,
- progress=0)
+ # 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)
self._record_action_start(context, instance, instance_actions.STOP)
@@ -1360,9 +1367,8 @@ class API(base.Base):
"""Start an instance."""
LOG.debug(_("Going to try to start instance"), instance=instance)
- instance = self.update(context, instance,
- task_state=task_states.POWERING_ON,
- expected_task_state=None)
+ instance.task_state = task_states.POWERING_ON
+ instance.save(expected_task_state=None)
self._record_action_start(context, instance, instance_actions.START)
# TODO(yamahata): injected_files isn't supported right now.
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 2390eb3c3..8c593bda5 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -60,6 +60,7 @@ from nova import manager
from nova import network
from nova.network import model as network_model
from nova.network.security_group import openstack_driver
+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
@@ -266,6 +267,27 @@ def wrap_instance_event(function):
return decorated_function
+# TODO(danms): Remove me after havana
+def object_compat(function):
+ """Wraps a method that expects a new-world instance
+
+ This provides compatibility for callers passing old-style dict
+ instances.
+ """
+
+ @functools.wraps(function)
+ def decorated_function(self, context, **kwargs):
+ metas = ['metadata', 'system_metadata']
+ instance = kwargs['instance']
+ if isinstance(instance, dict):
+ kwargs['instance'] = instance_obj.Instance._from_db_object(
+ instance_obj.Instance(), instance, expected_attrs=metas)
+ kwargs['instance']._context = context
+ return function(self, context, **kwargs)
+
+ return decorated_function
+
+
def _get_image_meta(context, image_ref):
image_service, image_id = glance.get_remote_image_service(context,
image_ref)
@@ -328,7 +350,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
- RPC_API_VERSION = '2.28'
+ RPC_API_VERSION = '2.29'
def __init__(self, compute_driver=None, *args, **kwargs):
"""Load configuration options and connect to the hypervisor."""
@@ -1457,6 +1479,7 @@ class ComputeManager(manager.SchedulerDependentManager):
# NOTE(johannes): This is probably better named power_off_instance
# so it matches the driver method, but because of other issues, we
# can't use that name in grizzly.
+ @object_compat
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@reverts_task_state
@wrap_instance_event
@@ -1466,17 +1489,17 @@ class ComputeManager(manager.SchedulerDependentManager):
self._notify_about_instance_usage(context, instance, "power_off.start")
self.driver.power_off(instance)
current_power_state = self._get_power_state(context, instance)
- instance = self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.STOPPED,
- expected_task_state=(task_states.POWERING_OFF,
- task_states.STOPPING),
- task_state=None)
+ instance.power_state = current_power_state
+ instance.vm_state = vm_states.STOPPED
+ instance.task_state = None
+ instance.save(expected_task_state=(task_states.POWERING_OFF,
+ task_states.STOPPING))
self._notify_about_instance_usage(context, instance, "power_off.end")
# NOTE(johannes): This is probably better named power_on_instance
# so it matches the driver method, but because of other issues, we
# can't use that name in grizzly.
+ @object_compat
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@reverts_task_state
@wrap_instance_event
@@ -1486,12 +1509,11 @@ class ComputeManager(manager.SchedulerDependentManager):
self._notify_about_instance_usage(context, instance, "power_on.start")
self.driver.power_on(instance)
current_power_state = self._get_power_state(context, instance)
- instance = self._instance_update(context, instance['uuid'],
- power_state=current_power_state,
- vm_state=vm_states.ACTIVE,
- task_state=None,
- expected_task_state=(task_states.POWERING_ON,
- task_states.STARTING))
+ instance.power_state = current_power_state
+ instance.vm_state = vm_states.ACTIVE
+ instance.task_state = None
+ instance.save(expected_task_state=(task_states.POWERING_ON,
+ task_states.STARTING))
self._notify_about_instance_usage(context, instance, "power_on.end")
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@@ -1709,7 +1731,7 @@ class ComputeManager(manager.SchedulerDependentManager):
task_state=task_states.STOPPING,
terminated_at=timeutils.utcnow(),
progress=0)
- self.stop_instance(context, instance)
+ self.stop_instance(context, instance=instance)
self._notify_about_instance_usage(
context, instance, "rebuild.end",
@@ -2320,7 +2342,7 @@ class ComputeManager(manager.SchedulerDependentManager):
instance = self._instance_update(
context, instance['uuid'],
task_state=task_states.STOPPING)
- self.stop_instance(context, instance)
+ self.stop_instance(context, instance=instance)
self._notify_about_instance_usage(
context, instance, "resize.revert.end")
diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py
index a8d7eaa47..ac3003cce 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -21,8 +21,10 @@ Client side of the compute RPC API.
from oslo.config import cfg
from nova import exception
+from nova.objects import base as objects_base
from nova.openstack.common import jsonutils
from nova.openstack.common import rpc
+import nova.openstack.common.rpc
import nova.openstack.common.rpc.proxy
rpcapi_opts = [
@@ -166,6 +168,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
2.27 - Adds 'reservations' to terminate_instance() and
soft_delete_instance()
2.28 - Adds check_instance_shared_storage()
+ 2.29 - Made start_instance() and stop_instance() take new-world
+ instance objects
'''
#
@@ -181,7 +185,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
def __init__(self):
super(ComputeAPI, self).__init__(
topic=CONF.compute_topic,
- default_version=self.BASE_RPC_API_VERSION)
+ default_version=self.BASE_RPC_API_VERSION,
+ serializer=objects_base.NovaObjectSerializer())
def add_aggregate_host(self, ctxt, aggregate, host_param, host,
slave_info=None):
@@ -581,17 +586,17 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
topic=_compute_topic(self.topic, ctxt, None, instance))
def start_instance(self, ctxt, instance):
- instance_p = jsonutils.to_primitive(instance)
self.cast(ctxt, self.make_msg('start_instance',
- instance=instance_p),
- topic=_compute_topic(self.topic, ctxt, None, instance))
+ instance=instance),
+ topic=_compute_topic(self.topic, ctxt, None, instance),
+ version='2.29')
def stop_instance(self, ctxt, instance, cast=True):
rpc_method = self.cast if cast else self.call
- instance_p = jsonutils.to_primitive(instance)
return rpc_method(ctxt, self.make_msg('stop_instance',
- instance=instance_p),
- topic=_compute_topic(self.topic, ctxt, None, instance))
+ instance=instance),
+ topic=_compute_topic(self.topic, ctxt, None, instance),
+ version='2.29')
def suspend_instance(self, ctxt, instance):
instance_p = jsonutils.to_primitive(instance)