diff options
| author | Dan Smith <danms@us.ibm.com> | 2013-05-22 17:30:36 -0700 |
|---|---|---|
| committer | Dan Smith <danms@us.ibm.com> | 2013-06-07 11:43:37 -0700 |
| commit | 6fcf4133b49cfefa77151937dec4db097a85c349 (patch) | |
| tree | 07436a73fb8f9ff6b154ffde59aaba52c3078072 /nova/compute | |
| parent | e86d5b063bbb741d411bf4b50b5cc8a9829960db (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.py | 20 | ||||
| -rwxr-xr-x | nova/compute/manager.py | 52 | ||||
| -rw-r--r-- | nova/compute/rpcapi.py | 19 |
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) |
