Merge "Support 'multiattach' for cinder volume"
This commit is contained in:
commit
3f6a109b0f
|
@ -34,23 +34,23 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
|
|||
PROPERTIES = (
|
||||
AVAILABILITY_ZONE, SIZE, SNAPSHOT_ID, BACKUP_ID, NAME,
|
||||
DESCRIPTION, VOLUME_TYPE, METADATA, IMAGE_REF, IMAGE,
|
||||
SOURCE_VOLID, CINDER_SCHEDULER_HINTS, READ_ONLY,
|
||||
SOURCE_VOLID, CINDER_SCHEDULER_HINTS, READ_ONLY, MULTI_ATTACH,
|
||||
) = (
|
||||
'availability_zone', 'size', 'snapshot_id', 'backup_id', 'name',
|
||||
'description', 'volume_type', 'metadata', 'imageRef', 'image',
|
||||
'source_volid', 'scheduler_hints', 'read_only',
|
||||
'source_volid', 'scheduler_hints', 'read_only', 'multiattach',
|
||||
)
|
||||
|
||||
ATTRIBUTES = (
|
||||
AVAILABILITY_ZONE_ATTR, SIZE_ATTR, SNAPSHOT_ID_ATTR, DISPLAY_NAME_ATTR,
|
||||
DISPLAY_DESCRIPTION_ATTR, VOLUME_TYPE_ATTR, METADATA_ATTR,
|
||||
SOURCE_VOLID_ATTR, STATUS, CREATED_AT, BOOTABLE, METADATA_VALUES_ATTR,
|
||||
ENCRYPTED_ATTR, ATTACHMENTS,
|
||||
ENCRYPTED_ATTR, ATTACHMENTS, MULTI_ATTACH_ATTR,
|
||||
) = (
|
||||
'availability_zone', 'size', 'snapshot_id', 'display_name',
|
||||
'display_description', 'volume_type', 'metadata',
|
||||
'source_volid', 'status', 'created_at', 'bootable', 'metadata_values',
|
||||
'encrypted', 'attachments',
|
||||
'encrypted', 'attachments', 'multiattach',
|
||||
)
|
||||
|
||||
properties_schema = {
|
||||
|
@ -146,6 +146,12 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
|
|||
support_status=support.SupportStatus(version='5.0.0'),
|
||||
update_allowed=True,
|
||||
),
|
||||
MULTI_ATTACH: properties.Schema(
|
||||
properties.Schema.BOOLEAN,
|
||||
_('Whether allow the volume to be attached more than once. '
|
||||
'This property is only supported from Cinder API v2.'),
|
||||
support_status=support.SupportStatus(version='6.0.0'),
|
||||
),
|
||||
}
|
||||
|
||||
attributes_schema = {
|
||||
|
@ -205,6 +211,12 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
|
|||
_('The list of attachments of the volume.'),
|
||||
type=attributes.Schema.STRING
|
||||
),
|
||||
MULTI_ATTACH_ATTR: attributes.Schema(
|
||||
_('Boolean indicating whether allow the volume to be attached '
|
||||
'more than once.'),
|
||||
type=attributes.Schema.BOOLEAN,
|
||||
support_status=support.SupportStatus(version='6.0.0'),
|
||||
),
|
||||
}
|
||||
|
||||
_volume_creating_status = ['creating', 'restoring-backup', 'downloading']
|
||||
|
@ -248,9 +260,10 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
|
|||
arguments['imageRef'] = self.properties[self.IMAGE_REF]
|
||||
|
||||
optionals = (self.SNAPSHOT_ID, self.VOLUME_TYPE, self.SOURCE_VOLID,
|
||||
self.METADATA)
|
||||
self.METADATA, self.MULTI_ATTACH)
|
||||
|
||||
arguments.update((prop, self.properties[prop]) for prop in optionals
|
||||
if self.properties[prop])
|
||||
if self.properties[prop] is not None)
|
||||
|
||||
return arguments
|
||||
|
||||
|
@ -562,6 +575,13 @@ class CinderVolume(vb.BaseVolume, sh.SchedulerHintsMixin):
|
|||
raise exception.StackValidationFailed(
|
||||
message=_('Scheduler hints are not supported by the current '
|
||||
'volume API.'))
|
||||
# Multi attach is only supported from Cinder API v2
|
||||
if (self.properties[self.MULTI_ATTACH]
|
||||
and self.client().volume_api_version == 1):
|
||||
raise exception.StackValidationFailed(
|
||||
message=_('Multiple attach is not supported by the current '
|
||||
'volume API. Use this property since '
|
||||
'Cinder API v2.'))
|
||||
# can not specify both image and imageRef
|
||||
image = self.properties.get(self.IMAGE)
|
||||
imageRef = self.properties.get(self.IMAGE_REF)
|
||||
|
|
|
@ -57,6 +57,13 @@ resources:
|
|||
size: 1
|
||||
name: test_name
|
||||
scheduler_hints: {"hint1": "good_advice"}
|
||||
volume4:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
availability_zone: nova
|
||||
size: 1
|
||||
name: test_name
|
||||
multiattach: True
|
||||
attachment:
|
||||
type: OS::Cinder::VolumeAttachment
|
||||
properties:
|
||||
|
@ -238,7 +245,7 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
|
|||
description='desc', volume_type='lvm',
|
||||
metadata={'key': 'value'}, source_volid=None,
|
||||
bootable=False, created_at='2013-02-25T02:40:21.000000',
|
||||
encrypted=False, attachments=[])
|
||||
encrypted=False, attachments=[], multiattach=False)
|
||||
self.cinder_fc.volumes.get('vol-123').MultipleTimes().AndReturn(fv)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -264,6 +271,7 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
|
|||
self.assertEqual(u'False', rsrc.FnGetAtt('encrypted'))
|
||||
self.assertEqual(u'[]', rsrc.FnGetAtt('attachments'))
|
||||
self.assertEqual({'volume': 'info'}, rsrc.FnGetAtt('show'))
|
||||
self.assertEqual('False', rsrc.FnGetAtt('multiattach'))
|
||||
error = self.assertRaises(exception.InvalidTemplateAttribute,
|
||||
rsrc.FnGetAtt, 'unknown')
|
||||
self.assertEqual(
|
||||
|
@ -928,6 +936,26 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
|
|||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_cinder_create_with_multiattach(self):
|
||||
fv = vt_base.FakeVolume('creating')
|
||||
|
||||
cinder.CinderClientPlugin._create().AndReturn(self.cinder_fc)
|
||||
self.cinder_fc.volumes.create(
|
||||
size=1, name='test_name', description=None,
|
||||
availability_zone='nova',
|
||||
multiattach=True).AndReturn(fv)
|
||||
self.cinder_fc.volumes.get(fv.id).AndReturn(fv)
|
||||
fv_ready = vt_base.FakeVolume('available', id=fv.id)
|
||||
self.cinder_fc.volumes.get(fv.id).AndReturn(fv_ready)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
stack_name = 'test_cvolume_multiattach_stack'
|
||||
stack = utils.parse_stack(self.t, stack_name=stack_name)
|
||||
self.create_volume(self.t, stack, 'volume4')
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_cinder_create_with_scheduler_hints_and_cinder_api_v1(self):
|
||||
cinder.CinderClientPlugin._create().AndReturn(self.cinder_fc)
|
||||
self.cinder_fc.volume_api_version = 1
|
||||
|
@ -978,6 +1006,22 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
|
|||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_cinder_create_with_multiattach_and_cinder_api_v1(self):
|
||||
cinder.CinderClientPlugin._create().AndReturn(self.cinder_fc)
|
||||
self.cinder_fc.volume_api_version = 1
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
stack_name = 'test_cvolume_multiattach_api_v1_stack'
|
||||
stack = utils.parse_stack(self.t, stack_name=stack_name)
|
||||
ex = self.assertRaises(exception.StackValidationFailed,
|
||||
self.create_volume, self.t, stack, 'volume4')
|
||||
self.assertIn('Multiple attach is not supported by the current '
|
||||
'volume API. Use this property since '
|
||||
'Cinder API v2.', six.text_type(ex))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def _test_cinder_create_invalid_property_combinations(
|
||||
self, stack_name, combinations, err_msg, exc):
|
||||
stack = utils.parse_stack(self.t, stack_name=stack_name)
|
||||
|
|
Loading…
Reference in New Issue