Merge "object-ify flavors manager side of the RPC"

This commit is contained in:
Jenkins 2014-12-05 13:40:42 +00:00 committed by Gerrit Code Review
commit 16d38947ae
12 changed files with 88 additions and 44 deletions

View File

@ -73,7 +73,7 @@ class CellsManager(manager.Manager):
Scheduling requests get passed to the scheduler class.
"""
target = oslo_messaging.Target(version='1.29')
target = oslo_messaging.Target(version='1.30')
def __init__(self, *args, **kwargs):
LOG.warning(_LW('The cells feature of Nova is considered experimental '

View File

@ -101,6 +101,8 @@ class CellsAPI(object):
... Juno supports message version 1.29. So, any changes to
existing methods in 1.x after that point should be done such that they
can handle the version_cap being set to 1.29.
* 1.30 - Make build_instances() use flavor object
'''
VERSION_ALIASES = {
@ -150,11 +152,15 @@ class CellsAPI(object):
build_inst_kwargs['instances'] = instances_p
build_inst_kwargs['image'] = jsonutils.to_primitive(
build_inst_kwargs['image'])
if 'filter_properties' in build_inst_kwargs:
flavor = build_inst_kwargs['filter_properties']['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
build_inst_kwargs['filter_properties']['instance_type'] = flavor_p
cctxt = self.client.prepare(version='1.8')
version = '1.30'
if not self.client.can_send_version(version):
version = '1.8'
if 'filter_properties' in build_inst_kwargs:
filter_properties = build_inst_kwargs['filter_properties']
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties['instance_type'] = flavor_p
cctxt = self.client.prepare(version=version)
cctxt.cast(ctxt, 'build_instances',
build_inst_kwargs=build_inst_kwargs)

View File

@ -587,7 +587,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
class ComputeManager(manager.Manager):
"""Manages the running instances from creation to destruction."""
target = messaging.Target(version='3.35')
target = messaging.Target(version='3.36')
# How long to wait in seconds before re-issuing a shutdown
# signal to a instance during power off. The overall
@ -1994,6 +1994,13 @@ class ComputeManager(manager.Manager):
requested_networks = objects.NetworkRequestList(
objects=[objects.NetworkRequest.from_tuple(t)
for t in requested_networks])
# NOTE(melwitt): Remove this in v4.0 of the RPC API
flavor = filter_properties.get('instance_type')
if flavor and not isinstance(flavor, objects.Flavor):
# Code downstream may expect extra_specs to be populated since it
# is receiving an object, so lookup the flavor to ensure this.
flavor = objects.Flavor.get_by_id(context, flavor['id'])
filter_properties = dict(filter_properties, instance_type=flavor)
@utils.synchronized(instance.uuid)
def _locked_do_build_and_run_instance(*args, **kwargs):

View File

@ -274,6 +274,8 @@ class ComputeAPI(object):
... Juno supports message version 3.35. So, any changes to
existing methods in 3.x after that point should be done such that they
can handle the version_cap being set to 3.35.
* 3.36 - Make build_and_run_instance() send a Flavor object
'''
VERSION_ALIASES = {
@ -880,17 +882,20 @@ class ComputeAPI(object):
filter_properties, admin_password=None, injected_files=None,
requested_networks=None, security_groups=None,
block_device_mapping=None, node=None, limits=None):
version = '3.33'
version = '3.36'
if not self.client.can_send_version(version):
version = '3.33'
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties,
instance_type=flavor_p)
if not self.client.can_send_version(version):
version = '3.23'
if requested_networks is not None:
requested_networks = [(network_id, address, port_id)
for (network_id, address, port_id, _) in
requested_networks.as_tuples()]
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties, instance_type=flavor_p)
cctxt = self.client.prepare(server=host, version=version)
cctxt.cast(ctxt, 'build_and_run_instance', instance=instance,

View File

@ -461,7 +461,7 @@ class ComputeTaskManager(base.Base):
may involve coordinating activities on multiple compute nodes.
"""
target = messaging.Target(namespace='compute_task', version='1.9')
target = messaging.Target(namespace='compute_task', version='1.10')
def __init__(self):
super(ComputeTaskManager, self).__init__()
@ -491,6 +491,11 @@ class ComputeTaskManager(base.Base):
instance = objects.Instance._from_db_object(
context, objects.Instance(), instance,
expected_attrs=attrs)
# NOTE(melwitt): Remove this in version 2.0 of the RPC API
if flavor and not isinstance(flavor, objects.Flavor):
# Code downstream may expect extra_specs to be populated since it
# is receiving an object, so lookup the flavor to ensure this.
flavor = objects.Flavor.get_by_id(context, flavor['id'])
if live and not rebuild and not flavor:
self._live_migrate(context, instance, scheduler_hint,
block_migration, disk_over_commit)
@ -545,11 +550,6 @@ class ComputeTaskManager(base.Base):
# context is not serializable
filter_properties.pop('context', None)
# TODO(timello): originally, instance_type in request_spec
# on compute.api.resize does not have 'extra_specs', so we
# remove it for now to keep tests backward compatibility.
request_spec['instance_type'].pop('extra_specs', None)
(host, node) = (host_state['host'], host_state['nodename'])
self.compute_rpcapi.prep_resize(
context, image, instance,
@ -622,6 +622,13 @@ class ComputeTaskManager(base.Base):
requested_networks = objects.NetworkRequestList(
objects=[objects.NetworkRequest.from_tuple(t)
for t in requested_networks])
# TODO(melwitt): Remove this in version 2.0 of the RPC API
flavor = filter_properties.get('instance_type')
if flavor and not isinstance(flavor, objects.Flavor):
# Code downstream may expect extra_specs to be populated since it
# is receiving an object, so lookup the flavor to ensure this.
flavor = objects.Flavor.get_by_id(context, flavor['id'])
filter_properties = dict(filter_properties, instance_type=flavor)
try:
# check retry policy. Rather ugly use of instances[0]...

View File

@ -390,6 +390,7 @@ class ComputeTaskAPI(object):
1.7 - Do not send block_device_mapping and legacy_bdm to build_instances
1.8 - Add rebuild_instance
1.9 - Converted requested_networks to NetworkRequestList object
1.10 - Made migrate_server() and build_instances() send flavor objects
"""
@ -404,17 +405,18 @@ class ComputeTaskAPI(object):
def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
flavor, block_migration, disk_over_commit,
reservations=None):
if self.client.can_send_version('1.6'):
version = '1.10'
if not self.client.can_send_version(version):
flavor = objects_base.obj_to_primitive(flavor)
version = '1.6'
else:
if not self.client.can_send_version(version):
instance = jsonutils.to_primitive(
objects_base.obj_to_primitive(instance))
version = '1.4'
flavor_p = jsonutils.to_primitive(flavor)
cctxt = self.client.prepare(version=version)
return cctxt.call(context, 'migrate_server',
instance=instance, scheduler_hint=scheduler_hint,
live=live, rebuild=rebuild, flavor=flavor_p,
live=live, rebuild=rebuild, flavor=flavor,
block_migration=block_migration,
disk_over_commit=disk_over_commit,
reservations=reservations)
@ -423,19 +425,21 @@ class ComputeTaskAPI(object):
admin_password, injected_files, requested_networks,
security_groups, block_device_mapping, legacy_bdm=True):
image_p = jsonutils.to_primitive(image)
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties, instance_type=flavor_p)
version = '1.10'
if not self.client.can_send_version(version):
version = '1.9'
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties,
instance_type=flavor_p)
kw = {'instances': instances, 'image': image_p,
'filter_properties': filter_properties,
'admin_password': admin_password,
'injected_files': injected_files,
'requested_networks': requested_networks,
'security_groups': security_groups}
version = '1.9'
if not self.client.can_send_version('1.9'):
if not self.client.can_send_version(version):
version = '1.8'
kw['requested_networks'] = kw['requested_networks'].as_tuples()
if not self.client.can_send_version('1.7'):

View File

@ -60,7 +60,7 @@ QUOTAS = quota.QUOTAS
class SchedulerManager(manager.Manager):
"""Chooses a host to run instances on."""
target = messaging.Target(version='3.0')
target = messaging.Target(version='3.1')
def __init__(self, scheduler_driver=None, *args, **kwargs):
if not scheduler_driver:
@ -171,6 +171,13 @@ class SchedulerManager(manager.Manager):
The result should be a list of dicts with 'host', 'nodename' and
'limits' as keys.
"""
# TODO(melwitt): Remove this in version 4.0 of the RPC API
flavor = filter_properties.get('instance_type')
if flavor and not isinstance(flavor, objects.Flavor):
# Code downstream may expect extra_specs to be populated since it
# is receiving an object, so lookup the flavor to ensure this.
flavor = objects.Flavor.get_by_id(context, flavor['id'])
filter_properties = dict(filter_properties, instance_type=flavor)
dests = self.driver.select_destinations(context, request_spec,
filter_properties)
return jsonutils.to_primitive(dests)

View File

@ -84,6 +84,8 @@ class SchedulerAPI(object):
existing methods in 3.x after that point should be done such that they
can handle the version_cap being set to 3.0.
* 3.1 - Made select_destinations() send flavor object
'''
VERSION_ALIASES = {
@ -103,10 +105,14 @@ class SchedulerAPI(object):
serializer=serializer)
def select_destinations(self, ctxt, request_spec, filter_properties):
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties, instance_type=flavor_p)
cctxt = self.client.prepare()
version = '3.1'
if not self.client.can_send_version(version):
version = '3.0'
if 'instance_type' in filter_properties:
flavor = filter_properties['instance_type']
flavor_p = objects_base.obj_to_primitive(flavor)
filter_properties = dict(filter_properties,
instance_type=flavor_p)
cctxt = self.client.prepare(version=version)
return cctxt.call(ctxt, 'select_destinations',
request_spec=request_spec, filter_properties=filter_properties)

View File

@ -135,7 +135,7 @@ class CellsAPITestCase(test.NoDBTestCase):
'arg2': 2,
'arg3': 3}}
self._check_result(call_info, 'build_instances',
expected_args, version='1.8')
expected_args, version='1.30')
def test_get_capacities(self):
capacity_info = {"capacity": "info"}

View File

@ -468,7 +468,7 @@ class ComputeRpcAPITestCase(test.TestCase):
admin_password='passwd', injected_files=None,
requested_networks=['network1'], security_groups=None,
block_device_mapping=None, node='node', limits=[],
version='3.33')
version='3.36')
@mock.patch('nova.utils.is_neutron', return_value=True)
def test_build_and_run_instance_icehouse_compat(self, is_neutron):

View File

@ -1196,9 +1196,9 @@ class _BaseTaskTestCase(object):
inst = fake_instance.fake_db_instance(image_ref='image_ref')
inst_obj = objects.Instance._from_db_object(
self.context, objects.Instance(), inst, [])
flavor = obj_base.obj_to_primitive(flavors.get_default_flavor())
flavor['extra_specs'] = 'extra_specs'
request_spec = {'instance_type': flavor,
flavor = flavors.get_default_flavor()
flavor.extra_specs = {'extra_specs': 'fake'}
request_spec = {'instance_type': obj_base.obj_to_primitive(flavor),
'instance_properties': {}}
compute_utils.get_image_metadata(
self.context, self.conductor_manager.image_api,
@ -1207,7 +1207,7 @@ class _BaseTaskTestCase(object):
scheduler_utils.build_request_spec(
self.context, 'image',
[mox.IsA(objects.Instance)],
instance_type=flavor).AndReturn(request_spec)
instance_type=mox.IsA(objects.Flavor)).AndReturn(request_spec)
scheduler_utils.setup_instance_group(self.context, request_spec, {})
@ -1222,7 +1222,7 @@ class _BaseTaskTestCase(object):
self.conductor_manager.compute_rpcapi.prep_resize(
self.context, 'image', mox.IsA(objects.Instance),
mox.IsA(dict), 'host1', [], request_spec=request_spec,
mox.IsA(objects.Flavor), 'host1', [], request_spec=request_spec,
filter_properties=filter_properties, node=None)
self.mox.ReplayAll()
@ -1630,8 +1630,9 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
self.context, None, None, True, True, None, None, None)
def test_migrate_server_fails_with_flavor(self):
flavor = flavors.get_flavor_by_name('m1.tiny')
self.assertRaises(NotImplementedError, self.conductor.migrate_server,
self.context, None, None, True, False, "dummy", None, None)
self.context, None, None, True, False, flavor, None, None)
def _build_request_spec(self, instance):
return {

View File

@ -66,4 +66,5 @@ class SchedulerRpcAPITestCase(test.NoDBTestCase):
def test_select_destinations(self):
self._test_scheduler_api('select_destinations', rpc_method='call',
request_spec='fake_request_spec',
filter_properties='fake_prop')
filter_properties='fake_prop',
version='3.1')