Make compute API create() use BDM objects
Once we have consolidated all the block device information for an instance coming from different sources (request, image metadata) we turn them into objects and use objects update_or_create() for saving them into the database. Blueprint: kilo-objects Change-Id: I9a70761d6a0a448cfbaf7102c45d6dc180a4cdea
This commit is contained in:
parent
c11cd4fa26
commit
220ba7dbbc
|
@ -74,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.33')
|
target = oslo_messaging.Target(version='1.34')
|
||||||
|
|
||||||
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 '
|
||||||
|
|
|
@ -106,6 +106,8 @@ class CellsAPI(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()
|
* 1.32 - Send objects for instances in build_instances()
|
||||||
* 1.33 - Add clean_shutdown to resize_instance()
|
* 1.33 - Add clean_shutdown to resize_instance()
|
||||||
|
* 1.34 - build_instances uses BlockDeviceMapping objects, drops
|
||||||
|
legacy_bdm argument
|
||||||
'''
|
'''
|
||||||
|
|
||||||
VERSION_ALIASES = {
|
VERSION_ALIASES = {
|
||||||
|
@ -153,7 +155,15 @@ class CellsAPI(object):
|
||||||
instances = build_inst_kwargs['instances']
|
instances = build_inst_kwargs['instances']
|
||||||
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'
|
|
||||||
|
version = '1.34'
|
||||||
|
if self.client.can_send_version('1.34'):
|
||||||
|
build_inst_kwargs.pop('legacy_bdm', None)
|
||||||
|
else:
|
||||||
|
bdm_p = objects_base.obj_to_primitive(
|
||||||
|
build_inst_kwargs['block_device_mapping'])
|
||||||
|
build_inst_kwargs['block_device_mapping'] = bdm_p
|
||||||
|
version = '1.32'
|
||||||
if not self.client.can_send_version('1.32'):
|
if not self.client.can_send_version('1.32'):
|
||||||
instances_p = [jsonutils.to_primitive(inst) for inst in instances]
|
instances_p = [jsonutils.to_primitive(inst) for inst in instances]
|
||||||
build_inst_kwargs['instances'] = instances_p
|
build_inst_kwargs['instances'] = instances_p
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
networking and storage of VMs, and compute hosts on which they run)."""
|
networking and storage of VMs, and compute hosts on which they run)."""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
import copy
|
||||||
import functools
|
import functools
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
@ -62,6 +63,7 @@ from nova.network.security_group import security_group_base
|
||||||
from nova import notifications
|
from nova import notifications
|
||||||
from nova import objects
|
from nova import objects
|
||||||
from nova.objects import base as obj_base
|
from nova.objects import base as obj_base
|
||||||
|
from nova.objects import block_device as block_device_obj
|
||||||
from nova.objects import keypair as keypair_obj
|
from nova.objects import keypair as keypair_obj
|
||||||
from nova.objects import quotas as quotas_obj
|
from nova.objects import quotas as quotas_obj
|
||||||
from nova.objects import security_group as security_group_obj
|
from nova.objects import security_group as security_group_obj
|
||||||
|
@ -705,9 +707,9 @@ class API(base.Base):
|
||||||
|
|
||||||
return image_defined_bdms
|
return image_defined_bdms
|
||||||
|
|
||||||
def _check_and_transform_bdm(self, base_options, instance_type, image_meta,
|
def _check_and_transform_bdm(self, context, base_options, instance_type,
|
||||||
min_count, max_count, block_device_mapping,
|
image_meta, min_count, max_count,
|
||||||
legacy_bdm):
|
block_device_mapping, legacy_bdm):
|
||||||
# NOTE (ndipanov): Assume root dev name is 'vda' if not supplied.
|
# NOTE (ndipanov): Assume root dev name is 'vda' if not supplied.
|
||||||
# It's needed for legacy conversion to work.
|
# It's needed for legacy conversion to work.
|
||||||
root_device_name = (base_options.get('root_device_name') or 'vda')
|
root_device_name = (base_options.get('root_device_name') or 'vda')
|
||||||
|
@ -758,7 +760,8 @@ class API(base.Base):
|
||||||
' instances')
|
' instances')
|
||||||
raise exception.InvalidRequest(msg)
|
raise exception.InvalidRequest(msg)
|
||||||
|
|
||||||
return block_device_mapping
|
return block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
context, block_device_mapping)
|
||||||
|
|
||||||
def _get_image(self, context, image_href):
|
def _get_image(self, context, image_href):
|
||||||
if not image_href:
|
if not image_href:
|
||||||
|
@ -783,7 +786,6 @@ class API(base.Base):
|
||||||
user_data, metadata, injected_files,
|
user_data, metadata, injected_files,
|
||||||
access_ip_v4, access_ip_v6,
|
access_ip_v4, access_ip_v6,
|
||||||
requested_networks, config_drive,
|
requested_networks, config_drive,
|
||||||
block_device_mapping,
|
|
||||||
auto_disk_config, reservation_id,
|
auto_disk_config, reservation_id,
|
||||||
max_count):
|
max_count):
|
||||||
"""Verify all the input parameters regardless of the provisioning
|
"""Verify all the input parameters regardless of the provisioning
|
||||||
|
@ -1097,8 +1099,7 @@ class API(base.Base):
|
||||||
key_name, key_data, security_groups, availability_zone,
|
key_name, key_data, security_groups, availability_zone,
|
||||||
forced_host, user_data, metadata, injected_files, access_ip_v4,
|
forced_host, user_data, metadata, injected_files, access_ip_v4,
|
||||||
access_ip_v6, requested_networks, config_drive,
|
access_ip_v6, requested_networks, config_drive,
|
||||||
block_device_mapping, auto_disk_config, reservation_id,
|
auto_disk_config, reservation_id, max_count)
|
||||||
max_count)
|
|
||||||
|
|
||||||
# max_net_count is the maximum number of instances requested by the
|
# max_net_count is the maximum number of instances requested by the
|
||||||
# user adjusted for any network quota constraints, including
|
# user adjusted for any network quota constraints, including
|
||||||
|
@ -1112,7 +1113,7 @@ class API(base.Base):
|
||||||
'max_net_count': max_net_count})
|
'max_net_count': max_net_count})
|
||||||
max_count = max_net_count
|
max_count = max_net_count
|
||||||
|
|
||||||
block_device_mapping = self._check_and_transform_bdm(
|
block_device_mapping = self._check_and_transform_bdm(context,
|
||||||
base_options, instance_type, boot_meta, min_count, max_count,
|
base_options, instance_type, boot_meta, min_count, max_count,
|
||||||
block_device_mapping, legacy_bdm)
|
block_device_mapping, legacy_bdm)
|
||||||
|
|
||||||
|
@ -1194,34 +1195,33 @@ class API(base.Base):
|
||||||
|
|
||||||
return prepared_mappings
|
return prepared_mappings
|
||||||
|
|
||||||
def _update_block_device_mapping(self, elevated_context,
|
def _create_block_device_mapping(self, instance_type, instance_uuid,
|
||||||
instance_type, instance_uuid,
|
|
||||||
block_device_mapping):
|
block_device_mapping):
|
||||||
"""tell vm driver to attach volume at boot time by updating
|
"""Create the BlockDeviceMapping objects in the db.
|
||||||
BlockDeviceMapping
|
|
||||||
|
This method makes a copy of the list in order to avoid using the same
|
||||||
|
id field in case this is called for multiple instances.
|
||||||
"""
|
"""
|
||||||
LOG.debug("block_device_mapping %s", block_device_mapping,
|
LOG.debug("block_device_mapping %s", block_device_mapping,
|
||||||
instance_uuid=instance_uuid)
|
instance_uuid=instance_uuid)
|
||||||
for bdm in block_device_mapping:
|
instance_block_device_mapping = copy.deepcopy(block_device_mapping)
|
||||||
bdm['volume_size'] = self._volume_size(instance_type, bdm)
|
for bdm in instance_block_device_mapping:
|
||||||
if bdm.get('volume_size') == 0:
|
bdm.volume_size = self._volume_size(instance_type, bdm)
|
||||||
|
if bdm.volume_size == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bdm['instance_uuid'] = instance_uuid
|
bdm.instance_uuid = instance_uuid
|
||||||
|
bdm.update_or_create()
|
||||||
self.db.block_device_mapping_update_or_create(elevated_context,
|
|
||||||
bdm,
|
|
||||||
legacy=False)
|
|
||||||
|
|
||||||
def _validate_bdm(self, context, instance, instance_type, all_mappings):
|
def _validate_bdm(self, context, instance, instance_type, all_mappings):
|
||||||
def _subsequent_list(l):
|
def _subsequent_list(l):
|
||||||
return all(el + 1 == l[i + 1] for i, el in enumerate(l[:-1]))
|
return all(el + 1 == l[i + 1] for i, el in enumerate(l[:-1]))
|
||||||
|
|
||||||
# Make sure that the boot indexes make sense
|
# Make sure that the boot indexes make sense
|
||||||
boot_indexes = sorted([bdm['boot_index']
|
boot_indexes = sorted([bdm.boot_index
|
||||||
for bdm in all_mappings
|
for bdm in all_mappings
|
||||||
if bdm.get('boot_index') is not None
|
if bdm.boot_index is not None
|
||||||
and bdm.get('boot_index') >= 0])
|
and bdm.boot_index >= 0])
|
||||||
|
|
||||||
if 0 not in boot_indexes or not _subsequent_list(boot_indexes):
|
if 0 not in boot_indexes or not _subsequent_list(boot_indexes):
|
||||||
raise exception.InvalidBDMBootSequence()
|
raise exception.InvalidBDMBootSequence()
|
||||||
|
@ -1230,18 +1230,18 @@ class API(base.Base):
|
||||||
# NOTE(vish): For now, just make sure the volumes are accessible.
|
# NOTE(vish): For now, just make sure the volumes are accessible.
|
||||||
# Additionally, check that the volume can be attached to this
|
# Additionally, check that the volume can be attached to this
|
||||||
# instance.
|
# instance.
|
||||||
snapshot_id = bdm.get('snapshot_id')
|
snapshot_id = bdm.snapshot_id
|
||||||
volume_id = bdm.get('volume_id')
|
volume_id = bdm.volume_id
|
||||||
image_id = bdm.get('image_id')
|
image_id = bdm.image_id
|
||||||
if (image_id is not None and
|
if (image_id is not None and
|
||||||
image_id != instance.get('image_ref')):
|
image_id != instance.get('image_ref')):
|
||||||
try:
|
try:
|
||||||
self._get_image(context, image_id)
|
self._get_image(context, image_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise exception.InvalidBDMImage(id=image_id)
|
raise exception.InvalidBDMImage(id=image_id)
|
||||||
if (bdm['source_type'] == 'image' and
|
if (bdm.source_type == 'image' and
|
||||||
bdm['destination_type'] == 'volume' and
|
bdm.destination_type == 'volume' and
|
||||||
not bdm['volume_size']):
|
not bdm.volume_size):
|
||||||
raise exception.InvalidBDM(message=_("Images with "
|
raise exception.InvalidBDM(message=_("Images with "
|
||||||
"destination_type 'volume' need to have a non-zero "
|
"destination_type 'volume' need to have a non-zero "
|
||||||
"size specified"))
|
"size specified"))
|
||||||
|
@ -1264,7 +1264,7 @@ class API(base.Base):
|
||||||
except Exception:
|
except Exception:
|
||||||
raise exception.InvalidBDMSnapshot(id=snapshot_id)
|
raise exception.InvalidBDMSnapshot(id=snapshot_id)
|
||||||
|
|
||||||
ephemeral_size = sum(bdm.get('volume_size') or 0
|
ephemeral_size = sum(bdm.volume_size or 0
|
||||||
for bdm in all_mappings
|
for bdm in all_mappings
|
||||||
if block_device.new_format_is_ephemeral(bdm))
|
if block_device.new_format_is_ephemeral(bdm))
|
||||||
if ephemeral_size > instance_type['ephemeral_gb']:
|
if ephemeral_size > instance_type['ephemeral_gb']:
|
||||||
|
@ -1278,14 +1278,14 @@ class API(base.Base):
|
||||||
raise exception.InvalidBDMFormat(details=msg)
|
raise exception.InvalidBDMFormat(details=msg)
|
||||||
|
|
||||||
if swap_list:
|
if swap_list:
|
||||||
swap_size = swap_list[0].get('volume_size') or 0
|
swap_size = swap_list[0].volume_size or 0
|
||||||
if swap_size > instance_type['swap']:
|
if swap_size > instance_type['swap']:
|
||||||
raise exception.InvalidBDMSwapSize()
|
raise exception.InvalidBDMSwapSize()
|
||||||
|
|
||||||
max_local = CONF.max_local_block_devices
|
max_local = CONF.max_local_block_devices
|
||||||
if max_local >= 0:
|
if max_local >= 0:
|
||||||
num_local = len([bdm for bdm in all_mappings
|
num_local = len([bdm for bdm in all_mappings
|
||||||
if bdm.get('destination_type') == 'local'])
|
if bdm.destination_type == 'local'])
|
||||||
if num_local > max_local:
|
if num_local > max_local:
|
||||||
raise exception.InvalidBDMLocalsLimit()
|
raise exception.InvalidBDMLocalsLimit()
|
||||||
|
|
||||||
|
@ -1400,8 +1400,8 @@ class API(base.Base):
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
instance.destroy()
|
instance.destroy()
|
||||||
|
|
||||||
self._update_block_device_mapping(
|
self._create_block_device_mapping(
|
||||||
context, instance_type, instance['uuid'], block_device_mapping)
|
instance_type, instance['uuid'], block_device_mapping)
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ class ComputeCellsAPI(compute_api.API):
|
||||||
"""
|
"""
|
||||||
return super(ComputeCellsAPI, self).create(*args, **kwargs)
|
return super(ComputeCellsAPI, self).create(*args, **kwargs)
|
||||||
|
|
||||||
def _update_block_device_mapping(self, *args, **kwargs):
|
def _create_block_device_mapping(self, *args, **kwargs):
|
||||||
"""Don't create block device mappings in the API cell.
|
"""Don't create block device mappings in the API cell.
|
||||||
|
|
||||||
The child cell will create it and propagate it up to the parent cell.
|
The child cell will create it and propagate it up to the parent cell.
|
||||||
|
|
|
@ -199,6 +199,7 @@ class ConductorManager(manager.Manager):
|
||||||
architecture)
|
architecture)
|
||||||
return jsonutils.to_primitive(info)
|
return jsonutils.to_primitive(info)
|
||||||
|
|
||||||
|
# NOTE(ndipanov): This can be removed in version 3.0 of the RPC API
|
||||||
def block_device_mapping_update_or_create(self, context, values, create):
|
def block_device_mapping_update_or_create(self, context, values, create):
|
||||||
if create is None:
|
if create is None:
|
||||||
bdm = self.db.block_device_mapping_update_or_create(context,
|
bdm = self.db.block_device_mapping_update_or_create(context,
|
||||||
|
|
|
@ -449,7 +449,8 @@ class ComputeTaskAPI(object):
|
||||||
kw['requested_networks'] = kw['requested_networks'].as_tuples()
|
kw['requested_networks'] = kw['requested_networks'].as_tuples()
|
||||||
if not self.client.can_send_version('1.7'):
|
if not self.client.can_send_version('1.7'):
|
||||||
version = '1.5'
|
version = '1.5'
|
||||||
kw.update({'block_device_mapping': block_device_mapping,
|
bdm_p = objects_base.obj_to_primitive(block_device_mapping)
|
||||||
|
kw.update({'block_device_mapping': bdm_p,
|
||||||
'legacy_bdm': legacy_bdm})
|
'legacy_bdm': legacy_bdm})
|
||||||
|
|
||||||
cctxt = self.client.prepare(version=version)
|
cctxt = self.client.prepare(version=version)
|
||||||
|
|
|
@ -296,3 +296,9 @@ def block_device_make_list(context, db_list, **extra_args):
|
||||||
objects.BlockDeviceMappingList(context),
|
objects.BlockDeviceMappingList(context),
|
||||||
objects.BlockDeviceMapping, db_list,
|
objects.BlockDeviceMapping, db_list,
|
||||||
**extra_args)
|
**extra_args)
|
||||||
|
|
||||||
|
|
||||||
|
def block_device_make_list_from_dicts(context, bdm_dicts_list):
|
||||||
|
bdm_objects = [objects.BlockDeviceMapping(context=context, **bdm)
|
||||||
|
for bdm in bdm_dicts_list]
|
||||||
|
return BlockDeviceMappingList(objects=bdm_objects)
|
||||||
|
|
|
@ -139,7 +139,7 @@ class CellsAPITestCase(test.NoDBTestCase):
|
||||||
'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.32')
|
expected_args, version='1.34')
|
||||||
|
|
||||||
def test_get_capacities(self):
|
def test_get_capacities(self):
|
||||||
capacity_info = {"capacity": "info"}
|
capacity_info = {"capacity": "info"}
|
||||||
|
|
|
@ -33,6 +33,7 @@ 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_block_device
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -115,8 +116,12 @@ class CellsSchedulerTestCase(test.TestCase):
|
||||||
'project_id': self.ctxt.project_id}
|
'project_id': self.ctxt.project_id}
|
||||||
|
|
||||||
call_info = {'uuids': []}
|
call_info = {'uuids': []}
|
||||||
block_device_mapping = [block_device.create_image_bdm(
|
block_device_mapping = [
|
||||||
'fake_image_ref')]
|
objects.BlockDeviceMapping(context=self.ctxt,
|
||||||
|
**fake_block_device.FakeDbBlockDeviceDict(
|
||||||
|
block_device.create_image_bdm('fake_image_ref'),
|
||||||
|
anon=True))
|
||||||
|
]
|
||||||
|
|
||||||
def _fake_instance_update_at_top(_ctxt, instance):
|
def _fake_instance_update_at_top(_ctxt, instance):
|
||||||
call_info['uuids'].append(instance['uuid'])
|
call_info['uuids'].append(instance['uuid'])
|
||||||
|
|
|
@ -902,7 +902,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
instance = self._create_fake_instance_obj()
|
instance = self._create_fake_instance_obj()
|
||||||
instance_type = {'swap': 1, 'ephemeral_gb': 2}
|
instance_type = {'swap': 1, 'ephemeral_gb': 2}
|
||||||
mappings = [
|
mappings = [
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/sdb4',
|
'device_name': '/dev/sdb4',
|
||||||
'source_type': 'blank',
|
'source_type': 'blank',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
|
@ -910,8 +910,8 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': 'swap',
|
'guest_format': 'swap',
|
||||||
'boot_index': -1,
|
'boot_index': -1,
|
||||||
'volume_size': 1
|
'volume_size': 1
|
||||||
},
|
}, anon=True),
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/sda1',
|
'device_name': '/dev/sda1',
|
||||||
'source_type': 'volume',
|
'source_type': 'volume',
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
|
@ -920,8 +920,8 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': None,
|
'guest_format': None,
|
||||||
'boot_index': 1,
|
'boot_index': 1,
|
||||||
'volume_size': 6
|
'volume_size': 6
|
||||||
},
|
}, anon=True),
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/sda2',
|
'device_name': '/dev/sda2',
|
||||||
'source_type': 'snapshot',
|
'source_type': 'snapshot',
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
|
@ -930,8 +930,8 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': None,
|
'guest_format': None,
|
||||||
'boot_index': 0,
|
'boot_index': 0,
|
||||||
'volume_size': 4
|
'volume_size': 4
|
||||||
},
|
}, anon=True),
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/sda3',
|
'device_name': '/dev/sda3',
|
||||||
'source_type': 'image',
|
'source_type': 'image',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
|
@ -939,20 +939,22 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': None,
|
'guest_format': None,
|
||||||
'boot_index': 2,
|
'boot_index': 2,
|
||||||
'volume_size': 1
|
'volume_size': 1
|
||||||
}
|
}, anon=True)
|
||||||
]
|
]
|
||||||
|
mappings = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, mappings)
|
||||||
|
|
||||||
# Make sure it passes at first
|
# Make sure it passes at first
|
||||||
self.compute_api._validate_bdm(self.context, instance,
|
self.compute_api._validate_bdm(self.context, instance,
|
||||||
instance_type, mappings)
|
instance_type, mappings)
|
||||||
|
|
||||||
# Boot sequence
|
# Boot sequence
|
||||||
mappings[2]['boot_index'] = 2
|
mappings[2].boot_index = 2
|
||||||
self.assertRaises(exception.InvalidBDMBootSequence,
|
self.assertRaises(exception.InvalidBDMBootSequence,
|
||||||
self.compute_api._validate_bdm,
|
self.compute_api._validate_bdm,
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings)
|
mappings)
|
||||||
mappings[2]['boot_index'] = 0
|
mappings[2].boot_index = 0
|
||||||
|
|
||||||
# number of local block_devices
|
# number of local block_devices
|
||||||
self.flags(max_local_block_devices=1)
|
self.flags(max_local_block_devices=1)
|
||||||
|
@ -961,7 +963,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings)
|
mappings)
|
||||||
ephemerals = [
|
ephemerals = [
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/vdb',
|
'device_name': '/dev/vdb',
|
||||||
'source_type': 'blank',
|
'source_type': 'blank',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
|
@ -970,8 +972,8 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': None,
|
'guest_format': None,
|
||||||
'boot_index': -1,
|
'boot_index': -1,
|
||||||
'volume_size': 1
|
'volume_size': 1
|
||||||
},
|
}, anon=True),
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/vdc',
|
'device_name': '/dev/vdc',
|
||||||
'source_type': 'blank',
|
'source_type': 'blank',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
|
@ -980,34 +982,37 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': None,
|
'guest_format': None,
|
||||||
'boot_index': -1,
|
'boot_index': -1,
|
||||||
'volume_size': 1
|
'volume_size': 1
|
||||||
}]
|
}, anon=True)
|
||||||
|
]
|
||||||
|
ephemerals = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, ephemerals)
|
||||||
|
|
||||||
self.flags(max_local_block_devices=4)
|
self.flags(max_local_block_devices=4)
|
||||||
# More ephemerals are OK as long as they are not over the size limit
|
# More ephemerals are OK as long as they are not over the size limit
|
||||||
|
mappings_ = mappings[:]
|
||||||
|
mappings_.objects.extend(ephemerals)
|
||||||
self.compute_api._validate_bdm(self.context, instance,
|
self.compute_api._validate_bdm(self.context, instance,
|
||||||
instance_type, mappings + ephemerals)
|
instance_type, mappings_)
|
||||||
|
|
||||||
# Ephemerals over the size limit
|
# Ephemerals over the size limit
|
||||||
ephemerals[0]['volume_size'] = 3
|
ephemerals[0].volume_size = 3
|
||||||
|
mappings_ = mappings[:]
|
||||||
|
mappings_.objects.extend(ephemerals)
|
||||||
self.assertRaises(exception.InvalidBDMEphemeralSize,
|
self.assertRaises(exception.InvalidBDMEphemeralSize,
|
||||||
self.compute_api._validate_bdm,
|
self.compute_api._validate_bdm,
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings + ephemerals)
|
mappings_)
|
||||||
self.assertRaises(exception.InvalidBDMEphemeralSize,
|
|
||||||
self.compute_api._validate_bdm,
|
|
||||||
self.context, instance, instance_type,
|
|
||||||
mappings + [ephemerals[0]])
|
|
||||||
|
|
||||||
# Swap over the size limit
|
# Swap over the size limit
|
||||||
mappings[0]['volume_size'] = 3
|
mappings[0].volume_size = 3
|
||||||
self.assertRaises(exception.InvalidBDMSwapSize,
|
self.assertRaises(exception.InvalidBDMSwapSize,
|
||||||
self.compute_api._validate_bdm,
|
self.compute_api._validate_bdm,
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings)
|
mappings)
|
||||||
mappings[0]['volume_size'] = 1
|
mappings[0].volume_size = 1
|
||||||
|
|
||||||
additional_swap = [
|
additional_swap = [
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/vdb',
|
'device_name': '/dev/vdb',
|
||||||
'source_type': 'blank',
|
'source_type': 'blank',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
|
@ -1015,31 +1020,42 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'guest_format': 'swap',
|
'guest_format': 'swap',
|
||||||
'boot_index': -1,
|
'boot_index': -1,
|
||||||
'volume_size': 1
|
'volume_size': 1
|
||||||
}]
|
}, anon=True)
|
||||||
|
]
|
||||||
|
additional_swap = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, additional_swap)
|
||||||
|
|
||||||
# More than one swap
|
# More than one swap
|
||||||
|
mappings_ = mappings[:]
|
||||||
|
mappings_.objects.extend(additional_swap)
|
||||||
self.assertRaises(exception.InvalidBDMFormat,
|
self.assertRaises(exception.InvalidBDMFormat,
|
||||||
self.compute_api._validate_bdm,
|
self.compute_api._validate_bdm,
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings + additional_swap)
|
mappings_)
|
||||||
|
|
||||||
image_no_size = [
|
image_no_size = [
|
||||||
{
|
fake_block_device.FakeDbBlockDeviceDict({
|
||||||
'device_name': '/dev/sda4',
|
'device_name': '/dev/sda4',
|
||||||
'source_type': 'image',
|
'source_type': 'image',
|
||||||
'image_id': image_id,
|
'image_id': image_id,
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
'boot_index': -1,
|
'boot_index': -1,
|
||||||
'volume_size': None,
|
'volume_size': None,
|
||||||
}]
|
}, anon=True)
|
||||||
|
]
|
||||||
|
image_no_size = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, image_no_size)
|
||||||
|
mappings_ = mappings[:]
|
||||||
|
mappings_.objects.extend(image_no_size)
|
||||||
self.assertRaises(exception.InvalidBDM,
|
self.assertRaises(exception.InvalidBDM,
|
||||||
self.compute_api._validate_bdm,
|
self.compute_api._validate_bdm,
|
||||||
self.context, instance, instance_type,
|
self.context, instance, instance_type,
|
||||||
mappings + image_no_size)
|
mappings_)
|
||||||
|
|
||||||
def test_validate_bdm_media_service_exceptions(self):
|
def test_validate_bdm_media_service_exceptions(self):
|
||||||
instance_type = {'swap': 1, 'ephemeral_gb': 1}
|
instance_type = {'swap': 1, 'ephemeral_gb': 1}
|
||||||
all_mappings = [{'id': 1,
|
all_mappings = [fake_block_device.FakeDbBlockDeviceDict({
|
||||||
|
'id': 1,
|
||||||
'no_device': None,
|
'no_device': None,
|
||||||
'source_type': 'volume',
|
'source_type': 'volume',
|
||||||
'destination_type': 'volume',
|
'destination_type': 'volume',
|
||||||
|
@ -1047,7 +1063,9 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||||
'volume_id': self.volume_id,
|
'volume_id': self.volume_id,
|
||||||
'device_name': 'vda',
|
'device_name': 'vda',
|
||||||
'boot_index': 0,
|
'boot_index': 0,
|
||||||
'delete_on_termination': False}]
|
'delete_on_termination': False}, anon=True)]
|
||||||
|
all_mappings = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, all_mappings)
|
||||||
|
|
||||||
# First we test a list of invalid status values that should result
|
# First we test a list of invalid status values that should result
|
||||||
# in an InvalidVolume exception being raised.
|
# in an InvalidVolume exception being raised.
|
||||||
|
@ -8312,7 +8330,12 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
|
|
||||||
return bdm
|
return bdm
|
||||||
|
|
||||||
def test_update_block_device_mapping(self):
|
def test_create_block_device_mapping(self):
|
||||||
|
def _compare_bdm_object(obj1, obj2, extra_keys=()):
|
||||||
|
for key in (('device_name', 'source_type', 'destination_type')
|
||||||
|
+ extra_keys):
|
||||||
|
self.assertEqual(getattr(obj1, key), getattr(obj2, key))
|
||||||
|
|
||||||
swap_size = ephemeral_size = 1
|
swap_size = ephemeral_size = 1
|
||||||
instance_type = {'swap': swap_size, 'ephemeral_gb': ephemeral_size}
|
instance_type = {'swap': swap_size, 'ephemeral_gb': ephemeral_size}
|
||||||
instance = self._create_fake_instance_obj()
|
instance = self._create_fake_instance_obj()
|
||||||
|
@ -8377,12 +8400,13 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
|
|
||||||
image_mapping = self.compute_api._prepare_image_mapping(
|
image_mapping = self.compute_api._prepare_image_mapping(
|
||||||
instance_type, mappings)
|
instance_type, mappings)
|
||||||
self.compute_api._update_block_device_mapping(
|
image_mapping = block_device_obj.block_device_make_list_from_dicts(
|
||||||
self.context, instance_type, instance['uuid'], image_mapping)
|
self.context, image_mapping)
|
||||||
|
self.compute_api._create_block_device_mapping(
|
||||||
|
instance_type, instance['uuid'], image_mapping)
|
||||||
|
|
||||||
bdms = [block_device.BlockDeviceDict(bdm) for bdm in
|
bdms = block_device_obj.BlockDeviceMappingList.get_by_instance_uuid(
|
||||||
db.block_device_mapping_get_all_by_instance(
|
self.context, instance['uuid'])
|
||||||
self.context, instance['uuid'])]
|
|
||||||
expected_result = [
|
expected_result = [
|
||||||
{'source_type': 'blank', 'destination_type': 'local',
|
{'source_type': 'blank', 'destination_type': 'local',
|
||||||
'guest_format': 'swap', 'device_name': '/dev/sdb1',
|
'guest_format': 'swap', 'device_name': '/dev/sdb1',
|
||||||
|
@ -8397,21 +8421,32 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
'guest_format': CONF.default_ephemeral_format,
|
'guest_format': CONF.default_ephemeral_format,
|
||||||
'device_name': '/dev/sdc2', 'delete_on_termination': True},
|
'device_name': '/dev/sdc2', 'delete_on_termination': True},
|
||||||
]
|
]
|
||||||
bdms.sort(key=operator.itemgetter('device_name'))
|
expected_result = block_device_obj.block_device_make_list_from_dicts(
|
||||||
expected_result.sort(key=operator.itemgetter('device_name'))
|
self.context,
|
||||||
|
map(fake_block_device.AnonFakeDbBlockDeviceDict,
|
||||||
|
expected_result))
|
||||||
|
bdms.sort(key=operator.attrgetter('device_name'))
|
||||||
|
expected_result.sort(key=operator.attrgetter('device_name'))
|
||||||
self.assertEqual(len(bdms), len(expected_result))
|
self.assertEqual(len(bdms), len(expected_result))
|
||||||
for expected, got in zip(expected_result, bdms):
|
for expected, got in zip(expected_result, bdms):
|
||||||
self.assertThat(expected, matchers.IsSubDictOf(got))
|
_compare_bdm_object(
|
||||||
|
expected, got,
|
||||||
|
extra_keys=('guest_format', 'delete_on_termination'))
|
||||||
|
|
||||||
self.compute_api._update_block_device_mapping(
|
block_device_mapping = (
|
||||||
self.context, flavors.get_default_flavor(),
|
block_device_obj.block_device_make_list_from_dicts(
|
||||||
instance['uuid'], block_device_mapping)
|
self.context,
|
||||||
bdms = [block_device.BlockDeviceDict(bdm) for bdm in
|
map(fake_block_device.AnonFakeDbBlockDeviceDict,
|
||||||
db.block_device_mapping_get_all_by_instance(
|
block_device_mapping)))
|
||||||
self.context, instance['uuid'])]
|
self.compute_api._create_block_device_mapping(
|
||||||
|
flavors.get_default_flavor(), instance['uuid'],
|
||||||
|
block_device_mapping)
|
||||||
|
bdms = block_device_obj.BlockDeviceMappingList.get_by_instance_uuid(
|
||||||
|
self.context, instance['uuid'])
|
||||||
expected_result = [
|
expected_result = [
|
||||||
{'snapshot_id': '00000000-aaaa-bbbb-cccc-000000000000',
|
{'snapshot_id': '00000000-aaaa-bbbb-cccc-000000000000',
|
||||||
'device_name': '/dev/sda1'},
|
'device_name': '/dev/sda1', 'source_type': 'snapshot',
|
||||||
|
'destination_type': 'volume'},
|
||||||
|
|
||||||
{'source_type': 'blank', 'destination_type': 'local',
|
{'source_type': 'blank', 'destination_type': 'local',
|
||||||
'guest_format': 'swap', 'device_name': '/dev/sdb1',
|
'guest_format': 'swap', 'device_name': '/dev/sdb1',
|
||||||
|
@ -8449,11 +8484,17 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
'source_type': 'snapshot', 'destination_type': 'volume',
|
'source_type': 'snapshot', 'destination_type': 'volume',
|
||||||
'snapshot_id': '77777777-aaaa-bbbb-cccc-888888888888'},
|
'snapshot_id': '77777777-aaaa-bbbb-cccc-888888888888'},
|
||||||
{'no_device': True, 'device_name': '/dev/sdd4'}]
|
{'no_device': True, 'device_name': '/dev/sdd4'}]
|
||||||
|
expected_result = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context,
|
||||||
|
map(fake_block_device.AnonFakeDbBlockDeviceDict,
|
||||||
|
expected_result))
|
||||||
bdms.sort(key=operator.itemgetter('device_name'))
|
bdms.sort(key=operator.itemgetter('device_name'))
|
||||||
expected_result.sort(key=operator.itemgetter('device_name'))
|
expected_result.sort(key=operator.itemgetter('device_name'))
|
||||||
self.assertEqual(len(bdms), len(expected_result))
|
self.assertEqual(len(bdms), len(expected_result))
|
||||||
for expected, got in zip(expected_result, bdms):
|
for expected, got in zip(expected_result, bdms):
|
||||||
self.assertThat(expected, matchers.IsSubDictOf(got))
|
_compare_bdm_object(
|
||||||
|
expected, got,
|
||||||
|
extra_keys=('snapshot_id', 'delete_on_termination'))
|
||||||
|
|
||||||
def _test_check_and_transform_bdm(self, bdms, expected_bdms,
|
def _test_check_and_transform_bdm(self, bdms, expected_bdms,
|
||||||
image_bdms=None, base_options=None,
|
image_bdms=None, base_options=None,
|
||||||
|
@ -8468,9 +8509,11 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
base_options = base_options or {'root_device_name': 'vda',
|
base_options = base_options or {'root_device_name': 'vda',
|
||||||
'image_ref': FAKE_IMAGE_REF}
|
'image_ref': FAKE_IMAGE_REF}
|
||||||
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
||||||
base_options, {}, image_meta, 1, 1, bdms, legacy_bdms)
|
self.context, base_options, {},
|
||||||
self.assertThat(expected_bdms,
|
image_meta, 1, 1, bdms, legacy_bdms)
|
||||||
matchers.DictListMatches(transformed_bdm))
|
for expected, got in zip(expected_bdms, transformed_bdm):
|
||||||
|
self.assertThat(dict(expected.items()),
|
||||||
|
matchers.DictMatches(dict(got.items())))
|
||||||
|
|
||||||
def test_check_and_transform_legacy_bdm_no_image_bdms(self):
|
def test_check_and_transform_legacy_bdm_no_image_bdms(self):
|
||||||
legacy_bdms = [
|
legacy_bdms = [
|
||||||
|
@ -8480,6 +8523,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
expected_bdms = [block_device.BlockDeviceDict.from_legacy(
|
expected_bdms = [block_device.BlockDeviceDict.from_legacy(
|
||||||
legacy_bdms[0])]
|
legacy_bdms[0])]
|
||||||
expected_bdms[0]['boot_index'] = 0
|
expected_bdms[0]['boot_index'] = 0
|
||||||
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, expected_bdms)
|
||||||
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
||||||
legacy_bdms=True)
|
legacy_bdms=True)
|
||||||
|
|
||||||
|
@ -8497,6 +8542,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
block_device.BlockDeviceDict.from_legacy(image_bdms[0])]
|
block_device.BlockDeviceDict.from_legacy(image_bdms[0])]
|
||||||
expected_bdms[0]['boot_index'] = -1
|
expected_bdms[0]['boot_index'] = -1
|
||||||
expected_bdms[1]['boot_index'] = 0
|
expected_bdms[1]['boot_index'] = 0
|
||||||
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, expected_bdms)
|
||||||
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
||||||
image_bdms=image_bdms,
|
image_bdms=image_bdms,
|
||||||
legacy_bdms=True,
|
legacy_bdms=True,
|
||||||
|
@ -8515,6 +8562,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
block_device.BlockDeviceDict.from_legacy(legacy_bdms[0]),
|
block_device.BlockDeviceDict.from_legacy(legacy_bdms[0]),
|
||||||
image_bdms[0]]
|
image_bdms[0]]
|
||||||
expected_bdms[0]['boot_index'] = -1
|
expected_bdms[0]['boot_index'] = -1
|
||||||
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, expected_bdms)
|
||||||
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
self._test_check_and_transform_bdm(legacy_bdms, expected_bdms,
|
||||||
image_bdms=image_bdms,
|
image_bdms=image_bdms,
|
||||||
legacy_bdms=True)
|
legacy_bdms=True)
|
||||||
|
@ -8524,7 +8573,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
'image_id': FAKE_IMAGE_REF,
|
'image_id': FAKE_IMAGE_REF,
|
||||||
'boot_index': 0})]
|
'boot_index': 0})]
|
||||||
expected_bdms = bdms
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, bdms)
|
||||||
self._test_check_and_transform_bdm(bdms, expected_bdms)
|
self._test_check_and_transform_bdm(bdms, expected_bdms)
|
||||||
|
|
||||||
def test_check_and_transform_bdm_image_bdms(self):
|
def test_check_and_transform_bdm_image_bdms(self):
|
||||||
|
@ -8536,6 +8586,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
{'source_type': 'volume', 'destination_type': 'volume',
|
{'source_type': 'volume', 'destination_type': 'volume',
|
||||||
'volume_id': '33333333-aaaa-bbbb-cccc-444444444444'})]
|
'volume_id': '33333333-aaaa-bbbb-cccc-444444444444'})]
|
||||||
expected_bdms = bdms + image_bdms
|
expected_bdms = bdms + image_bdms
|
||||||
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, expected_bdms)
|
||||||
self._test_check_and_transform_bdm(bdms, expected_bdms,
|
self._test_check_and_transform_bdm(bdms, expected_bdms,
|
||||||
image_bdms=image_bdms)
|
image_bdms=image_bdms)
|
||||||
|
|
||||||
|
@ -8550,6 +8602,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
expected_bdms = [block_device.BlockDeviceDict.from_legacy(
|
expected_bdms = [block_device.BlockDeviceDict.from_legacy(
|
||||||
image_bdms[0])]
|
image_bdms[0])]
|
||||||
expected_bdms[0]['boot_index'] = 0
|
expected_bdms[0]['boot_index'] = 0
|
||||||
|
expected_bdms = block_device_obj.block_device_make_list_from_dicts(
|
||||||
|
self.context, expected_bdms)
|
||||||
self._test_check_and_transform_bdm(bdms, expected_bdms,
|
self._test_check_and_transform_bdm(bdms, expected_bdms,
|
||||||
image_bdms=image_bdms,
|
image_bdms=image_bdms,
|
||||||
legacy_image_bdms=True)
|
legacy_image_bdms=True)
|
||||||
|
@ -8569,30 +8623,26 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
|
|
||||||
# We get an image BDM
|
# We get an image BDM
|
||||||
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
||||||
base_options, {}, {}, 1, 1, fake_legacy_bdms, True)
|
self.context, base_options, {}, {}, 1, 1, fake_legacy_bdms, True)
|
||||||
self.assertEqual(len(transformed_bdm), 2)
|
self.assertEqual(len(transformed_bdm), 2)
|
||||||
|
|
||||||
# No image BDM created if image already defines a root BDM
|
# No image BDM created if image already defines a root BDM
|
||||||
base_options['root_device_name'] = 'vda'
|
base_options['root_device_name'] = 'vda'
|
||||||
base_options['image_ref'] = None
|
base_options['image_ref'] = None
|
||||||
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
||||||
base_options, {}, image_meta, 1, 1, [], True)
|
self.context, base_options, {}, image_meta, 1, 1, [], True)
|
||||||
self.assertEqual(len(transformed_bdm), 1)
|
self.assertEqual(len(transformed_bdm), 1)
|
||||||
|
|
||||||
# No image BDM created
|
# No image BDM created
|
||||||
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
||||||
base_options, {}, {}, 1, 1, fake_legacy_bdms, True)
|
self.context, base_options, {}, {}, 1, 1, fake_legacy_bdms, True)
|
||||||
self.assertEqual(len(transformed_bdm), 1)
|
self.assertEqual(len(transformed_bdm), 1)
|
||||||
|
|
||||||
# Volumes with multiple instances fails
|
# Volumes with multiple instances fails
|
||||||
self.assertRaises(exception.InvalidRequest,
|
self.assertRaises(exception.InvalidRequest,
|
||||||
self.compute_api._check_and_transform_bdm,
|
self.compute_api._check_and_transform_bdm, self.context,
|
||||||
base_options, {}, {}, 1, 2, fake_legacy_bdms, True)
|
base_options, {}, {}, 1, 2, fake_legacy_bdms, True)
|
||||||
|
|
||||||
checked_bdm = self.compute_api._check_and_transform_bdm(
|
|
||||||
base_options, {}, {}, 1, 1, transformed_bdm, True)
|
|
||||||
self.assertEqual(checked_bdm, transformed_bdm)
|
|
||||||
|
|
||||||
# Volume backed so no image_ref in base_options
|
# Volume backed so no image_ref in base_options
|
||||||
# v2 bdms contains a root image to volume mapping
|
# v2 bdms contains a root image to volume mapping
|
||||||
# image_meta contains a snapshot as the image
|
# image_meta contains a snapshot as the image
|
||||||
|
@ -8608,7 +8658,8 @@ class ComputeAPITestCase(BaseTestCase):
|
||||||
'volume_size': 1}]
|
'volume_size': 1}]
|
||||||
base_options['image_ref'] = None
|
base_options['image_ref'] = None
|
||||||
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
transformed_bdm = self.compute_api._check_and_transform_bdm(
|
||||||
base_options, {}, image_meta, 1, 1, fake_v2_bdms, False)
|
self.context, base_options, {}, image_meta, 1, 1,
|
||||||
|
fake_v2_bdms, False)
|
||||||
self.assertEqual(len(transformed_bdm), 1)
|
self.assertEqual(len(transformed_bdm), 1)
|
||||||
|
|
||||||
def test_volume_size(self):
|
def test_volume_size(self):
|
||||||
|
|
|
@ -2811,8 +2811,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||||
'volume_id': 'volume_id'}]
|
'volume_id': 'volume_id'}]
|
||||||
self.assertRaises(exception.InvalidRequest,
|
self.assertRaises(exception.InvalidRequest,
|
||||||
self.compute_api._check_and_transform_bdm,
|
self.compute_api._check_and_transform_bdm,
|
||||||
base_options, instance_type, image_meta, 1, 1,
|
self.context, base_options, instance_type,
|
||||||
block_device_mapping, legacy_bdm)
|
image_meta, 1, 1, block_device_mapping, legacy_bdm)
|
||||||
|
|
||||||
@mock.patch.object(objects.Instance, 'save')
|
@mock.patch.object(objects.Instance, 'save')
|
||||||
@mock.patch.object(objects.InstanceAction, 'action_start')
|
@mock.patch.object(objects.InstanceAction, 'action_start')
|
||||||
|
|
|
@ -181,14 +181,14 @@ class CellsComputeAPITestCase(test_compute.ComputeAPITestCase):
|
||||||
|
|
||||||
self.assertEqual(migrations, response)
|
self.assertEqual(migrations, response)
|
||||||
|
|
||||||
def test_update_block_device_mapping(self):
|
def test_create_block_device_mapping(self):
|
||||||
instance_type = {'swap': 1, 'ephemeral_gb': 1}
|
instance_type = {'swap': 1, 'ephemeral_gb': 1}
|
||||||
instance = self._create_fake_instance_obj()
|
instance = self._create_fake_instance_obj()
|
||||||
bdms = [block_device.BlockDeviceDict({'source_type': 'image',
|
bdms = [block_device.BlockDeviceDict({'source_type': 'image',
|
||||||
'destination_type': 'local',
|
'destination_type': 'local',
|
||||||
'image_id': 'fake-image',
|
'image_id': 'fake-image',
|
||||||
'boot_index': 0})]
|
'boot_index': 0})]
|
||||||
self.compute_api._update_block_device_mapping(
|
self.compute_api._create_block_device_mapping(
|
||||||
instance_type, instance.uuid, bdms)
|
instance_type, instance.uuid, bdms)
|
||||||
bdms = db.block_device_mapping_get_all_by_instance(
|
bdms = db.block_device_mapping_get_all_by_instance(
|
||||||
self.context, instance['uuid'])
|
self.context, instance['uuid'])
|
||||||
|
|
Loading…
Reference in New Issue