block_device: Add DriverImageBlockDevice to block_device_info
Change-Id: I17e0758e3b77caebd4d142664a8367ab4601ebdf
This commit is contained in:
parent
794d2f98d9
commit
5df97016b4
@ -71,6 +71,8 @@ called ``block_device_info``, and is generated by
|
||||
|
||||
``root_device_name``
|
||||
Hypervisor's notion of the root device's name
|
||||
``image``
|
||||
An image backed disk if used
|
||||
``ephemerals``
|
||||
A list of all ephemeral disks
|
||||
``block_device_mapping``
|
||||
@ -105,13 +107,6 @@ persist data to the BDM object in the DB.
|
||||
In other contexts this filtering will not have happened, and
|
||||
``block_device_mapping`` will contain all volumes.
|
||||
|
||||
.. note::
|
||||
|
||||
Unlike BDMs, ``block_device_info`` does not currently represent all
|
||||
disks that an instance might have. Significantly, it will not contain any
|
||||
representation of an image-backed local disk, i.e. the root disk of a
|
||||
typical instance which isn't boot-from-volume. Other representations used
|
||||
by the libvirt driver explicitly reconstruct this missing disk.
|
||||
|
||||
libvirt driver specific BDM data structures
|
||||
===========================================
|
||||
|
@ -2025,6 +2025,7 @@ class ComputeManager(manager.Manager):
|
||||
ephemerals = []
|
||||
swap = []
|
||||
block_device_mapping = []
|
||||
image = []
|
||||
|
||||
for device in block_devices:
|
||||
if block_device.new_format_is_ephemeral(device):
|
||||
@ -2036,8 +2037,12 @@ class ComputeManager(manager.Manager):
|
||||
if driver_block_device.is_block_device_mapping(device):
|
||||
block_device_mapping.append(device)
|
||||
|
||||
if driver_block_device.is_local_image(device):
|
||||
image.append(device)
|
||||
|
||||
self._default_device_names_for_instance(instance,
|
||||
root_device_name,
|
||||
image,
|
||||
ephemerals,
|
||||
swap,
|
||||
block_device_mapping)
|
||||
|
@ -1389,13 +1389,14 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
@mock.patch.object(nova.virt.block_device, 'convert_snapshots')
|
||||
@mock.patch.object(nova.virt.block_device, 'convert_volumes')
|
||||
@mock.patch.object(nova.virt.block_device, 'convert_ephemerals')
|
||||
@mock.patch.object(nova.virt.block_device, 'convert_local_images')
|
||||
@mock.patch.object(nova.virt.block_device, 'convert_swap')
|
||||
@mock.patch.object(nova.virt.block_device, 'attach_block_devices')
|
||||
def test_prep_block_device_with_blanks(self, attach_block_devices,
|
||||
convert_swap, convert_ephemerals,
|
||||
convert_volumes, convert_snapshots,
|
||||
convert_images, convert_blanks,
|
||||
get_swap):
|
||||
convert_swap, convert_local_images,
|
||||
convert_ephemerals, convert_volumes,
|
||||
convert_snapshots, convert_images,
|
||||
convert_blanks, get_swap):
|
||||
instance = self._create_fake_instance_obj()
|
||||
instance['root_device_name'] = '/dev/vda'
|
||||
root_volume = objects.BlockDeviceMapping(
|
||||
@ -1426,6 +1427,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
return bdm
|
||||
|
||||
convert_swap.return_value = []
|
||||
convert_local_images.return_value = []
|
||||
convert_ephemerals.return_value = []
|
||||
convert_volumes.return_value = [blank_volume1, blank_volume2]
|
||||
convert_snapshots.return_value = []
|
||||
@ -1438,6 +1440,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
'root_device_name': '/dev/vda',
|
||||
'swap': [],
|
||||
'ephemerals': [],
|
||||
'image': [],
|
||||
'block_device_mapping': bdms
|
||||
}
|
||||
|
||||
@ -1452,6 +1455,7 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
self.assertIsNotNone(bdm.device_name)
|
||||
|
||||
convert_swap.assert_called_once_with(bdms)
|
||||
convert_local_images.assert_called_once_with(bdms)
|
||||
convert_ephemerals.assert_called_once_with(bdms)
|
||||
bdm_args = tuple(bdms)
|
||||
convert_volumes.assert_called_once_with(bdm_args)
|
||||
@ -3212,6 +3216,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
expected = {
|
||||
'swap': None,
|
||||
'ephemerals': [],
|
||||
'image': [],
|
||||
'root_device_name': None,
|
||||
'block_device_mapping': driver_bdms
|
||||
}
|
||||
@ -3240,6 +3245,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
expected = {
|
||||
'swap': None,
|
||||
'ephemerals': [],
|
||||
'image': [],
|
||||
'root_device_name': None,
|
||||
'block_device_mapping': driver_bdms
|
||||
}
|
||||
@ -3318,6 +3324,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
'size': 2
|
||||
}
|
||||
],
|
||||
'image': [],
|
||||
'block_device_mapping': [],
|
||||
'root_device_name': None
|
||||
}
|
||||
@ -6108,7 +6115,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
mock_pre.assert_called_once_with(
|
||||
test.MatchType(nova.context.RequestContext),
|
||||
test.MatchType(objects.Instance),
|
||||
{'swap': None, 'ephemerals': [],
|
||||
{'swap': None, 'ephemerals': [], 'image': [],
|
||||
'root_device_name': None,
|
||||
'block_device_mapping': []},
|
||||
mock.ANY, mock.ANY, mock.ANY)
|
||||
@ -6474,7 +6481,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
self.assertEqual(2, mock_notify.call_count)
|
||||
post_live_migration.assert_has_calls([
|
||||
mock.call(c, instance, {'swap': None, 'ephemerals': [],
|
||||
'root_device_name': None,
|
||||
'image': [], 'root_device_name': None,
|
||||
'block_device_mapping': []},
|
||||
migrate_data)])
|
||||
migrate_instance_start.assert_has_calls([
|
||||
@ -6705,7 +6712,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
mock_setup.assert_called_once_with(c, instance, self.compute.host,
|
||||
teardown=True)
|
||||
mock_rollback.assert_called_once_with(c, instance, [],
|
||||
{'swap': None, 'ephemerals': [],
|
||||
{'swap': None, 'ephemerals': [], 'image': [],
|
||||
'root_device_name': None,
|
||||
'block_device_mapping': []},
|
||||
destroy_disks=True, migrate_data=None)
|
||||
@ -8134,7 +8141,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
self.compute._default_block_device_names(instance, {}, bdms)
|
||||
|
||||
self.assertEqual('/dev/vda', instance.root_device_name)
|
||||
mock_def.assert_called_once_with(instance, '/dev/vda', [], [],
|
||||
mock_def.assert_called_once_with(instance, '/dev/vda', [], [], [],
|
||||
[bdm for bdm in bdms])
|
||||
|
||||
@mock.patch.object(objects.BlockDeviceMapping, 'save')
|
||||
@ -8148,7 +8155,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
|
||||
self.compute._default_block_device_names(instance, {}, bdms)
|
||||
|
||||
mock_def.assert_called_once_with(instance, '/dev/vda', [], [],
|
||||
mock_def.assert_called_once_with(instance, '/dev/vda', [], [], [],
|
||||
[bdm for bdm in bdms])
|
||||
|
||||
@mock.patch.object(objects.Instance, 'save')
|
||||
@ -8170,7 +8177,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
self.assertEqual('/dev/vda', instance.root_device_name)
|
||||
mock_default_dev.assert_called_once_with(instance, mock.ANY, bdms[0])
|
||||
mock_default_name.assert_called_once_with(instance, '/dev/vda', [], [],
|
||||
[bdm for bdm in bdms])
|
||||
[], [bdm for bdm in bdms])
|
||||
|
||||
def test_default_block_device_names_with_blank_volumes(self):
|
||||
instance = self._create_fake_instance_obj()
|
||||
@ -8230,7 +8237,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
self.assertEqual('/dev/vda', instance.root_device_name)
|
||||
self.assertTrue(object_save.called)
|
||||
default_device_names.assert_called_once_with(instance,
|
||||
'/dev/vda', [bdms[-2]], [bdms[-1]],
|
||||
'/dev/vda', [], [bdms[-2]], [bdms[-1]],
|
||||
[bdm for bdm in bdms[:-2]])
|
||||
|
||||
def test_reserve_block_device_name(self):
|
||||
|
@ -74,6 +74,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
def _test_block_device_info(self, with_eph=True, with_swap=True,
|
||||
with_bdms=True):
|
||||
swap = {'device_name': '/dev/vdb', 'swap_size': 1}
|
||||
image = [{'device_type': 'disk', 'boot_index': 0}]
|
||||
ephemerals = [{'device_type': 'disk', 'guest_format': 'ext4',
|
||||
'device_name': '/dev/vdc1', 'size': 10},
|
||||
{'disk_bus': 'ide', 'guest_format': None,
|
||||
@ -84,6 +85,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
'device_path': 'fake_device'}]
|
||||
return {'root_device_name': '/dev/vda',
|
||||
'swap': swap if with_swap else {},
|
||||
'image': image,
|
||||
'ephemerals': ephemerals if with_eph else [],
|
||||
'block_device_mapping':
|
||||
block_device_mapping if with_bdms else []}
|
||||
@ -178,11 +180,16 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
]
|
||||
}
|
||||
with mock.patch.object(instance_ref, 'get_flavor',
|
||||
return_value=instance_ref.flavor) as get_flavor:
|
||||
mapping = blockinfo.get_disk_mapping("kvm", instance_ref,
|
||||
"virtio", "ide",
|
||||
image_meta)
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
# Since there was no block_device_info passed to get_disk_mapping we
|
||||
# expect to get the swap info from the flavor in the instance.
|
||||
get_flavor.assert_called_once_with()
|
||||
@ -202,7 +209,8 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
block_device_info = {
|
||||
'root_device_name': '/dev/sda'
|
||||
'root_device_name': '/dev/sda',
|
||||
'image': [{'device_type': 'disk', 'boot_index': 0}],
|
||||
}
|
||||
|
||||
mapping = blockinfo.get_disk_mapping("kvm", instance_ref,
|
||||
@ -490,9 +498,12 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
mapping = blockinfo.get_disk_mapping("lxc", instance_ref,
|
||||
"lxc", "lxc",
|
||||
image_meta)
|
||||
block_device_info = {
|
||||
'image': [{'device_type': 'disk', 'boot_index': 0}],
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"lxc", instance_ref, "lxc", "lxc", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
expect = {
|
||||
'disk': {'bus': 'lxc', 'dev': None,
|
||||
'type': 'disk', 'boot_index': '1'},
|
||||
@ -527,9 +538,14 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref.flavor.swap = 5
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
mapping = blockinfo.get_disk_mapping("kvm", instance_ref,
|
||||
"virtio", "ide",
|
||||
image_meta)
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
]
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
|
||||
expect = {
|
||||
'disk': {'bus': 'virtio', 'dev': 'vda',
|
||||
@ -549,6 +565,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref.ephemeral_gb = 0
|
||||
|
||||
block_dev_info = {'swap': None, 'root_device_name': u'/dev/vda',
|
||||
'image': [],
|
||||
'ephemerals': [],
|
||||
'block_device_mapping': [{'boot_index': None,
|
||||
'mount_device': u'/dev/vdb',
|
||||
@ -591,8 +608,14 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
]
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta)
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
|
||||
# Pick the first drive letter on the bus that is available
|
||||
# as the config drive. Delete the last device hardcode as
|
||||
@ -647,8 +670,14 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
]
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta)
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
|
||||
expect = {
|
||||
'disk': {
|
||||
@ -697,9 +726,14 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
mapping = blockinfo.get_disk_mapping("kvm", instance_ref,
|
||||
"virtio", "ide",
|
||||
image_meta)
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
]
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping(
|
||||
"kvm", instance_ref, "virtio", "ide", image_meta,
|
||||
block_device_info=block_device_info)
|
||||
|
||||
expect = {
|
||||
'disk': {'bus': 'virtio', 'dev': 'vda',
|
||||
@ -718,6 +752,9 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [
|
||||
{'device_type': 'disk', 'boot_index': 0},
|
||||
],
|
||||
'ephemerals': [
|
||||
{'device_type': 'disk', 'guest_format': 'ext4',
|
||||
'device_name': '/dev/vdb', 'size': 10},
|
||||
@ -754,6 +791,8 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
block_device_info = {
|
||||
'swap': {'device_name': '/dev/vdb',
|
||||
'swap_size': 10},
|
||||
'image': [{'device_type': 'disk',
|
||||
'boot_index': 0}],
|
||||
}
|
||||
mapping = blockinfo.get_disk_mapping("kvm", instance_ref,
|
||||
"virtio", "ide",
|
||||
@ -775,6 +814,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [],
|
||||
'block_device_mapping': [
|
||||
{'connection_info': "fake",
|
||||
'mount_device': "/dev/vda",
|
||||
@ -803,6 +843,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
image_meta = {}
|
||||
|
||||
block_device_info = {
|
||||
'image': [],
|
||||
'block_device_mapping': [
|
||||
{'connection_info': None,
|
||||
'mount_device': None,
|
||||
@ -858,6 +899,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
image_meta = objects.ImageMeta.from_dict(self.test_image_meta)
|
||||
|
||||
block_device_info = {
|
||||
'image': [],
|
||||
'block_device_mapping': [
|
||||
{'connection_info': "fake",
|
||||
'mount_device': "/dev/vda",
|
||||
@ -899,6 +941,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
'root_device_name': '/dev/vdf',
|
||||
'swap': {'device_name': '/dev/vdy',
|
||||
'swap_size': 10},
|
||||
'image': [{'device_type': 'disk', 'boot_index': 0}],
|
||||
'ephemerals': [
|
||||
{'device_type': 'disk', 'guest_format': 'ext4',
|
||||
'device_name': '/dev/vdb', 'size': 10},
|
||||
@ -940,6 +983,8 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
'swap': {'device_name': '/dev/vdb',
|
||||
'device_type': 'really_lame_type',
|
||||
'swap_size': 10},
|
||||
'image': [{'device_name': '/dev/vda',
|
||||
'device_type': 'disk'}],
|
||||
'ephemerals': [{'disk_bus': 'no_such_bus',
|
||||
'device_type': 'yeah_right',
|
||||
'device_name': '/dev/vdc', 'size': 10}],
|
||||
@ -951,6 +996,8 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
}
|
||||
expected_swap = {'device_name': '/dev/vdb', 'disk_bus': 'virtio',
|
||||
'device_type': 'disk', 'swap_size': 10}
|
||||
expected_image = {'device_name': '/dev/vda', 'device_type': 'disk',
|
||||
'disk_bus': 'virtio'}
|
||||
expected_ephemeral = {'disk_bus': 'virtio',
|
||||
'device_type': 'disk',
|
||||
'device_name': '/dev/vdc', 'size': 10}
|
||||
@ -970,6 +1017,7 @@ class LibvirtBlockInfoTest(test.NoDBTestCase):
|
||||
self.assertFalse(get_flavor_mock.called)
|
||||
|
||||
self.assertEqual(expected_swap, block_device_info['swap'])
|
||||
self.assertEqual(expected_image, block_device_info['image'][0])
|
||||
self.assertEqual(expected_ephemeral,
|
||||
block_device_info['ephemerals'][0])
|
||||
self.assertEqual(expected_bdm,
|
||||
@ -1441,6 +1489,15 @@ class DefaultDeviceNamesTestCase(test.NoDBTestCase):
|
||||
'destination_type': 'volume',
|
||||
'boot_index': -1}))]
|
||||
|
||||
self.image = [
|
||||
objects.BlockDeviceMapping(self.context,
|
||||
**fake_block_device.FakeDbBlockDeviceDict(
|
||||
{'id': 6, 'instance_uuid': uuids.instance,
|
||||
'source_type': 'image',
|
||||
'destination_type': 'local',
|
||||
'device_type': 'disk',
|
||||
'boot_index': 0}))]
|
||||
|
||||
def tearDown(self):
|
||||
super(DefaultDeviceNamesTestCase, self).tearDown()
|
||||
for patcher in self.patchers:
|
||||
@ -1450,7 +1507,7 @@ class DefaultDeviceNamesTestCase(test.NoDBTestCase):
|
||||
'nova.virt.libvirt.utils.get_arch',
|
||||
return_value=obj_fields.Architecture.X86_64)
|
||||
def _test_default_device_names(self, eph, swap, bdm, mock_get_arch):
|
||||
bdms = eph + swap + bdm
|
||||
bdms = self.image + eph + swap + bdm
|
||||
bdi = driver.get_block_device_info(self.instance, bdms)
|
||||
blockinfo.default_device_names(self.virt_type,
|
||||
self.context,
|
||||
|
@ -20410,7 +20410,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
**fake_block_device.FakeDbBlockDeviceDict(
|
||||
{'id': 0,
|
||||
'source_type': 'volume', 'destination_type': 'volume',
|
||||
'device_name': '/dev/sda'}))
|
||||
'device_name': '/dev/sda', 'boot_index': 0}))
|
||||
info = {'block_device_mapping': driver_block_device.convert_volumes(
|
||||
[bdm])}
|
||||
info['block_device_mapping'][0]['connection_info'] = conn_info
|
||||
@ -24941,7 +24941,8 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
'id': 1,
|
||||
'source_type': 'volume',
|
||||
'destination_type': 'volume',
|
||||
'device_name': '/dev/vda'}))
|
||||
'device_name': '/dev/vda',
|
||||
'boot_index': 0}))
|
||||
bdms = driver_block_device.convert_volumes([bdm])
|
||||
block_device_info = {'root_device_name': '/dev/vda',
|
||||
'ephemerals': [],
|
||||
|
@ -49,7 +49,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
'volume': driver_block_device.DriverVolumeBlockDevice,
|
||||
'volsnapshot': driver_block_device.DriverVolSnapshotBlockDevice,
|
||||
'volimage': driver_block_device.DriverVolImageBlockDevice,
|
||||
'volblank': driver_block_device.DriverVolBlankBlockDevice
|
||||
'volblank': driver_block_device.DriverVolBlankBlockDevice,
|
||||
'image': driver_block_device.DriverImageBlockDevice,
|
||||
}
|
||||
|
||||
swap_bdm_dict = block_device.BlockDeviceDict(
|
||||
@ -210,6 +211,27 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
'boot_index': -1,
|
||||
'volume_type': None}
|
||||
|
||||
image_bdm_dict = block_device.BlockDeviceDict(
|
||||
{'id': 7, 'instance_uuid': uuids.instance,
|
||||
'device_name': '/dev/vda',
|
||||
'source_type': 'image',
|
||||
'destination_type': 'local',
|
||||
'disk_bus': 'virtio',
|
||||
'device_type': 'disk',
|
||||
'guest_format': 'ext4',
|
||||
'boot_index': 0,
|
||||
'image_id': 'fake-image-id-1',
|
||||
'volume_size': 5})
|
||||
|
||||
image_driver_bdm = {
|
||||
'device_name': '/dev/vda',
|
||||
'device_type': 'disk',
|
||||
'guest_format': 'ext4',
|
||||
'disk_bus': 'virtio',
|
||||
'boot_index': 0,
|
||||
'image_id': 'fake-image-id-1',
|
||||
'size': 5}
|
||||
|
||||
def setUp(self):
|
||||
super(TestDriverBlockDevice, self).setUp()
|
||||
self.volume_api = mock.MagicMock(autospec=cinder.API)
|
||||
@ -219,6 +241,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
# create bdm objects for testing
|
||||
self.swap_bdm = fake_block_device.fake_bdm_object(
|
||||
self.context, self.swap_bdm_dict)
|
||||
self.image_bdm = fake_block_device.fake_bdm_object(
|
||||
self.context, self.image_bdm_dict)
|
||||
self.ephemeral_bdm = fake_block_device.fake_bdm_object(
|
||||
self.context, self.ephemeral_bdm_dict)
|
||||
self.volume_bdm = fake_block_device.fake_bdm_object(
|
||||
@ -337,6 +361,10 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
if field == 'attachment_id':
|
||||
# Must set UUID values on UUID fields.
|
||||
fake_value = ATTACHMENT_ID
|
||||
elif isinstance(test_bdm._bdm_obj.fields[fld],
|
||||
fields.UUIDField):
|
||||
# Generically handle other UUID fields.
|
||||
fake_value = uuids.fake_value
|
||||
else:
|
||||
fake_value = 'fake_changed_value'
|
||||
test_bdm[field] = fake_value
|
||||
@ -377,6 +405,20 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
def test_driver_swap_default_size(self):
|
||||
self._test_driver_default_size('swap')
|
||||
|
||||
def test_driver_image_block_device(self):
|
||||
self._test_driver_device("image")
|
||||
|
||||
def test_driver_image_default_size(self):
|
||||
self._test_driver_default_size('image')
|
||||
|
||||
def test_driver_image_block_device_destination_not_local(self):
|
||||
self._test_driver_device('image')
|
||||
bdm = self.image_bdm_dict.copy()
|
||||
bdm['destination_type'] = 'volume'
|
||||
self.assertRaises(driver_block_device._InvalidType,
|
||||
self.driver_classes['image'],
|
||||
fake_block_device.fake_bdm_object(self.context, bdm))
|
||||
|
||||
def test_driver_ephemeral_block_device(self):
|
||||
self._test_driver_device("ephemeral")
|
||||
|
||||
@ -406,7 +448,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
self.assertEqual(test_bdm.volume_size, 3)
|
||||
self.assertEqual('fake-snapshot-id-1', test_bdm.get('snapshot_id'))
|
||||
|
||||
def test_driver_image_block_device(self):
|
||||
def test_driver_volume_image_block_device(self):
|
||||
self._test_driver_device('volimage')
|
||||
|
||||
test_bdm = self.driver_classes['volimage'](
|
||||
@ -416,7 +458,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
self.assertEqual(test_bdm.volume_size, 1)
|
||||
self.assertEqual('fake-image-id-1', test_bdm.get('image_id'))
|
||||
|
||||
def test_driver_image_block_device_destination_local(self):
|
||||
def test_driver_volume_image_block_device_destination_local(self):
|
||||
self._test_driver_device('volimage')
|
||||
bdm = self.volimage_bdm_dict.copy()
|
||||
bdm['destination_type'] = 'local'
|
||||
@ -1263,12 +1305,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
|
||||
|
||||
def test_is_implemented(self):
|
||||
for bdm in (self.volimage_bdm, self.volume_bdm, self.swap_bdm,
|
||||
self.ephemeral_bdm, self.volsnapshot_bdm):
|
||||
self.ephemeral_bdm, self.volsnapshot_bdm, self.image_bdm):
|
||||
self.assertTrue(driver_block_device.is_implemented(bdm))
|
||||
local_image = self.volimage_bdm_dict.copy()
|
||||
local_image['destination_type'] = 'local'
|
||||
self.assertFalse(driver_block_device.is_implemented(
|
||||
fake_block_device.fake_bdm_object(self.context, local_image)))
|
||||
|
||||
def test_is_block_device_mapping(self):
|
||||
test_swap = self.driver_classes['swap'](self.swap_bdm)
|
||||
|
@ -227,6 +227,36 @@ class DriverSwapBlockDevice(DriverBlockDevice):
|
||||
})
|
||||
|
||||
|
||||
class DriverImageBlockDevice(DriverBlockDevice):
|
||||
_valid_source = 'image'
|
||||
_proxy_as_attr_inherited = set(['image_id'])
|
||||
_new_only_fields = set([
|
||||
'disk_bus',
|
||||
'device_type',
|
||||
'guest_format',
|
||||
'boot_index',
|
||||
])
|
||||
_fields = set([
|
||||
'device_name',
|
||||
'size']) | _new_only_fields
|
||||
_legacy_fields = (
|
||||
_fields - _new_only_fields | set(['num', 'virtual_name']))
|
||||
|
||||
def _transform(self):
|
||||
if (not self._bdm_obj.get('source_type') == 'image' or
|
||||
not self._bdm_obj.get('destination_type') == 'local'):
|
||||
raise _InvalidType
|
||||
self.update({
|
||||
'device_name': self._bdm_obj.device_name,
|
||||
'size': self._bdm_obj.volume_size or 0,
|
||||
'disk_bus': self._bdm_obj.disk_bus,
|
||||
'device_type': self._bdm_obj.device_type,
|
||||
'guest_format': self._bdm_obj.guest_format,
|
||||
'image_id': self._bdm_obj.image_id,
|
||||
'boot_index': 0,
|
||||
})
|
||||
|
||||
|
||||
class DriverEphemeralBlockDevice(DriverBlockDevice):
|
||||
_new_only_fields = set(['disk_bus', 'device_type', 'guest_format'])
|
||||
_fields = set(['device_name', 'size']) | _new_only_fields
|
||||
@ -802,15 +832,15 @@ def _convert_block_devices(device_type, block_device_mapping):
|
||||
convert_swap = functools.partial(_convert_block_devices,
|
||||
DriverSwapBlockDevice)
|
||||
|
||||
convert_local_images = functools.partial(_convert_block_devices,
|
||||
DriverImageBlockDevice)
|
||||
|
||||
convert_ephemerals = functools.partial(_convert_block_devices,
|
||||
DriverEphemeralBlockDevice)
|
||||
|
||||
|
||||
convert_volumes = functools.partial(_convert_block_devices,
|
||||
DriverVolumeBlockDevice)
|
||||
|
||||
|
||||
convert_snapshots = functools.partial(_convert_block_devices,
|
||||
DriverVolSnapshotBlockDevice)
|
||||
|
||||
@ -897,9 +927,15 @@ def get_swap(transformed_list):
|
||||
return None
|
||||
|
||||
|
||||
_IMPLEMENTED_CLASSES = (DriverSwapBlockDevice, DriverEphemeralBlockDevice,
|
||||
DriverVolumeBlockDevice, DriverVolSnapshotBlockDevice,
|
||||
DriverVolImageBlockDevice, DriverVolBlankBlockDevice)
|
||||
_IMPLEMENTED_CLASSES = (
|
||||
DriverSwapBlockDevice,
|
||||
DriverEphemeralBlockDevice,
|
||||
DriverVolumeBlockDevice,
|
||||
DriverVolSnapshotBlockDevice,
|
||||
DriverVolImageBlockDevice,
|
||||
DriverVolBlankBlockDevice,
|
||||
DriverImageBlockDevice
|
||||
)
|
||||
|
||||
|
||||
def is_implemented(bdm):
|
||||
@ -912,6 +948,10 @@ def is_implemented(bdm):
|
||||
return False
|
||||
|
||||
|
||||
def is_local_image(bdm):
|
||||
return bdm.source_type == 'image' and bdm.destination_type == 'local'
|
||||
|
||||
|
||||
def is_block_device_mapping(bdm):
|
||||
return (bdm.source_type in ('image', 'volume', 'snapshot', 'blank') and
|
||||
bdm.destination_type == 'volume' and
|
||||
|
@ -44,6 +44,7 @@ def get_block_device_info(instance, block_device_mapping):
|
||||
of a dict containing the following keys:
|
||||
|
||||
- root_device_name: device name of the root disk
|
||||
- image: An instance of DriverImageBlockDevice or None
|
||||
- ephemerals: a (potentially empty) list of DriverEphemeralBlockDevice
|
||||
instances
|
||||
- swap: An instance of DriverSwapBlockDevice or None
|
||||
@ -54,6 +55,8 @@ def get_block_device_info(instance, block_device_mapping):
|
||||
from nova.virt import block_device as virt_block_device
|
||||
return {
|
||||
'root_device_name': instance.root_device_name,
|
||||
'image': virt_block_device.convert_local_images(
|
||||
block_device_mapping),
|
||||
'ephemerals': virt_block_device.convert_ephemerals(
|
||||
block_device_mapping),
|
||||
'block_device_mapping':
|
||||
@ -79,6 +82,14 @@ def swap_is_usable(swap):
|
||||
return swap and swap['device_name'] and swap['swap_size'] > 0
|
||||
|
||||
|
||||
def block_device_info_get_image(block_device_info):
|
||||
block_device_info = block_device_info or {}
|
||||
# get_disk_mapping() supports block_device_info=None and thus requires that
|
||||
# we return a list here.
|
||||
image = block_device_info.get('image') or []
|
||||
return image
|
||||
|
||||
|
||||
def block_device_info_get_ephemerals(block_device_info):
|
||||
block_device_info = block_device_info or {}
|
||||
ephemerals = block_device_info.get('ephemerals') or []
|
||||
|
@ -414,13 +414,7 @@ def get_device_name(bdm):
|
||||
def get_root_info(instance, virt_type, image_meta, root_bdm,
|
||||
disk_bus, cdrom_bus, root_device_name=None):
|
||||
|
||||
# NOTE (ndipanov): This is a hack to avoid considering an image
|
||||
# BDM with local target, as we don't support them
|
||||
# yet. Only applies when passed non-driver format
|
||||
no_root_bdm = (not root_bdm or (
|
||||
root_bdm.get('source_type') == 'image' and
|
||||
root_bdm.get('destination_type') == 'local'))
|
||||
if no_root_bdm:
|
||||
if root_bdm is None:
|
||||
# NOTE(mriedem): In case the image_meta object was constructed from
|
||||
# an empty dict, like in the case of evacuate, we have to first check
|
||||
# if disk_format is set on the ImageMeta object.
|
||||
@ -452,10 +446,13 @@ def default_device_names(virt_type, context, instance, block_device_info,
|
||||
image_meta):
|
||||
get_disk_info(virt_type, instance, image_meta, block_device_info)
|
||||
|
||||
for driver_bdm in itertools.chain(block_device_info['ephemerals'],
|
||||
[block_device_info['swap']] if
|
||||
block_device_info['swap'] else [],
|
||||
block_device_info['block_device_mapping']):
|
||||
for driver_bdm in itertools.chain(
|
||||
block_device_info['image'],
|
||||
block_device_info['ephemerals'],
|
||||
[block_device_info['swap']] if
|
||||
block_device_info['swap'] else [],
|
||||
block_device_info['block_device_mapping']
|
||||
):
|
||||
driver_bdm.save()
|
||||
|
||||
|
||||
@ -563,41 +560,48 @@ def _get_disk_mapping(virt_type, instance, disk_bus, cdrom_bus, image_meta,
|
||||
:returns: Disk mapping for the given instance.
|
||||
"""
|
||||
mapping = {}
|
||||
pre_assigned_device_names = \
|
||||
[block_device.strip_dev(get_device_name(bdm)) for bdm in itertools.chain(
|
||||
|
||||
driver_bdms = itertools.chain(
|
||||
driver.block_device_info_get_image(block_device_info),
|
||||
driver.block_device_info_get_ephemerals(block_device_info),
|
||||
[driver.block_device_info_get_swap(block_device_info)],
|
||||
driver.block_device_info_get_mapping(block_device_info))
|
||||
if get_device_name(bdm)]
|
||||
driver.block_device_info_get_mapping(block_device_info)
|
||||
)
|
||||
|
||||
# NOTE (ndipanov): root_bdm can be None when we boot from image
|
||||
# as there is no driver representation of local targeted images
|
||||
# and they will not be in block_device_info list.
|
||||
root_bdm = block_device.get_root_bdm(
|
||||
driver.block_device_info_get_mapping(block_device_info))
|
||||
pre_assigned_device_names = [
|
||||
block_device.strip_dev(get_device_name(bdm))
|
||||
for bdm in driver_bdms if get_device_name(bdm)
|
||||
]
|
||||
|
||||
# Try to find the root driver bdm, either an image based disk or volume
|
||||
root_bdm = None
|
||||
if any(driver.block_device_info_get_image(block_device_info)):
|
||||
root_bdm = driver.block_device_info_get_image(block_device_info)[0]
|
||||
elif driver.block_device_info_get_mapping(block_device_info):
|
||||
root_bdm = block_device.get_root_bdm(
|
||||
driver.block_device_info_get_mapping(block_device_info))
|
||||
root_device_name = block_device.strip_dev(
|
||||
driver.block_device_info_get_root_device(block_device_info))
|
||||
root_info = get_root_info(
|
||||
instance, virt_type, image_meta, root_bdm,
|
||||
disk_bus, cdrom_bus, root_device_name)
|
||||
|
||||
mapping['root'] = root_info
|
||||
# NOTE (ndipanov): This implicitly relies on image->local BDMs not
|
||||
# being considered in the driver layer - so missing
|
||||
# bdm with boot_index 0 means - use image, unless it was
|
||||
# overridden. This can happen when using legacy syntax and
|
||||
# no root_device_name is set on the instance.
|
||||
if not root_bdm and not block_device.volume_in_mapping(root_info['dev'],
|
||||
block_device_info):
|
||||
mapping['disk'] = root_info
|
||||
elif root_bdm:
|
||||
# NOTE (ft): If device name is not set in root bdm, root_info has a
|
||||
# generated one. We have to copy device name to root bdm to prevent its
|
||||
# second generation in loop through bdms. If device name is already
|
||||
# set, nothing is changed.
|
||||
|
||||
# NOTE (ft): If device name is not set in root bdm, root_info has a
|
||||
# generated one. We have to copy device name to root bdm to prevent its
|
||||
# second generation in loop through bdms. If device name is already
|
||||
# set, nothing is changed.
|
||||
# NOTE(melwitt): root_bdm can be None in the case of a ISO root device, for
|
||||
# example.
|
||||
if root_bdm:
|
||||
update_bdm(root_bdm, root_info)
|
||||
|
||||
if (
|
||||
driver.block_device_info_get_image(block_device_info) or
|
||||
root_bdm is None
|
||||
):
|
||||
mapping['disk'] = root_info
|
||||
|
||||
default_eph = get_default_ephemeral_info(instance, disk_bus,
|
||||
block_device_info, mapping)
|
||||
if default_eph:
|
||||
|
Loading…
x
Reference in New Issue
Block a user