Merge "Add compute version 36 to support ``volume_type``"

This commit is contained in:
Zuul 2018-10-12 05:54:37 +00:00 committed by Gerrit Code Review
commit 67ac57b325
3 changed files with 190 additions and 19 deletions

View File

@ -31,7 +31,7 @@ LOG = logging.getLogger(__name__)
# NOTE(danms): This is the global service version counter
SERVICE_VERSION = 35
SERVICE_VERSION = 36
# NOTE(danms): This is our SERVICE_VERSION history. The idea is that any
@ -146,6 +146,9 @@ SERVICE_VERSION_HISTORY = (
# Version 35: Indicates that nova-compute supports live migration with
# ports bound early on the destination host using VIFMigrateData.
{'compute_rpc': '5.0'},
# Version 36: Indicates that nova-compute supports specifying volume
# type when booting a volume-backed server.
{'compute_rpc': '5.0'},
)

View File

@ -112,7 +112,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'disk_bus': 'scsi',
'device_type': 'disk',
'guest_format': 'ext4',
'boot_index': 0}
'boot_index': 0,
'volume_type': None}
volume_legacy_driver_bdm = {
'mount_device': '/dev/sda1',
@ -131,7 +132,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'connection_info': '{"fake": "connection_info"}',
'snapshot_id': 'fake-snapshot-id-1',
'volume_id': 'fake-volume-id-2',
'boot_index': -1})
'boot_index': -1,
'volume_type': None})
volsnapshot_driver_bdm = {
'mount_device': '/dev/sda2',
@ -140,7 +142,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'disk_bus': 'scsi',
'device_type': 'disk',
'guest_format': None,
'boot_index': -1}
'boot_index': -1,
'volume_type': None}
volsnapshot_legacy_driver_bdm = {
'mount_device': '/dev/sda2',
@ -159,7 +162,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'connection_info': '{"fake": "connection_info"}',
'image_id': 'fake-image-id-1',
'volume_id': 'fake-volume-id-2',
'boot_index': -1})
'boot_index': -1,
'volume_type': None})
volimage_driver_bdm = {
'mount_device': '/dev/sda2',
@ -168,7 +172,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'disk_bus': 'scsi',
'device_type': 'disk',
'guest_format': None,
'boot_index': -1}
'boot_index': -1,
'volume_type': None}
volimage_legacy_driver_bdm = {
'mount_device': '/dev/sda2',
@ -187,7 +192,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'connection_info': '{"fake": "connection_info"}',
'snapshot_id': 'fake-snapshot-id-1',
'volume_id': 'fake-volume-id-2',
'boot_index': -1})
'boot_index': -1,
'volume_type': None})
volblank_driver_bdm = {
'mount_device': '/dev/sda2',
@ -196,7 +202,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'disk_bus': 'scsi',
'device_type': 'disk',
'guest_format': None,
'boot_index': -1}
'boot_index': -1,
'volume_type': None}
volblank_legacy_driver_bdm = {
'mount_device': '/dev/sda2',
@ -851,7 +858,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
self.volume_api.get_snapshot(self.context,
'fake-snapshot-id-1').AndReturn(snapshot)
self.volume_api.create(self.context, 3, '', '', snapshot,
availability_zone=None).AndReturn(volume)
availability_zone=None,
volume_type=None).AndReturn(volume)
wait_func(self.context, 'fake-volume-id-2').AndReturn(None)
instance, expected_conn_info = self._test_volume_attach(
test_bdm, no_volume_snapshot, volume)
@ -883,7 +891,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
self.volume_api.get_snapshot(self.context,
'fake-snapshot-id-1').AndReturn(snapshot)
self.volume_api.create(self.context, 3, '', '', snapshot,
availability_zone='test-az').AndReturn(volume)
availability_zone='test-az',
volume_type=None).AndReturn(volume)
wait_func(self.context, 'fake-volume-id-2').AndReturn(None)
instance, expected_conn_info = self._test_volume_attach(
test_bdm, no_volume_snapshot, volume,
@ -930,7 +939,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
vol_get_snap.assert_called_once_with(
self.context, 'fake-snapshot-id-1')
vol_create.assert_called_once_with(
self.context, 3, '', '', snapshot, availability_zone=None)
self.context, 3, '', '', snapshot, availability_zone=None,
volume_type=None)
vol_delete.assert_called_once_with(self.context, volume['id'])
def test_snapshot_attach_volume(self):
@ -970,7 +980,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
wait_func = self.mox.CreateMockAnything()
self.volume_api.create(self.context, 1, '', '', image_id=image['id'],
availability_zone=None).AndReturn(volume)
availability_zone=None,
volume_type=None).AndReturn(volume)
wait_func(self.context, 'fake-volume-id-2').AndReturn(None)
instance, expected_conn_info = self._test_volume_attach(
test_bdm, no_volume_image, volume)
@ -999,7 +1010,8 @@ class TestDriverBlockDevice(test.NoDBTestCase):
wait_func = self.mox.CreateMockAnything()
self.volume_api.create(self.context, 1, '', '', image_id=image['id'],
availability_zone='test-az').AndReturn(volume)
availability_zone='test-az',
volume_type=None).AndReturn(volume)
wait_func(self.context, 'fake-volume-id-2').AndReturn(None)
instance, expected_conn_info = self._test_volume_attach(
test_bdm, no_volume_image, volume,
@ -1042,7 +1054,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
vol_create.assert_called_once_with(
self.context, 1, '', '', image_id=image['id'],
availability_zone=None)
availability_zone=None, volume_type=None)
vol_delete.assert_called_once_with(self.context, volume['id'])
def test_image_attach_volume(self):
@ -1097,7 +1109,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size,
'%s-blank-vol' % uuids.uuid,
'', availability_zone=None)
'', volume_type=None, availability_zone=None)
vol_delete.assert_called_once_with(
self.context, volume['id'])
@ -1123,7 +1135,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size,
'%s-blank-vol' % uuids.uuid,
'', availability_zone=None)
'', volume_type=None, availability_zone=None)
vol_attach.assert_called_once_with(self.context, instance,
self.volume_api,
self.virt_driver)
@ -1154,7 +1166,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size,
'%s-blank-vol' % uuids.uuid,
'', availability_zone='test-az')
'', volume_type=None, availability_zone='test-az')
vol_attach.assert_called_once_with(self.context, instance,
self.volume_api,
self.virt_driver)
@ -1319,6 +1331,155 @@ class TestDriverBlockDevice(test.NoDBTestCase):
self.assertEqual(set(['uuid', 'is_volume', 'B', 'C', 'E']),
E(bdm)._proxy_as_attr)
def _test_boot_from_volume_source_blank_volume_type(
self, bdm, expected_volume_type):
self.flags(cross_az_attach=False, group='cinder')
test_bdm = self.driver_classes['volblank'](bdm)
updates = {'uuid': uuids.uuid, 'availability_zone': 'test-az'}
instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
**updates)
volume_class = self.driver_classes['volume']
volume = {'id': 'fake-volume-id-2',
'display_name': '%s-blank-vol' % uuids.uuid}
with mock.patch.object(self.volume_api, 'create',
return_value=volume) as vol_create:
with mock.patch.object(volume_class, 'attach') as vol_attach:
test_bdm.attach(self.context, instance, self.volume_api,
self.virt_driver)
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size,
'%s-blank-vol' % uuids.uuid, '',
volume_type=expected_volume_type,
availability_zone='test-az')
vol_attach.assert_called_once_with(
self.context, instance, self.volume_api, self.virt_driver)
self.assertEqual('fake-volume-id-2', test_bdm.volume_id)
def test_boot_from_volume_source_blank_with_unset_volume_type(self):
"""Tests the scenario that the BlockDeviceMapping.volume_type field
is unset for RPC compatibility to an older compute.
"""
no_blank_volume = self.volblank_bdm_dict.copy()
no_blank_volume['volume_id'] = None
bdm = fake_block_device.fake_bdm_object(self.context, no_blank_volume)
delattr(bdm, 'volume_type')
self.assertNotIn('volume_type', bdm)
self._test_boot_from_volume_source_blank_volume_type(bdm, None)
def test_boot_from_volume_source_blank_with_volume_type(self):
# Tests that the blank volume created specifies the volume type.
no_blank_volume = self.volblank_bdm_dict.copy()
no_blank_volume['volume_id'] = None
no_blank_volume['volume_type'] = 'fake-lvm-1'
bdm = fake_block_device.fake_bdm_object(self.context, no_blank_volume)
self._test_boot_from_volume_source_blank_volume_type(bdm, 'fake-lvm-1')
def _test_boot_from_volume_source_image_volume_type(
self, bdm, expected_volume_type):
self.flags(cross_az_attach=False, group='cinder')
test_bdm = self.driver_classes['volimage'](bdm)
updates = {'uuid': uuids.uuid, 'availability_zone': 'test-az'}
instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
**updates)
volume_class = self.driver_classes['volume']
image = {'id': 'fake-image-id-1'}
volume = {'id': 'fake-volume-id-2',
'display_name': 'fake-image-vol'}
with mock.patch.object(self.volume_api, 'create',
return_value=volume) as vol_create:
with mock.patch.object(volume_class, 'attach') as vol_attach:
test_bdm.attach(self.context, instance, self.volume_api,
self.virt_driver)
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size,
'', '', image_id=image['id'],
volume_type=expected_volume_type,
availability_zone='test-az')
vol_attach.assert_called_once_with(
self.context, instance, self.volume_api, self.virt_driver)
self.assertEqual('fake-volume-id-2', test_bdm.volume_id)
def test_boot_from_volume_source_image_with_unset_volume_type(self):
"""Tests the scenario that the BlockDeviceMapping.volume_type field
is unset for RPC compatibility to an older compute.
"""
no_volume_image = self.volimage_bdm_dict.copy()
no_volume_image['volume_id'] = None
bdm = fake_block_device.fake_bdm_object(self.context, no_volume_image)
delattr(bdm, 'volume_type')
self.assertNotIn('volume_type', bdm)
self._test_boot_from_volume_source_image_volume_type(bdm, None)
def test_boot_from_volume_source_image_with_volume_type(self):
# Tests that the volume created from the image specifies the volume
# type.
no_volume_image = self.volimage_bdm_dict.copy()
no_volume_image['volume_id'] = None
no_volume_image['volume_type'] = 'fake-lvm-1'
bdm = fake_block_device.fake_bdm_object(self.context, no_volume_image)
self._test_boot_from_volume_source_image_volume_type(bdm, 'fake-lvm-1')
def _test_boot_from_volume_source_snapshot_volume_type(
self, bdm, expected_volume_type):
self.flags(cross_az_attach=False, group='cinder')
test_bdm = self.driver_classes['volsnapshot'](bdm)
snapshot = {'id': 'fake-snapshot-id-1',
'attach_status': 'detached'}
updates = {'uuid': uuids.uuid, 'availability_zone': 'test-az'}
instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
**updates)
volume_class = self.driver_classes['volume']
volume = {'id': 'fake-volume-id-2',
'display_name': 'fake-snapshot-vol'}
with test.nested(
mock.patch.object(self.volume_api, 'create', return_value=volume),
mock.patch.object(self.volume_api, 'get_snapshot',
return_value=snapshot),
mock.patch.object(volume_class, 'attach')
) as (
vol_create, vol_get_snap, vol_attach
):
test_bdm.attach(self.context, instance, self.volume_api,
self.virt_driver)
vol_create.assert_called_once_with(
self.context, test_bdm.volume_size, '', '', snapshot,
volume_type=expected_volume_type, availability_zone='test-az')
vol_attach.assert_called_once_with(
self.context, instance, self.volume_api, self.virt_driver)
self.assertEqual('fake-volume-id-2', test_bdm.volume_id)
def test_boot_from_volume_source_snapshot_with_unset_volume_type(self):
"""Tests the scenario that the BlockDeviceMapping.volume_type field
is unset for RPC compatibility to an older compute.
"""
no_volume_snapshot = self.volsnapshot_bdm_dict.copy()
no_volume_snapshot['volume_id'] = None
bdm = fake_block_device.fake_bdm_object(
self.context, no_volume_snapshot)
delattr(bdm, 'volume_type')
self.assertNotIn('volume_type', bdm)
self._test_boot_from_volume_source_snapshot_volume_type(bdm, None)
def test_boot_from_volume_source_snapshot_with_volume_type(self):
# Tests that the volume created from the snapshot specifies the volume
# type.
no_volume_snapshot = self.volsnapshot_bdm_dict.copy()
no_volume_snapshot['volume_id'] = None
no_volume_snapshot['volume_type'] = 'fake-lvm-1'
bdm = fake_block_device.fake_bdm_object(
self.context, no_volume_snapshot)
self._test_boot_from_volume_source_snapshot_volume_type(
bdm, 'fake-lvm-1')
class TestDriverBlockDeviceNewFlow(TestDriverBlockDevice):
"""Virt block_device tests for the Cinder 3.44 volume attach flow

View File

@ -265,7 +265,7 @@ class DriverVolumeBlockDevice(DriverBlockDevice):
_valid_source = 'volume'
_valid_destination = 'volume'
_proxy_as_attr_inherited = set(['volume_size', 'volume_id'])
_proxy_as_attr_inherited = set(['volume_size', 'volume_id', 'volume_type'])
_update_on_save = {'disk_bus': None,
'device_name': 'mount_device',
'device_type': None}
@ -286,6 +286,10 @@ class DriverVolumeBlockDevice(DriverBlockDevice):
self._bdm_obj.connection_info)
except TypeError:
self['connection_info'] = None
# volume_type might not be set on the internal bdm object so default
# to None if not set
self['volume_type'] = (
self.volume_type if 'volume_type' in self._bdm_obj else None)
def _preserve_multipath_id(self, connection_info):
if self['connection_info'] and 'data' in self['connection_info']:
@ -710,7 +714,8 @@ class DriverVolSnapshotBlockDevice(DriverVolumeBlockDevice):
snapshot = volume_api.get_snapshot(context,
self.snapshot_id)
vol = volume_api.create(context, self.volume_size, '', '',
snapshot, availability_zone=av_zone)
snapshot, volume_type=self.volume_type,
availability_zone=av_zone)
if wait_func:
self._call_wait_func(context, wait_func, volume_api, vol['id'])
@ -735,6 +740,7 @@ class DriverVolImageBlockDevice(DriverVolumeBlockDevice):
av_zone = _get_volume_create_az_value(instance)
vol = volume_api.create(context, self.volume_size,
'', '', image_id=self.image_id,
volume_type=self.volume_type,
availability_zone=av_zone)
if wait_func:
self._call_wait_func(context, wait_func, volume_api, vol['id'])
@ -759,6 +765,7 @@ class DriverVolBlankBlockDevice(DriverVolumeBlockDevice):
vol_name = instance.uuid + '-blank-vol'
av_zone = _get_volume_create_az_value(instance)
vol = volume_api.create(context, self.volume_size, vol_name, '',
volume_type=self.volume_type,
availability_zone=av_zone)
if wait_func:
self._call_wait_func(context, wait_func, volume_api, vol['id'])