Make cells send Instance objects in build_instance()

This makes the cells rpcapi pass real objects through in the build_instances()
call.

Related to blueprint kilo-objects

Change-Id: I4a08274c34acedc58a2010a5f3093865bd1055d4
This commit is contained in:
Dan Smith 2014-12-03 12:26:15 -08:00
parent ebbb56e297
commit 1a1a8ca295
6 changed files with 49 additions and 23 deletions

View File

@ -33,6 +33,7 @@ from nova.i18n import _LW
from nova import manager
from nova import objects
from nova.objects import base as base_obj
from nova.objects import instance as instance_obj
from nova.openstack.common import log as logging
from nova.openstack.common import periodic_task
@ -73,7 +74,7 @@ class CellsManager(manager.Manager):
Scheduling requests get passed to the scheduler class.
"""
target = oslo_messaging.Target(version='1.31')
target = oslo_messaging.Target(version='1.32')
def __init__(self, *args, **kwargs):
LOG.warning(_LW('The cells feature of Nova is considered experimental '
@ -206,6 +207,13 @@ class CellsManager(manager.Manager):
flavor = objects.Flavor(**filter_properties['instance_type'])
build_inst_kwargs['filter_properties'] = dict(
filter_properties, instance_type=flavor)
instances = build_inst_kwargs['instances']
if not isinstance(instances[0], objects.Instance):
# NOTE(danms): Handle pre-1.32 build_instances() call. Remove me
# when we bump the RPC API version to 2.0
build_inst_kwargs['instances'] = instance_obj._make_instance_list(
ctxt, objects.InstanceList(), instances, ['system_metadata',
'metadata'])
our_cell = self.state_manager.get_my_state()
self.msg_runner.build_instances(ctxt, our_cell, build_inst_kwargs)

View File

@ -104,6 +104,7 @@ class CellsAPI(object):
* 1.30 - Make build_instances() use flavor object
* 1.31 - Add clean_shutdown to stop, resize, rescue, and shelve
* 1.32 - Send objects for instances in build_instances()
'''
VERSION_ALIASES = {
@ -149,18 +150,20 @@ class CellsAPI(object):
"""Build instances."""
build_inst_kwargs = kwargs
instances = build_inst_kwargs['instances']
instances_p = [jsonutils.to_primitive(inst) for inst in instances]
build_inst_kwargs['instances'] = instances_p
build_inst_kwargs['image'] = jsonutils.to_primitive(
build_inst_kwargs['image'])
version = '1.30'
if not self.client.can_send_version(version):
version = '1.8'
version = '1.32'
if not self.client.can_send_version('1.32'):
instances_p = [jsonutils.to_primitive(inst) for inst in instances]
build_inst_kwargs['instances'] = instances_p
version = '1.30'
if not self.client.can_send_version('1.30'):
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
version = '1.8'
cctxt = self.client.prepare(version=version)
cctxt.cast(ctxt, 'build_instances',
build_inst_kwargs=build_inst_kwargs)

View File

@ -167,7 +167,8 @@ class CellsScheduler(base.Base):
build_inst_kwargs):
"""Attempt to build instance(s) or send msg to child cell."""
ctxt = message.ctxt
instance_properties = build_inst_kwargs['instances'][0]
instance_properties = obj_base.obj_to_primitive(
build_inst_kwargs['instances'][0])
filter_properties = build_inst_kwargs['filter_properties']
instance_type = filter_properties['instance_type']
image = build_inst_kwargs['image']

View File

@ -28,6 +28,7 @@ from nova import context
from nova import objects
from nova import test
from nova.tests.unit.cells import fakes
from nova.tests.unit import fake_instance
from nova.tests.unit import fake_server_actions
from nova.tests.unit.objects import test_flavor
@ -116,7 +117,8 @@ class CellsManagerClassTestCase(test.NoDBTestCase):
self.cells_manager._update_our_parents(self.ctxt)
def test_build_instances(self):
build_inst_kwargs = {'instances': [1, 2]}
build_inst_kwargs = {'instances': [objects.Instance(),
objects.Instance()]}
self.mox.StubOutWithMock(self.msg_runner, 'build_instances')
our_cell = self.msg_runner.state_manager.get_my_state()
self.msg_runner.build_instances(self.ctxt, our_cell, build_inst_kwargs)
@ -126,7 +128,8 @@ class CellsManagerClassTestCase(test.NoDBTestCase):
def test_build_instances_old_flavor(self):
flavor_dict = test_flavor.fake_flavor
args = {'filter_properties': {'instance_type': flavor_dict}}
args = {'filter_properties': {'instance_type': flavor_dict},
'instances': [objects.Instance()]}
with mock.patch.object(self.msg_runner, 'build_instances') as mock_bi:
self.cells_manager.build_instances(self.ctxt,
build_inst_kwargs=args)
@ -134,6 +137,14 @@ class CellsManagerClassTestCase(test.NoDBTestCase):
self.assertIsInstance(filter_properties['instance_type'],
objects.Flavor)
def test_build_instances_old_instances(self):
args = {'instances': [fake_instance.fake_db_instance()]}
with mock.patch.object(self.msg_runner, 'build_instances') as mock_bi:
self.cells_manager.build_instances(self.ctxt,
build_inst_kwargs=args)
self.assertIsInstance(mock_bi.call_args[0][2]['instances'][0],
objects.Instance)
def test_run_compute_api_method(self):
# Args should just be silently passed through
cell_name = 'fake-cell-name'

View File

@ -21,6 +21,7 @@ import six
from nova.cells import rpcapi as cells_rpcapi
from nova import exception
from nova import objects
from nova import test
from nova.tests.unit import fake_instance
@ -125,17 +126,20 @@ class CellsAPITestCase(test.NoDBTestCase):
def test_build_instances(self):
call_info = self._stub_rpc_method('cast', None)
instances = [objects.Instance(id=1),
objects.Instance(id=2)]
self.cells_rpcapi.build_instances(
self.fake_context, instances=['1', '2'],
self.fake_context, instances=instances,
image={'fake': 'image'}, arg1=1, arg2=2, arg3=3)
expected_args = {'build_inst_kwargs': {'instances': ['1', '2'],
expected_args = {'build_inst_kwargs': {'instances': instances,
'image': {'fake': 'image'},
'arg1': 1,
'arg2': 2,
'arg3': 3}}
self._check_result(call_info, 'build_instances',
expected_args, version='1.30')
expected_args, version='1.32')
def test_get_capacities(self):
capacity_info = {"capacity": "info"}

View File

@ -27,11 +27,11 @@ from nova.compute import vm_states
from nova import context
from nova import db
from nova import exception
from nova import objects
from nova.openstack.common import uuidutils
from nova.scheduler import utils as scheduler_utils
from nova import test
from nova.tests.unit.cells import fakes
from nova.tests.unit import fake_instance
from nova import utils
CONF = cfg.CONF
@ -80,7 +80,8 @@ class CellsSchedulerTestCase(test.TestCase):
for x in xrange(3):
instance_uuids.append(uuidutils.generate_uuid())
self.instance_uuids = instance_uuids
self.instances = [{'uuid': uuid} for uuid in instance_uuids]
self.instances = [objects.Instance(uuid=uuid, id=id)
for id, uuid in enumerate(instance_uuids)]
self.request_spec = {
'instance_uuids': instance_uuids,
'instance_properties': self.instances[0],
@ -197,9 +198,7 @@ class CellsSchedulerTestCase(test.TestCase):
call_info['image'] = image
call_info['security_groups'] = security_groups
call_info['block_device_mapping'] = block_device_mapping
instances = [fake_instance.fake_instance_obj(ctxt, **instance)
for instance in self.instances]
return instances
return self.instances
def fake_rpc_build_instances(ctxt, **build_inst_kwargs):
call_info['build_inst_kwargs'] = build_inst_kwargs
@ -222,8 +221,8 @@ class CellsSchedulerTestCase(test.TestCase):
self.assertEqual(self.ctxt, call_info['ctxt'])
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
self.assertEqual(self.build_inst_kwargs['instances'][0],
call_info['instance_properties'])
self.assertEqual(self.build_inst_kwargs['instances'][0]['id'],
call_info['instance_properties']['id'])
self.assertEqual(
self.build_inst_kwargs['filter_properties']['instance_type'],
call_info['instance_type'])
@ -398,8 +397,8 @@ class CellsSchedulerTestCase(test.TestCase):
# Our cell was selected.
self.assertEqual(self.ctxt, call_info['ctxt'])
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
self.assertEqual(self.request_spec['instance_properties'],
call_info['instance_properties'])
self.assertEqual(self.request_spec['instance_properties']['id'],
call_info['instance_properties']['id'])
self.assertEqual(self.request_spec['instance_type'],
call_info['instance_type'])
self.assertEqual(self.request_spec['image'], call_info['image'])
@ -513,8 +512,8 @@ class CellsSchedulerTestCase(test.TestCase):
# Our cell was selected.
self.assertEqual(self.ctxt, call_info['ctxt'])
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
self.assertEqual(self.request_spec['instance_properties'],
call_info['instance_properties'])
self.assertEqual(self.request_spec['instance_properties']['id'],
call_info['instance_properties']['id'])
self.assertEqual(self.request_spec['instance_type'],
call_info['instance_type'])
self.assertEqual(self.request_spec['image'], call_info['image'])