Make compute_api migrate/resize paths use instance objects

This converts the migrate/resize/live_migrate paths to use instance
objects.  This also syncs up cells rpcapi and compute task rpcapi so
we can ditch the special cells code in compute/cells_api.py.

Related to blueprint compute-api-objects

Change-Id: I977a5edb8a5313b2a8827796ff8c2bc081f9d63f
This commit is contained in:
Dan Smith
2013-08-12 15:55:04 -07:00
committed by Chris Behrens
parent d40ffa8b2c
commit a2ba455e2d
25 changed files with 621 additions and 439 deletions

View File

@@ -349,12 +349,21 @@ class LocalComputeTaskAPI(object):
self._manager = utils.ExceptionHelper(
manager.ComputeTaskManager())
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit,
reservations=None):
def resize_instance(self, context, instance, extra_instance_updates,
scheduler_hint, flavor, reservations):
# NOTE(comstud): 'extra_instance_updates' is not used here but is
# needed for compatibility with the cells_rpcapi version of this
# method.
self._manager.migrate_server(
context, instance, scheduler_hint, live, rebuild, flavor,
block_migration, disk_over_commit, reservations)
context, instance, scheduler_hint, False, False, flavor,
None, None, reservations)
def live_migrate_instance(self, context, instance, host_name,
block_migration, disk_over_commit):
scheduler_hint = {'host': host_name}
self._manager.migrate_server(
context, instance, scheduler_hint, True, False, None,
block_migration, disk_over_commit, None)
def build_instances(self, context, instances, image,
filter_properties, admin_password, injected_files,
@@ -423,12 +432,21 @@ class ComputeTaskAPI(object):
def __init__(self):
self.conductor_compute_rpcapi = rpcapi.ComputeTaskAPI()
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit,
reservations=None):
def resize_instance(self, context, instance, extra_instance_updates,
scheduler_hint, flavor, reservations):
# NOTE(comstud): 'extra_instance_updates' is not used here but is
# needed for compatibility with the cells_rpcapi version of this
# method.
self.conductor_compute_rpcapi.migrate_server(
context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit, reservations)
context, instance, scheduler_hint, False, False, flavor,
None, None, reservations)
def live_migrate_instance(self, context, instance, host_name,
block_migration, disk_over_commit):
scheduler_hint = {'host': host_name}
self.conductor_compute_rpcapi.migrate_server(
context, instance, scheduler_hint, True, False, None,
block_migration, disk_over_commit, None)
def build_instances(self, context, instances, image, filter_properties,
admin_password, injected_files, requested_networks,

View File

@@ -582,7 +582,7 @@ class ComputeTaskManager(base.Base):
"""
RPC_API_NAMESPACE = 'compute_task'
RPC_API_VERSION = '1.5'
RPC_API_VERSION = '1.6'
def __init__(self):
super(ComputeTaskManager, self).__init__()
@@ -601,6 +601,14 @@ class ComputeTaskManager(base.Base):
exception.MigrationPreCheckError)
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit, reservations=None):
if instance and not isinstance(instance, instance_obj.Instance):
# NOTE(danms): Until v2 of the RPC API, we need to tolerate
# old-world instance objects here
attrs = ['metadata', 'system_metadata', 'info_cache',
'security_groups']
instance = instance_obj.Instance._from_db_object(
context, instance_obj.Instance(), instance,
expected_attrs=attrs)
if live and not rebuild and not flavor:
self._live_migrate(context, instance, scheduler_hint,
block_migration, disk_over_commit)
@@ -616,7 +624,7 @@ class ComputeTaskManager(base.Base):
def _cold_migrate(self, context, instance, flavor, filter_properties,
reservations):
image_ref = instance.get('image_ref')
image_ref = instance.image_ref
if image_ref:
image = self._get_image(context, image_ref)
else:
@@ -655,7 +663,8 @@ class ComputeTaskManager(base.Base):
(host, node) = (host_state['host'], host_state['nodename'])
self.compute_rpcapi.prep_resize(
context, image, instance, flavor, host,
context, image, nova_object.obj_to_primitive(instance),
flavor, host,
reservations, request_spec=request_spec,
filter_properties=filter_properties, node=node)
except Exception as ex:
@@ -722,12 +731,6 @@ class ComputeTaskManager(base.Base):
filter_properties=filter_properties,
legacy_bdm_in_spec=legacy_bdm)
def _instance_update(self, context, instance_uuid, **kwargs):
(old_ref, instance_ref) = self.db.instance_update_and_get_original(
context, instance_uuid, kwargs)
notifications.send_update(context, old_ref, instance_ref, 'conductor')
return instance_ref
def _get_image(self, context, image_id):
if not image_id:
return None

View File

@@ -519,6 +519,7 @@ class ComputeTaskAPI(nova.openstack.common.rpc.proxy.RpcProxy):
1.3 - Added unshelve_instance
1.4 - Added reservations to migrate_server.
1.5 - Added the leagacy_bdm parameter to build_instances
1.6 - Made migrate_server use instance objects
"""
BASE_RPC_API_VERSION = '1.0'
@@ -533,13 +534,18 @@ class ComputeTaskAPI(nova.openstack.common.rpc.proxy.RpcProxy):
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit,
reservations=None):
instance_p = jsonutils.to_primitive(instance)
if self.can_send_version('1.6'):
version = '1.6'
else:
instance = jsonutils.to_primitive(
objects_base.obj_to_primitive(instance))
version = '1.4'
flavor_p = jsonutils.to_primitive(flavor)
msg = self.make_msg('migrate_server', instance=instance_p,
msg = self.make_msg('migrate_server', instance=instance,
scheduler_hint=scheduler_hint, live=live, rebuild=rebuild,
flavor=flavor_p, block_migration=block_migration,
disk_over_commit=disk_over_commit, reservations=reservations)
return self.call(context, msg, version='1.4')
return self.call(context, msg, version=version)
def build_instances(self, context, instances, image, filter_properties,
admin_password, injected_files, requested_networks,

View File

@@ -20,6 +20,7 @@ from nova.compute import rpcapi as compute_rpcapi
from nova import db
from nova import exception
from nova.image import glance
from nova.objects import base as obj_base
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log as logging
from nova.scheduler import rpcapi as scheduler_rpcapi
@@ -45,7 +46,7 @@ class LiveMigrationTask(object):
self.destination = destination
self.block_migration = block_migration
self.disk_over_commit = disk_over_commit
self.source = instance['host']
self.source = instance.host
self.migrate_data = None
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
self.servicegroup_api = servicegroup.API()
@@ -79,9 +80,9 @@ class LiveMigrationTask(object):
raise NotImplementedError()
def _check_instance_is_running(self):
if self.instance['power_state'] != power_state.RUNNING:
if self.instance.power_state != power_state.RUNNING:
raise exception.InstanceNotRunning(
instance_id=self.instance['uuid'])
instance_id=self.instance.uuid)
def _check_host_is_up(self, host):
try:
@@ -102,14 +103,14 @@ class LiveMigrationTask(object):
def _check_destination_is_not_source(self):
if self.destination == self.source:
raise exception.UnableToMigrateToSelf(
instance_id=self.instance['uuid'], host=self.destination)
instance_id=self.instance.uuid, host=self.destination)
def _check_destination_has_enough_memory(self):
avail = self._get_compute_info(self.destination)['free_ram_mb']
mem_inst = self.instance['memory_mb']
mem_inst = self.instance.memory_mb
if not mem_inst or avail <= mem_inst:
instance_uuid = self.instance['uuid']
instance_uuid = self.instance.uuid
dest = self.destination
reason = _("Unable to migrate %(instance_uuid)s to %(dest)s: "
"Lack of memory(host:%(avail)s <= "
@@ -145,9 +146,9 @@ class LiveMigrationTask(object):
#TODO(johngarbutt) this retry loop should be shared
attempted_hosts = [self.source]
image = None
if self.instance['image_ref']:
if self.instance.image_ref:
image = self.image_service.show(self.context,
self.instance['image_ref'])
self.instance.image_ref)
instance_type = flavors.extract_flavor(self.instance)
host = None
@@ -168,9 +169,10 @@ class LiveMigrationTask(object):
def _get_candidate_destination(self, image, instance_type,
attempted_hosts):
request_spec = {'instance_properties': self.instance,
instance_p = obj_base.obj_to_primitive(self.instance)
request_spec = {'instance_properties': instance_p,
'instance_type': instance_type,
'instance_uuids': [self.instance['uuid']]}
'instance_uuids': [self.instance.uuid]}
if image:
request_spec['image'] = image
filter_properties = {'ignore_hosts': attempted_hosts}
@@ -186,7 +188,7 @@ class LiveMigrationTask(object):
msg = (_('Exceeded max scheduling retries %(max_retries)d for '
'instance %(instance_uuid)s during live migration')
% {'max_retries': retries,
'instance_uuid': self.instance['uuid']})
'instance_uuid': self.instance.uuid})
raise exception.NoValidHost(reason=msg)