Add compute version 36 to support `volume_type
`
Add support specifying ``volume_type`` to storage backend when booting instance in compute version 36. bp: boot-instance-specific-storage-backend Change-Id: Icc301230fe7c8e3ebbbcc7f4a807e562db7f93e3
This commit is contained in:
parent
f180025669
commit
88766d33a3
@ -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'},
|
||||
)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user