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:
parent
ebbb56e297
commit
1a1a8ca295
@ -33,6 +33,7 @@ from nova.i18n import _LW
|
|||||||
from nova import manager
|
from nova import manager
|
||||||
from nova import objects
|
from nova import objects
|
||||||
from nova.objects import base as base_obj
|
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 log as logging
|
||||||
from nova.openstack.common import periodic_task
|
from nova.openstack.common import periodic_task
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ class CellsManager(manager.Manager):
|
|||||||
Scheduling requests get passed to the scheduler class.
|
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):
|
def __init__(self, *args, **kwargs):
|
||||||
LOG.warning(_LW('The cells feature of Nova is considered experimental '
|
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'])
|
flavor = objects.Flavor(**filter_properties['instance_type'])
|
||||||
build_inst_kwargs['filter_properties'] = dict(
|
build_inst_kwargs['filter_properties'] = dict(
|
||||||
filter_properties, instance_type=flavor)
|
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()
|
our_cell = self.state_manager.get_my_state()
|
||||||
self.msg_runner.build_instances(ctxt, our_cell, build_inst_kwargs)
|
self.msg_runner.build_instances(ctxt, our_cell, build_inst_kwargs)
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ class CellsAPI(object):
|
|||||||
|
|
||||||
* 1.30 - Make build_instances() use flavor object
|
* 1.30 - Make build_instances() use flavor object
|
||||||
* 1.31 - Add clean_shutdown to stop, resize, rescue, and shelve
|
* 1.31 - Add clean_shutdown to stop, resize, rescue, and shelve
|
||||||
|
* 1.32 - Send objects for instances in build_instances()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
VERSION_ALIASES = {
|
VERSION_ALIASES = {
|
||||||
@ -149,18 +150,20 @@ class CellsAPI(object):
|
|||||||
"""Build instances."""
|
"""Build instances."""
|
||||||
build_inst_kwargs = kwargs
|
build_inst_kwargs = kwargs
|
||||||
instances = build_inst_kwargs['instances']
|
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'] = jsonutils.to_primitive(
|
||||||
build_inst_kwargs['image'])
|
build_inst_kwargs['image'])
|
||||||
|
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'
|
version = '1.30'
|
||||||
if not self.client.can_send_version(version):
|
if not self.client.can_send_version('1.30'):
|
||||||
version = '1.8'
|
|
||||||
if 'filter_properties' in build_inst_kwargs:
|
if 'filter_properties' in build_inst_kwargs:
|
||||||
filter_properties = build_inst_kwargs['filter_properties']
|
filter_properties = build_inst_kwargs['filter_properties']
|
||||||
flavor = filter_properties['instance_type']
|
flavor = filter_properties['instance_type']
|
||||||
flavor_p = objects_base.obj_to_primitive(flavor)
|
flavor_p = objects_base.obj_to_primitive(flavor)
|
||||||
filter_properties['instance_type'] = flavor_p
|
filter_properties['instance_type'] = flavor_p
|
||||||
|
version = '1.8'
|
||||||
cctxt = self.client.prepare(version=version)
|
cctxt = self.client.prepare(version=version)
|
||||||
cctxt.cast(ctxt, 'build_instances',
|
cctxt.cast(ctxt, 'build_instances',
|
||||||
build_inst_kwargs=build_inst_kwargs)
|
build_inst_kwargs=build_inst_kwargs)
|
||||||
|
@ -167,7 +167,8 @@ class CellsScheduler(base.Base):
|
|||||||
build_inst_kwargs):
|
build_inst_kwargs):
|
||||||
"""Attempt to build instance(s) or send msg to child cell."""
|
"""Attempt to build instance(s) or send msg to child cell."""
|
||||||
ctxt = message.ctxt
|
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']
|
filter_properties = build_inst_kwargs['filter_properties']
|
||||||
instance_type = filter_properties['instance_type']
|
instance_type = filter_properties['instance_type']
|
||||||
image = build_inst_kwargs['image']
|
image = build_inst_kwargs['image']
|
||||||
|
@ -28,6 +28,7 @@ from nova import context
|
|||||||
from nova import objects
|
from nova import objects
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.unit.cells import fakes
|
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 import fake_server_actions
|
||||||
from nova.tests.unit.objects import test_flavor
|
from nova.tests.unit.objects import test_flavor
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ class CellsManagerClassTestCase(test.NoDBTestCase):
|
|||||||
self.cells_manager._update_our_parents(self.ctxt)
|
self.cells_manager._update_our_parents(self.ctxt)
|
||||||
|
|
||||||
def test_build_instances(self):
|
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')
|
self.mox.StubOutWithMock(self.msg_runner, 'build_instances')
|
||||||
our_cell = self.msg_runner.state_manager.get_my_state()
|
our_cell = self.msg_runner.state_manager.get_my_state()
|
||||||
self.msg_runner.build_instances(self.ctxt, our_cell, build_inst_kwargs)
|
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):
|
def test_build_instances_old_flavor(self):
|
||||||
flavor_dict = test_flavor.fake_flavor
|
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:
|
with mock.patch.object(self.msg_runner, 'build_instances') as mock_bi:
|
||||||
self.cells_manager.build_instances(self.ctxt,
|
self.cells_manager.build_instances(self.ctxt,
|
||||||
build_inst_kwargs=args)
|
build_inst_kwargs=args)
|
||||||
@ -134,6 +137,14 @@ class CellsManagerClassTestCase(test.NoDBTestCase):
|
|||||||
self.assertIsInstance(filter_properties['instance_type'],
|
self.assertIsInstance(filter_properties['instance_type'],
|
||||||
objects.Flavor)
|
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):
|
def test_run_compute_api_method(self):
|
||||||
# Args should just be silently passed through
|
# Args should just be silently passed through
|
||||||
cell_name = 'fake-cell-name'
|
cell_name = 'fake-cell-name'
|
||||||
|
@ -21,6 +21,7 @@ import six
|
|||||||
|
|
||||||
from nova.cells import rpcapi as cells_rpcapi
|
from nova.cells import rpcapi as cells_rpcapi
|
||||||
from nova import exception
|
from nova import exception
|
||||||
|
from nova import objects
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.unit import fake_instance
|
from nova.tests.unit import fake_instance
|
||||||
|
|
||||||
@ -125,17 +126,20 @@ class CellsAPITestCase(test.NoDBTestCase):
|
|||||||
def test_build_instances(self):
|
def test_build_instances(self):
|
||||||
call_info = self._stub_rpc_method('cast', None)
|
call_info = self._stub_rpc_method('cast', None)
|
||||||
|
|
||||||
|
instances = [objects.Instance(id=1),
|
||||||
|
objects.Instance(id=2)]
|
||||||
|
|
||||||
self.cells_rpcapi.build_instances(
|
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)
|
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'},
|
'image': {'fake': 'image'},
|
||||||
'arg1': 1,
|
'arg1': 1,
|
||||||
'arg2': 2,
|
'arg2': 2,
|
||||||
'arg3': 3}}
|
'arg3': 3}}
|
||||||
self._check_result(call_info, 'build_instances',
|
self._check_result(call_info, 'build_instances',
|
||||||
expected_args, version='1.30')
|
expected_args, version='1.32')
|
||||||
|
|
||||||
def test_get_capacities(self):
|
def test_get_capacities(self):
|
||||||
capacity_info = {"capacity": "info"}
|
capacity_info = {"capacity": "info"}
|
||||||
|
@ -27,11 +27,11 @@ from nova.compute import vm_states
|
|||||||
from nova import context
|
from nova import context
|
||||||
from nova import db
|
from nova import db
|
||||||
from nova import exception
|
from nova import exception
|
||||||
|
from nova import objects
|
||||||
from nova.openstack.common import uuidutils
|
from nova.openstack.common import uuidutils
|
||||||
from nova.scheduler import utils as scheduler_utils
|
from nova.scheduler import utils as scheduler_utils
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.unit.cells import fakes
|
from nova.tests.unit.cells import fakes
|
||||||
from nova.tests.unit import fake_instance
|
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -80,7 +80,8 @@ class CellsSchedulerTestCase(test.TestCase):
|
|||||||
for x in xrange(3):
|
for x in xrange(3):
|
||||||
instance_uuids.append(uuidutils.generate_uuid())
|
instance_uuids.append(uuidutils.generate_uuid())
|
||||||
self.instance_uuids = instance_uuids
|
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 = {
|
self.request_spec = {
|
||||||
'instance_uuids': instance_uuids,
|
'instance_uuids': instance_uuids,
|
||||||
'instance_properties': self.instances[0],
|
'instance_properties': self.instances[0],
|
||||||
@ -197,9 +198,7 @@ class CellsSchedulerTestCase(test.TestCase):
|
|||||||
call_info['image'] = image
|
call_info['image'] = image
|
||||||
call_info['security_groups'] = security_groups
|
call_info['security_groups'] = security_groups
|
||||||
call_info['block_device_mapping'] = block_device_mapping
|
call_info['block_device_mapping'] = block_device_mapping
|
||||||
instances = [fake_instance.fake_instance_obj(ctxt, **instance)
|
return self.instances
|
||||||
for instance in self.instances]
|
|
||||||
return instances
|
|
||||||
|
|
||||||
def fake_rpc_build_instances(ctxt, **build_inst_kwargs):
|
def fake_rpc_build_instances(ctxt, **build_inst_kwargs):
|
||||||
call_info['build_inst_kwargs'] = 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.ctxt, call_info['ctxt'])
|
||||||
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
||||||
self.assertEqual(self.build_inst_kwargs['instances'][0],
|
self.assertEqual(self.build_inst_kwargs['instances'][0]['id'],
|
||||||
call_info['instance_properties'])
|
call_info['instance_properties']['id'])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.build_inst_kwargs['filter_properties']['instance_type'],
|
self.build_inst_kwargs['filter_properties']['instance_type'],
|
||||||
call_info['instance_type'])
|
call_info['instance_type'])
|
||||||
@ -398,8 +397,8 @@ class CellsSchedulerTestCase(test.TestCase):
|
|||||||
# Our cell was selected.
|
# Our cell was selected.
|
||||||
self.assertEqual(self.ctxt, call_info['ctxt'])
|
self.assertEqual(self.ctxt, call_info['ctxt'])
|
||||||
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
||||||
self.assertEqual(self.request_spec['instance_properties'],
|
self.assertEqual(self.request_spec['instance_properties']['id'],
|
||||||
call_info['instance_properties'])
|
call_info['instance_properties']['id'])
|
||||||
self.assertEqual(self.request_spec['instance_type'],
|
self.assertEqual(self.request_spec['instance_type'],
|
||||||
call_info['instance_type'])
|
call_info['instance_type'])
|
||||||
self.assertEqual(self.request_spec['image'], call_info['image'])
|
self.assertEqual(self.request_spec['image'], call_info['image'])
|
||||||
@ -513,8 +512,8 @@ class CellsSchedulerTestCase(test.TestCase):
|
|||||||
# Our cell was selected.
|
# Our cell was selected.
|
||||||
self.assertEqual(self.ctxt, call_info['ctxt'])
|
self.assertEqual(self.ctxt, call_info['ctxt'])
|
||||||
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
self.assertEqual(self.instance_uuids, call_info['instance_uuids'])
|
||||||
self.assertEqual(self.request_spec['instance_properties'],
|
self.assertEqual(self.request_spec['instance_properties']['id'],
|
||||||
call_info['instance_properties'])
|
call_info['instance_properties']['id'])
|
||||||
self.assertEqual(self.request_spec['instance_type'],
|
self.assertEqual(self.request_spec['instance_type'],
|
||||||
call_info['instance_type'])
|
call_info['instance_type'])
|
||||||
self.assertEqual(self.request_spec['image'], call_info['image'])
|
self.assertEqual(self.request_spec['image'], call_info['image'])
|
||||||
|
Loading…
Reference in New Issue
Block a user