Make resize api of compute manager to send flavor object
This code change implements the conversion of flavor to use object. Rpcapi of compute manager sends objects for new version and sents primitivized data for older versions. Related to blueprint liberty-objects Change-Id: I11a28cd3b2eb98b42d78f9327ed6b38dc2bc8f30
This commit is contained in:
parent
e1613d1bbe
commit
5bd81ab5fb
@ -644,7 +644,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
|
||||
class ComputeManager(manager.Manager):
|
||||
"""Manages the running instances from creation to destruction."""
|
||||
|
||||
target = messaging.Target(version='4.0')
|
||||
target = messaging.Target(version='4.1')
|
||||
|
||||
# How long to wait in seconds before re-issuing a shutdown
|
||||
# signal to a instance during power off. The overall
|
||||
@ -3473,7 +3473,7 @@ class ComputeManager(manager.Manager):
|
||||
|
||||
same_host = instance.host == self.host
|
||||
# if the flavor IDs match, it's migrate; otherwise resize
|
||||
if same_host and instance_type['id'] == instance['instance_type_id']:
|
||||
if same_host and instance_type.id == instance['instance_type_id']:
|
||||
# check driver whether support migrate to same host
|
||||
if not self.driver.capabilities['supports_migrate_to_same_host']:
|
||||
raise exception.UnableToMigrateToSelf(
|
||||
@ -3547,8 +3547,8 @@ class ComputeManager(manager.Manager):
|
||||
filter_properties)
|
||||
finally:
|
||||
extra_usage_info = dict(
|
||||
new_instance_type=instance_type['name'],
|
||||
new_instance_type_id=instance_type['id'])
|
||||
new_instance_type=instance_type.name,
|
||||
new_instance_type_id=instance_type.id)
|
||||
|
||||
self._notify_about_instance_usage(
|
||||
context, instance, "resize.prep.end",
|
||||
@ -3612,6 +3612,7 @@ class ComputeManager(manager.Manager):
|
||||
instance=instance)
|
||||
with self._error_out_instance_on_exception(context, instance,
|
||||
quotas=quotas):
|
||||
# TODO(chaochin) Remove this until v5 RPC API
|
||||
# Code downstream may expect extra_specs to be populated since it
|
||||
# is receiving an object, so lookup the flavor to ensure this.
|
||||
if (not instance_type or
|
||||
|
@ -297,6 +297,7 @@ class ComputeAPI(object):
|
||||
3.x for Juno compatibility. All new changes should go against 4.x.
|
||||
|
||||
* 4.0 - Remove 3.x compatibility
|
||||
* 4.1 - Make prep_resize() and resize_instance() send Flavor object
|
||||
'''
|
||||
|
||||
VERSION_ALIASES = {
|
||||
@ -563,18 +564,20 @@ class ComputeAPI(object):
|
||||
reservations=None, request_spec=None,
|
||||
filter_properties=None, node=None,
|
||||
clean_shutdown=True):
|
||||
# TODO(danms): This needs to be fixed for objects!
|
||||
instance_type_p = jsonutils.to_primitive(instance_type)
|
||||
image_p = jsonutils.to_primitive(image)
|
||||
msg_args = {'instance': instance,
|
||||
'instance_type': instance_type_p,
|
||||
'instance_type': instance_type,
|
||||
'image': image_p,
|
||||
'reservations': reservations,
|
||||
'request_spec': request_spec,
|
||||
'filter_properties': filter_properties,
|
||||
'node': node,
|
||||
'clean_shutdown': clean_shutdown}
|
||||
version = '4.0'
|
||||
version = '4.1'
|
||||
if not self.client.can_send_version(version):
|
||||
version = '4.0'
|
||||
msg_args['instance_type'] = objects_base.obj_to_primitive(
|
||||
instance_type)
|
||||
cctxt = self.client.prepare(server=host, version=version)
|
||||
cctxt.cast(ctxt, 'prep_resize', **msg_args)
|
||||
|
||||
@ -660,14 +663,16 @@ class ComputeAPI(object):
|
||||
|
||||
def resize_instance(self, ctxt, instance, migration, image, instance_type,
|
||||
reservations=None, clean_shutdown=True):
|
||||
# TODO(danms): This needs to be fixed for objects!
|
||||
instance_type_p = jsonutils.to_primitive(instance_type)
|
||||
msg_args = {'instance': instance, 'migration': migration,
|
||||
'image': image, 'reservations': reservations,
|
||||
'instance_type': instance_type_p,
|
||||
'instance_type': instance_type,
|
||||
'clean_shutdown': clean_shutdown,
|
||||
}
|
||||
version = '4.0'
|
||||
version = '4.1'
|
||||
if not self.client.can_send_version(version):
|
||||
msg_args['instance_type'] = objects_base.obj_to_primitive(
|
||||
instance_type)
|
||||
version = '4.0'
|
||||
cctxt = self.client.prepare(server=_compute_host(None, instance),
|
||||
version=version)
|
||||
cctxt.cast(ctxt, 'resize_instance', **msg_args)
|
||||
|
@ -4759,7 +4759,6 @@ class ComputeTestCase(BaseTestCase):
|
||||
timeutils.set_time_override(old_time)
|
||||
instance = self._create_fake_instance_obj()
|
||||
new_type = flavors.get_flavor_by_name('m1.small')
|
||||
new_type = jsonutils.to_primitive(new_type)
|
||||
new_type_id = new_type['id']
|
||||
flavor_id = new_type['flavorid']
|
||||
self.compute.build_and_run_instance(self.context, instance, {}, {}, {},
|
||||
@ -5093,12 +5092,10 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance.power_state = p_state
|
||||
instance.save()
|
||||
|
||||
new_instance_type_ref = db.flavor_get_by_flavor_id(
|
||||
self.context, 3)
|
||||
new_instance_type_p = jsonutils.to_primitive(new_instance_type_ref)
|
||||
new_instance_type_ref = flavors.get_flavor_by_flavor_id(3)
|
||||
self.compute.prep_resize(self.context,
|
||||
instance=instance,
|
||||
instance_type=new_instance_type_p,
|
||||
instance_type=new_instance_type_ref,
|
||||
image={}, reservations=reservations, request_spec={},
|
||||
filter_properties={}, node=None, clean_shutdown=True)
|
||||
|
||||
@ -5115,7 +5112,7 @@ class ComputeTestCase(BaseTestCase):
|
||||
migration=migration,
|
||||
image={},
|
||||
reservations=[],
|
||||
instance_type=new_instance_type_p,
|
||||
instance_type=new_instance_type_ref,
|
||||
clean_shutdown=True)
|
||||
self.compute.finish_resize(self.context,
|
||||
migration=migration, reservations=[],
|
||||
@ -5198,12 +5195,10 @@ class ComputeTestCase(BaseTestCase):
|
||||
instance.vm_state = old_vm_state
|
||||
instance.save()
|
||||
|
||||
new_instance_type_ref = db.flavor_get_by_flavor_id(
|
||||
self.context, 3)
|
||||
new_instance_type_p = jsonutils.to_primitive(new_instance_type_ref)
|
||||
new_instance_type_ref = flavors.get_flavor_by_flavor_id(3)
|
||||
self.compute.prep_resize(self.context,
|
||||
instance=instance,
|
||||
instance_type=new_instance_type_p,
|
||||
instance_type=new_instance_type_ref,
|
||||
image={}, reservations=reservations, request_spec={},
|
||||
filter_properties={}, node=None,
|
||||
clean_shutdown=True)
|
||||
@ -5221,15 +5216,14 @@ class ComputeTestCase(BaseTestCase):
|
||||
migration=migration,
|
||||
image={},
|
||||
reservations=[],
|
||||
instance_type=new_instance_type_p,
|
||||
instance_type=new_instance_type_ref,
|
||||
clean_shutdown=True)
|
||||
self.compute.finish_resize(self.context,
|
||||
migration=migration, reservations=[],
|
||||
disk_info={}, image={}, instance=instance)
|
||||
|
||||
# Prove that the instance size is now the new size
|
||||
instance_type_ref = db.flavor_get(self.context,
|
||||
instance['instance_type_id'])
|
||||
instance_type_ref = flavors.get_flavor_by_flavor_id(3)
|
||||
self.assertEqual(instance_type_ref['flavorid'], '3')
|
||||
|
||||
instance.task_state = task_states.RESIZE_REVERTING
|
||||
|
@ -27,6 +27,7 @@ from nova import context
|
||||
from nova.objects import block_device as objects_block_dev
|
||||
from nova import test
|
||||
from nova.tests.unit import fake_block_device
|
||||
from nova.tests.unit import fake_flavor
|
||||
from nova.tests.unit import fake_instance
|
||||
|
||||
CONF = cfg.CONF
|
||||
@ -37,10 +38,14 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(ComputeRpcAPITestCase, self).setUp()
|
||||
self.context = context.get_admin_context()
|
||||
self.fake_flavor_obj = fake_flavor.fake_flavor_obj(self.context)
|
||||
self.fake_flavor = jsonutils.to_primitive(self.fake_flavor_obj)
|
||||
instance_attr = {'host': 'fake_host',
|
||||
'instance_type_id': 1}
|
||||
'instance_type_id': self.fake_flavor_obj['id'],
|
||||
'instance_type': self.fake_flavor_obj}
|
||||
self.fake_instance_obj = fake_instance.fake_instance_obj(self.context,
|
||||
**instance_attr)
|
||||
self.fake_instance = jsonutils.to_primitive(self.fake_instance_obj)
|
||||
self.fake_volume_bdm = objects_block_dev.BlockDeviceMapping(
|
||||
**fake_block_device.FakeDbBlockDeviceDict(
|
||||
{'source_type': 'volume', 'destination_type': 'volume',
|
||||
@ -48,7 +53,7 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
'volume_id': 'fake-volume-id'}))
|
||||
|
||||
def _test_compute_api(self, method, rpc_method,
|
||||
assert_dict=False, **kwargs):
|
||||
expected_args=None, **kwargs):
|
||||
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||
|
||||
rpcapi = kwargs.pop('rpcapi_class', compute_rpcapi.ComputeAPI)()
|
||||
@ -60,15 +65,13 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
expected_version = kwargs.pop('version', base_version)
|
||||
|
||||
expected_kwargs = kwargs.copy()
|
||||
if expected_args:
|
||||
expected_kwargs.update(expected_args)
|
||||
if 'host_param' in expected_kwargs:
|
||||
expected_kwargs['host'] = expected_kwargs.pop('host_param')
|
||||
else:
|
||||
expected_kwargs.pop('host', None)
|
||||
|
||||
if assert_dict:
|
||||
expected_kwargs['instance'] = jsonutils.to_primitive(
|
||||
expected_kwargs['instance'])
|
||||
|
||||
cast_and_call = ['confirm_resize', 'stop_instance']
|
||||
if rpc_method == 'call' and method in cast_and_call:
|
||||
if method == 'confirm_resize':
|
||||
@ -187,8 +190,9 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
instance=self.fake_instance_obj, version='4.0')
|
||||
|
||||
def test_get_instance_diagnostics(self):
|
||||
expected_args = {'instance': self.fake_instance}
|
||||
self._test_compute_api('get_instance_diagnostics', 'call',
|
||||
assert_dict=True, instance=self.fake_instance_obj,
|
||||
expected_args, instance=self.fake_instance_obj,
|
||||
version='4.0')
|
||||
|
||||
def test_get_vnc_console(self):
|
||||
@ -265,7 +269,18 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
|
||||
def test_prep_resize(self):
|
||||
self._test_compute_api('prep_resize', 'cast',
|
||||
instance=self.fake_instance_obj, instance_type='fake_type',
|
||||
instance=self.fake_instance_obj,
|
||||
instance_type=self.fake_flavor_obj,
|
||||
image='fake_image', host='host',
|
||||
reservations=list('fake_res'),
|
||||
request_spec='fake_spec',
|
||||
filter_properties={'fakeprop': 'fakeval'},
|
||||
node='node', clean_shutdown=True, version='4.1')
|
||||
self.flags(compute='4.0', group='upgrade_levels')
|
||||
expected_args = {'instance_type': self.fake_flavor}
|
||||
self._test_compute_api('prep_resize', 'cast', expected_args,
|
||||
instance=self.fake_instance_obj,
|
||||
instance_type=self.fake_flavor_obj,
|
||||
image='fake_image', host='host',
|
||||
reservations=list('fake_res'),
|
||||
request_spec='fake_spec',
|
||||
@ -306,9 +321,10 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
security_group_id='id', host='host', version='4.0')
|
||||
|
||||
def test_refresh_instance_security_rules(self):
|
||||
expected_args = {'instance': self.fake_instance}
|
||||
self._test_compute_api('refresh_instance_security_rules', 'cast',
|
||||
host='fake_host', instance=self.fake_instance_obj,
|
||||
version='4.0', assert_dict=True)
|
||||
expected_args, host='fake_host',
|
||||
instance=self.fake_instance_obj, version='4.0')
|
||||
|
||||
def test_remove_aggregate_host(self):
|
||||
self._test_compute_api('remove_aggregate_host', 'cast',
|
||||
@ -338,7 +354,14 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
||||
def test_resize_instance(self):
|
||||
self._test_compute_api('resize_instance', 'cast',
|
||||
instance=self.fake_instance_obj, migration={'id': 'fake_id'},
|
||||
image='image', instance_type={'id': 1},
|
||||
image='image', instance_type=self.fake_flavor_obj,
|
||||
reservations=list('fake_res'),
|
||||
clean_shutdown=True, version='4.1')
|
||||
self.flags(compute='4.0', group='upgrade_levels')
|
||||
expected_args = {'instance_type': self.fake_flavor}
|
||||
self._test_compute_api('resize_instance', 'cast', expected_args,
|
||||
instance=self.fake_instance_obj, migration={'id': 'fake_id'},
|
||||
image='image', instance_type=self.fake_flavor_obj,
|
||||
reservations=list('fake_res'),
|
||||
clean_shutdown=True, version='4.0')
|
||||
|
||||
|
55
nova/tests/unit/fake_flavor.py
Normal file
55
nova/tests/unit/fake_flavor.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import objects
|
||||
from nova.objects import fields
|
||||
|
||||
|
||||
def fake_db_flavor(**updates):
|
||||
db_flavor = {
|
||||
'id': 1,
|
||||
'name': 'fake_flavor',
|
||||
'memory_mb': 1024,
|
||||
'vcpus': 1,
|
||||
'root_gb': 100,
|
||||
'ephemeral_gb': 0,
|
||||
'flavorid': 'abc',
|
||||
'swap': 0,
|
||||
'disabled': False,
|
||||
'is_public': True,
|
||||
'extra_specs': {},
|
||||
'projects': []
|
||||
}
|
||||
|
||||
for name, field in objects.Flavor.fields.items():
|
||||
if name in db_flavor:
|
||||
continue
|
||||
if field.nullable:
|
||||
db_flavor[name] = None
|
||||
elif field.default != fields.UnspecifiedDefault:
|
||||
db_flavor[name] = field.default
|
||||
else:
|
||||
raise Exception('fake_db_flavor needs help with %s' % name)
|
||||
|
||||
if updates:
|
||||
db_flavor.update(updates)
|
||||
|
||||
return db_flavor
|
||||
|
||||
|
||||
def fake_flavor_obj(context, **updates):
|
||||
expected_attrs = updates.pop('expected_attrs', None)
|
||||
return objects.Flavor._from_db_object(context,
|
||||
objects.Flavor(), fake_db_flavor(**updates),
|
||||
expected_attrs=expected_attrs)
|
Loading…
x
Reference in New Issue
Block a user