volume.
availability_zone The availability zone to associate with the new
volume.
+ bootable If set to True, marks the volume as bootable.
"""
context = req.environ['cinder.context']
authorize(context)
kwargs['description'] = volume.get('description', None)
kwargs['metadata'] = volume.get('metadata', None)
kwargs['availability_zone'] = volume.get('availability_zone', None)
-
+ kwargs['bootable'] = volume.get('bootable', False)
try:
new_volume = self.volume_api.manage_existing(context,
volume['host'],
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
obj = self.driver.manage_existing(volume, existing_ref)
expected_obj = {'display_name': 'Foo Volume'}
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
- mock.call.modifyVolume(existing_ref['name'],
+ mock.call.getVolume(existing_ref['source-name']),
+ mock.call.modifyVolume(existing_ref['source-name'],
{'newName': osv_matcher,
'comment': new_comment}),
mock.call.logout()
expected_obj = {'display_name': 'Test Volume'}
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
- mock.call.modifyVolume(existing_ref['name'],
+ mock.call.getVolume(existing_ref['source-name']),
+ mock.call.modifyVolume(existing_ref['source-name'],
{'newName': osv_matcher,
'comment': new_comment}),
mock.call.logout()
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
osv_matcher = self.driver.common._get_3par_vol_name(volume['id'])
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
obj = self.driver.manage_existing(volume, existing_ref)
expected_obj = {'display_name': 'Foo Volume'}
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
- mock.call.modifyVolume(existing_ref['name'],
+ mock.call.getVolume(existing_ref['source-name']),
+ mock.call.modifyVolume(existing_ref['source-name'],
{'newName': osv_matcher,
'comment': new_comment}),
mock.call.logout()
expected_obj = {'display_name': 'Test Volume'}
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
- mock.call.modifyVolume(existing_ref['name'],
+ mock.call.getVolume(existing_ref['source-name']),
+ mock.call.modifyVolume(existing_ref['source-name'],
{'newName': osv_matcher,
'comment': new_comment}),
mock.call.logout()
expected_obj = {'display_name': None}
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
- mock.call.modifyVolume(existing_ref['name'],
+ mock.call.getVolume(existing_ref['source-name']),
+ mock.call.modifyVolume(existing_ref['source-name'],
{'newName': osv_matcher,
'comment': new_comment}),
mock.call.logout()
mock_client.getVolume.side_effect = hpexceptions.HTTPNotFound('fake')
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
self.assertRaises(exception.InvalidInput,
self.driver.manage_existing,
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
+ mock.call.getVolume(existing_ref['source-name']),
mock.call.logout()
]
mock_client.getVolume.return_value = {'comment': comment}
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
self.assertRaises(exception.ManageExistingVolumeTypeMismatch,
self.driver.manage_existing,
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
+ mock.call.getVolume(existing_ref['source-name']),
mock.call.logout()
]
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
volume = {}
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
size = self.driver.manage_existing_get_size(volume, existing_ref)
expected_size = 2
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
+ mock.call.getVolume(existing_ref['source-name']),
mock.call.logout()
]
def test_manage_existing_get_size_invalid_reference(self):
mock_client = self.setup_driver()
volume = {}
- existing_ref = {'name': self.VOLUME_3PAR_NAME}
+ existing_ref = {'source-name': self.VOLUME_3PAR_NAME}
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size,
unm_matcher = self.driver.common._get_3par_unm_name(self.volume['id'])
volume = {}
- existing_ref = {'name': unm_matcher}
+ existing_ref = {'source-name': unm_matcher}
self.assertRaises(exception.InvalidInput,
self.driver.manage_existing_get_size,
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
- mock.call.getVolume(existing_ref['name']),
+ mock.call.getVolume(existing_ref['source-name']),
mock.call.logout()
]
del self.volumes[volume['name']]
def manage_volume_get_size(self, volume, existing_ref):
- if self.volumes.get(existing_ref['existing_ref'], None) is None:
+ if self.volumes.get(existing_ref['source-name'], None) is None:
raise self.exception.VolumeNotFound(volume_id=volume['id'])
- return self.volumes[existing_ref['existing_ref']]['size']
+ return self.volumes[existing_ref['source-name']]['size']
def manage_volume(self, volume, existing_ref):
- if self.volumes.get(existing_ref['existing_ref'], None) is None:
+ if self.volumes.get(existing_ref['source-name'], None) is None:
raise self.exception.VolumeNotFound(volume_id=volume['id'])
volume['size'] = MANAGED_VOLUME['size']
return {}
self.driver.do_setup(None)
self.driver.create_volume(MANAGED_VOLUME)
- existing_ref = {'existing_ref': MANAGED_VOLUME['name']}
+ existing_ref = {'source-name': MANAGED_VOLUME['name']}
return_size = self.driver.manage_existing_get_size(
VOLUME,
existing_ref)
self.driver.do_setup(None)
# on purpose - do NOT create managed volume
- existing_ref = {'existing_ref': MANAGED_VOLUME['name']}
+ existing_ref = {'source-name': MANAGED_VOLUME['name']}
self.assertRaises(exception.VolumeNotFound,
self.driver.manage_existing_get_size,
VOLUME,
self.driver.do_setup(None)
self.driver.create_volume(MANAGED_VOLUME)
- existing_ref = {'existing_ref': MANAGED_VOLUME['name']}
+ existing_ref = {'source-name': MANAGED_VOLUME['name']}
has_volume = self.driver.manage_existing(
VOLUME,
existing_ref)
self.driver.do_setup(None)
# on purpose - do NOT create managed volume
- existing_ref = {'existing_ref': MANAGED_VOLUME['name']}
+ existing_ref = {'source-name': MANAGED_VOLUME['name']}
self.assertRaises(exception.VolumeNotFound,
self.driver.manage_existing,
VOLUME,
with mock.patch.object(self.driver.rbd.Image, 'close') \
as mock_rbd_image_close:
mock_rbd_image_size.return_value = 2 * units.Gi
- existing_ref = {'rbd_name': self.volume_name}
+ existing_ref = {'source-name': self.volume_name}
return_size = self.driver.manage_existing_get_size(
self.volume,
existing_ref)
with mock.patch.object(self.driver.rbd.Image, 'close') \
as mock_rbd_image_close:
mock_rbd_image_size.return_value = 'abcd'
- existing_ref = {'rbd_name': self.volume_name}
+ existing_ref = {'source-name': self.volume_name}
self.assertRaises(exception.VolumeBackendAPIException,
self.driver.manage_existing_get_size,
self.volume, existing_ref)
with mock.patch.object(self.driver.rbd.RBD(), 'rename') as \
mock_rbd_image_rename:
exist_volume = 'vol-exist'
- existing_ref = {'rbd_name': exist_volume}
+ existing_ref = {'source-name': exist_volume}
mock_rbd_image_rename.return_value = 0
mock_rbd_image_rename(mock_rados_client.ioctx,
exist_volume,
MockImageExistsException
exist_volume = 'vol-exist'
- existing_ref = {'rbd_name': exist_volume}
+ existing_ref = {'source-name': exist_volume}
self.assertRaises(self.mock_rbd.ImageExists,
self.driver.manage_existing,
self.volume, existing_ref)
def test_manage_existing_bad_uid(self):
"""Error when the specified UUID does not exist."""
volume = self._generate_vol_info(None, None)
- ref = {'vdisk_UID': 'bad_uid'}
+ ref = {'source-id': 'bad_uid'}
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, volume, ref)
pass
new_volume = self._generate_vol_info(None, None)
# Submit the request to manage it.
- ref = {'vdisk_UID': uid}
+ ref = {'source-id': uid}
size = self.driver.manage_existing_get_size(new_volume, ref)
self.assertEqual(size, 10)
self.driver.manage_existing(new_volume, ref)
# Descriptor of the Cinder volume that we want to own the vdisk
# refrerenced by uid.
volume = self._generate_vol_info(None, None)
- ref = {'vdisk_UID': uid}
+ ref = {'source-id': uid}
# Attempt to manage this disk, and except an exception beause the
# volume is already mapped.
# Submit the request to manage it, specifying that it is OK to
# manage a volume that is already attached.
- ref = {'vdisk_UID': uid, 'manage_if_in_use': True}
+ ref = {'source-id': uid, 'manage_if_in_use': True}
size = self.driver.manage_existing_get_size(new_volume, ref)
self.assertEqual(size, 10)
self.driver.manage_existing(new_volume, ref)
"""
self._setup_stubs_for_manage_existing()
- ref = {'lv_name': 'fake_lv'}
+ ref = {'source-name': 'fake_lv'}
vol = {'name': 'test', 'id': 1, 'size': 0}
def _rename_volume(old_name, new_name):
- self.assertEqual(old_name, ref['lv_name'])
+ self.assertEqual(old_name, ref['source-name'])
self.assertEqual(new_name, vol['name'])
self.stubs.Set(self.volume.driver.vg, 'rename_volume',
"""
self._setup_stubs_for_manage_existing()
- ref = {'lv_name': 'fake_lv_bad_size'}
+ ref = {'source-name': 'fake_lv_bad_size'}
vol = {'name': 'test', 'id': 1, 'size': 2}
self.assertRaises(exception.VolumeBackendAPIException,
"""
self._setup_stubs_for_manage_existing()
- ref = {'lv_name': 'fake_nonexistent_lv'}
+ ref = {'source-name': 'fake_nonexistent_lv'}
vol = {'name': 'test', 'id': 1, 'size': 0, 'status': 'available'}
self.assertRaises(exception.ManageExistingInvalidReference,
def manage_existing(self, context, host, ref, name=None, description=None,
volume_type=None, metadata=None,
- availability_zone=None):
+ availability_zone=None, bootable=False):
if availability_zone is None:
elevated = context.elevated()
try:
'host': host,
'availability_zone': availability_zone,
'volume_type_id': volume_type_id,
- 'metadata': metadata
+ 'metadata': metadata,
+ 'bootable': bootable
}
# Call the scheduler to ensure that the host exists and that it can
if we got here then we have a vdisk that isn't in use (or we don't
care if it is in use.
"""
- vdisk = self._helpers.vdisk_by_uid(ref['vdisk_UID'])
+ vdisk = self._helpers.vdisk_by_uid(ref['source-id'])
if vdisk is None:
- reason = _('No vdisk with the specified vdisk_UID.')
+ reason = (_('No vdisk with the UID specified by source-id %s.')
+ % ref['source-id'])
raise exception.ManageExistingInvalidReference(existing_ref=ref,
reason=reason)
self._helpers.rename_vdisk(vdisk['name'], volume['name'])
def manage_existing_get_size(self, volume, ref):
- """Return size of an existing LV for manage_existing.
+ """Return size of an existing Vdisk for manage_existing.
existing_ref is a dictionary of the form:
- {'vdisk_UID': <uid of disk>}
+ {'source-id': <uid of disk>}
Optional elements are:
'manage_if_in_use': True/False (default is False)
"""
# Check that the reference is valid
- if 'vdisk_UID' not in ref:
- reason = _('Reference must contain vdisk_UID element.')
+ if 'source-id' not in ref:
+ reason = _('Reference must contain source-id element.')
raise exception.ManageExistingInvalidReference(existing_ref=ref,
reason=reason)
# Check for existence of the vdisk
- vdisk = self._helpers.vdisk_by_uid(ref['vdisk_UID'])
+ vdisk = self._helpers.vdisk_by_uid(ref['source-id'])
if vdisk is None:
- reason = _('No vdisk with the specified vdisk_UID.')
+ reason = (_('No vdisk with the UID specified by source-id %s.')
+ % (ref['source-id']))
raise exception.ManageExistingInvalidReference(existing_ref=ref,
reason=reason)
Renames the LV to match the expected name for the volume.
Error checking done by manage_existing_get_size is not repeated.
"""
- lv_name = existing_ref['lv_name']
+ lv_name = existing_ref['source-name']
self.vg.get_volume(lv_name)
# Attempt to rename the LV to match the OpenStack internal name.
"""Return size of an existing LV for manage_existing.
existing_ref is a dictionary of the form:
- {'lv_name': <name of LV>}
+ {'source-name': <name of LV>}
"""
# Check that the reference is valid
- if 'lv_name' not in existing_ref:
- reason = _('Reference must contain lv_name element.')
+ if 'source-name' not in existing_ref:
+ reason = _('Reference must contain source-name element.')
raise exception.ManageExistingInvalidReference(
existing_ref=existing_ref, reason=reason)
- lv_name = existing_ref['lv_name']
+ lv_name = existing_ref['source-name']
lv = self.vg.get_volume(lv_name)
# Raise an exception if we didn't find a suitable LV.
volume ref info to be set
:param existing_ref:
existing_ref is a dictionary of the form:
- {'rbd_name': <name of rbd image>}
+ {'source-name': <name of rbd image>}
"""
# Raise an exception if we didn't find a suitable rbd image.
with RADOSClient(self) as client:
- rbd_name = existing_ref['rbd_name']
+ rbd_name = existing_ref['source-name']
self.rbd.RBD().rename(client.ioctx, strutils.safe_encode(rbd_name),
strutils.safe_encode(volume['name']))
volume ref info to be set
:param existing_ref:
existing_ref is a dictionary of the form:
- {'rbd_name': <name of rbd image>}
+ {'source-name': <name of rbd image>}
"""
# Check that the reference is valid
- if 'rbd_name' not in existing_ref:
- reason = _('Reference must contain rbd_name element.')
+ if 'source-name' not in existing_ref:
+ reason = _('Reference must contain source-name element.')
raise exception.ManageExistingInvalidReference(
existing_ref=existing_ref, reason=reason)
- rbd_name = strutils.safe_encode(existing_ref['rbd_name'])
+ rbd_name = strutils.safe_encode(existing_ref['source-name'])
with RADOSClient(self) as client:
# Raise an exception if we didn't find a suitable rbd image.
2.0.11 - Remove hp3parclient requirement from unit tests #1315195
2.0.12 - Volume detach hangs when host is in a host set bug #1317134
2.0.13 - Added support for managing/unmanaging of volumes
+ 2.0.14 - Modified manage volume to use standard 'source-name' element.
"""
- VERSION = "2.0.13"
+ VERSION = "2.0.14"
stats = {}
self._extend_volume(volume, volume_name, growth_size_mib)
def manage_existing(self, volume, existing_ref):
- """Manage an existing 3PAR volume."""
+ """Manage an existing 3PAR volume.
+
+ existing_ref is a dictionary of the form:
+ {'source-name': <name of the virtual volume>}
+ """
# Check for the existence of the virtual volume.
try:
- vol = self.client.getVolume(existing_ref['name'])
+ vol = self.client.getVolume(existing_ref['source-name'])
except hpexceptions.HTTPNotFound:
err = (_("Virtual volume '%s' doesn't exist on array.") %
- existing_ref['name'])
+ existing_ref['source-name'])
LOG.error(err)
raise exception.InvalidInput(reason=err)
new_comment['qos'] = settings['qos']
# Update the existing volume with the new name and comments.
- self.client.modifyVolume(existing_ref['name'],
+ self.client.modifyVolume(existing_ref['source-name'],
{'newName': new_vol_name,
'comment': json.dumps(new_comment)})
LOG.info(_("Virtual volume '%(ref)s' renamed to '%(new)s'.") %
- {'ref': existing_ref['name'], 'new': new_vol_name})
+ {'ref': existing_ref['source-name'], 'new': new_vol_name})
LOG.info(_("Virtual volume %(disp)s '%(new)s' is now being managed.") %
{'disp': display_name, 'new': new_vol_name})
"""Return size of volume to be managed by manage_existing.
existing_ref is a dictionary of the form:
- {'name': <name of the virtual volume>}
+ {'source-name': <name of the virtual volume>}
"""
# Check that a valid reference was provided.
- if 'name' not in existing_ref:
- reason = _("Reference must contain name element.")
+ if 'source-name' not in existing_ref:
+ reason = _("Reference must contain source-name element.")
raise exception.ManageExistingInvalidReference(
existing_ref=existing_ref,
reason=reason)
# Make sure the reference is not in use.
- if re.match('osv-*|oss-*|vvs-*', existing_ref['name']):
+ if re.match('osv-*|oss-*|vvs-*', existing_ref['source-name']):
reason = _("Reference must be for an unmanaged virtual volume.")
raise exception.ManageExistingInvalidReference(
existing_ref=existing_ref,
# Check for the existence of the virtual volume.
try:
- vol = self.client.getVolume(existing_ref['name'])
+ vol = self.client.getVolume(existing_ref['source-name'])
except hpexceptions.HTTPNotFound:
err = (_("Virtual volume '%s' doesn't exist on array.") %
- existing_ref['name'])
+ existing_ref['source-name'])
LOG.error(err)
raise exception.InvalidInput(reason=err)