Merge "Support retype in K2 cinder driver"
This commit is contained in:
commit
7a8804aa20
@ -403,6 +403,49 @@ class TestKaminarioISCSI(test.TestCase):
|
|||||||
result = self.driver._get_is_replica(self.vol.volume_type)
|
result = self.driver._get_is_replica(self.vol.volume_type)
|
||||||
self.assertTrue(result)
|
self.assertTrue(result)
|
||||||
|
|
||||||
|
def test_after_volume_copy(self):
|
||||||
|
"""Test after_volume_copy."""
|
||||||
|
result = self.driver.after_volume_copy(None, self.vol,
|
||||||
|
self.vol.volume_type)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_retype(self):
|
||||||
|
"""Test retype."""
|
||||||
|
replica_status = self.driver._get_replica_status('test')
|
||||||
|
self.assertTrue(replica_status)
|
||||||
|
replica = self.driver._get_is_replica(self.vol.volume_type)
|
||||||
|
self.assertFalse(replica)
|
||||||
|
self.driver.replica = Replication()
|
||||||
|
result = self.driver._add_replication(self.vol)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
self.driver.target = FakeKrest()
|
||||||
|
self.driver._check_for_status = mock.Mock()
|
||||||
|
result = self.driver._delete_replication(self.vol)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
self.driver._delete_volume_replica = mock.Mock()
|
||||||
|
result = self.driver.retype(None, self.vol,
|
||||||
|
self.vol.volume_type, None, None)
|
||||||
|
self.assertTrue(result)
|
||||||
|
new_vol_type = fake_volume.fake_volume_type_obj(self.context)
|
||||||
|
new_vol_type.extra_specs = {'kaminario:thin_prov_type': 'nodedup'}
|
||||||
|
result2 = self.driver.retype(None, self.vol,
|
||||||
|
new_vol_type, None, None)
|
||||||
|
self.assertFalse(result2)
|
||||||
|
|
||||||
|
def test_add_replication(self):
|
||||||
|
""""Test _add_replication."""
|
||||||
|
self.driver.replica = Replication()
|
||||||
|
result = self.driver._add_replication(self.vol)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_delete_replication(self):
|
||||||
|
"""Test _delete_replication."""
|
||||||
|
self.driver.replica = Replication()
|
||||||
|
self.driver.target = FakeKrest()
|
||||||
|
self.driver._check_for_status = mock.Mock()
|
||||||
|
result = self.driver._delete_replication(self.vol)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
|
||||||
class TestKaminarioFC(TestKaminarioISCSI):
|
class TestKaminarioFC(TestKaminarioISCSI):
|
||||||
|
|
||||||
|
@ -41,9 +41,11 @@ kaminario1_opts = [
|
|||||||
default='K2-nodedup',
|
default='K2-nodedup',
|
||||||
help="If volume-type name contains this substring "
|
help="If volume-type name contains this substring "
|
||||||
"nodedup volume will be created, otherwise "
|
"nodedup volume will be created, otherwise "
|
||||||
"dedup volume wil be created. Note: this option is "
|
"dedup volume wil be created.",
|
||||||
"deprecated in favour of 'kaminario:thin_prov_type' in "
|
deprecated_for_removal=True,
|
||||||
"extra-specs and will be removed in the Ocata release.")]
|
deprecated_reason="This option is deprecated in favour of "
|
||||||
|
"'kaminario:thin_prov_type' in extra-specs "
|
||||||
|
"and will be removed in the next release.")]
|
||||||
kaminario2_opts = [
|
kaminario2_opts = [
|
||||||
cfg.BoolOpt('auto_calc_max_oversubscription_ratio',
|
cfg.BoolOpt('auto_calc_max_oversubscription_ratio',
|
||||||
default=False,
|
default=False,
|
||||||
@ -562,7 +564,7 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
|||||||
All other characters are replaced with '_'.
|
All other characters are replaced with '_'.
|
||||||
Total characters in initiator host name: 32
|
Total characters in initiator host name: 32
|
||||||
"""
|
"""
|
||||||
return re.sub('[^0-9a-zA-Z-_]', '_', connector['host'])[:32]
|
return re.sub('[^0-9a-zA-Z-_]', '_', connector.get('host', ''))[:32]
|
||||||
|
|
||||||
@kaminario_logger
|
@kaminario_logger
|
||||||
def get_volume_group_name(self, vid):
|
def get_volume_group_name(self, vid):
|
||||||
@ -715,7 +717,7 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
|||||||
LOG.info(_LI("'kaminario_nodedup_substring' option is "
|
LOG.info(_LI("'kaminario_nodedup_substring' option is "
|
||||||
"deprecated in favour of 'kaminario:thin_prov_"
|
"deprecated in favour of 'kaminario:thin_prov_"
|
||||||
"type' in extra-specs and will be removed in "
|
"type' in extra-specs and will be removed in "
|
||||||
"the Ocata release."))
|
"the 10.0.0 release."))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
@ -789,3 +791,58 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver):
|
|||||||
raise exception.ManageExistingInvalidReference(
|
raise exception.ManageExistingInvalidReference(
|
||||||
existing_ref=existing_ref,
|
existing_ref=existing_ref,
|
||||||
reason=_('Unable to get size of manage volume.'))
|
reason=_('Unable to get size of manage volume.'))
|
||||||
|
|
||||||
|
def after_volume_copy(self, ctxt, volume, new_volume, remote=None):
|
||||||
|
self.delete_volume(volume)
|
||||||
|
vg_name_old = self.get_volume_group_name(volume.id)
|
||||||
|
vol_name_old = self.get_volume_name(volume.id)
|
||||||
|
vg_name_new = self.get_volume_group_name(new_volume.id)
|
||||||
|
vol_name_new = self.get_volume_name(new_volume.id)
|
||||||
|
vg_new = self.client.search("volume_groups", name=vg_name_new).hits[0]
|
||||||
|
vg_new.name = vg_name_old
|
||||||
|
vg_new.save()
|
||||||
|
vol_new = self.client.search("volumes", name=vol_name_new).hits[0]
|
||||||
|
vol_new.name = vol_name_old
|
||||||
|
vol_new.save()
|
||||||
|
|
||||||
|
def retype(self, ctxt, volume, new_type, diff, host):
|
||||||
|
old_type = volume.get('volume_type')
|
||||||
|
vg_name = self.get_volume_group_name(volume.id)
|
||||||
|
old_rep_type = self._get_replica_status(vg_name)
|
||||||
|
new_rep_type = self._get_is_replica(new_type)
|
||||||
|
new_prov_type = self._get_is_dedup(new_type)
|
||||||
|
old_prov_type = self._get_is_dedup(old_type)
|
||||||
|
# Change dedup<->nodedup with add/remove replication is complex in K2
|
||||||
|
# since K2 does not have api to change dedup<->nodedup.
|
||||||
|
if new_prov_type == old_prov_type:
|
||||||
|
if not old_rep_type and new_rep_type:
|
||||||
|
self._add_replication(volume)
|
||||||
|
return True
|
||||||
|
elif old_rep_type and not new_rep_type:
|
||||||
|
self._delete_replication(volume)
|
||||||
|
return True
|
||||||
|
elif not new_rep_type and not old_rep_type:
|
||||||
|
LOG.debug("Use '--migration-policy on-demand' to change 'dedup "
|
||||||
|
"without replication'<->'nodedup without replication'.")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
LOG.error(_LE('Change from type1: %(type1)s to type2: %(type2)s '
|
||||||
|
'is not supported directly in K2.'),
|
||||||
|
{'type1': old_type, 'type2': new_type})
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _add_replication(self, volume):
|
||||||
|
vg_name = self.get_volume_group_name(volume.id)
|
||||||
|
vol_name = self.get_volume_name(volume.id)
|
||||||
|
LOG.debug("Searching volume group with name: %(name)s",
|
||||||
|
{'name': vg_name})
|
||||||
|
vg = self.client.search("volume_groups", name=vg_name).hits[0]
|
||||||
|
LOG.debug("Searching volume with name: %(name)s",
|
||||||
|
{'name': vol_name})
|
||||||
|
vol = self.client.search("volumes", name=vol_name).hits[0]
|
||||||
|
self._create_volume_replica(volume, vg, vol, 500)
|
||||||
|
|
||||||
|
def _delete_replication(self, volume):
|
||||||
|
vg_name = self.get_volume_group_name(volume.id)
|
||||||
|
vol_name = self.get_volume_name(volume.id)
|
||||||
|
self._delete_volume_replica(volume, vg_name, vol_name)
|
||||||
|
@ -34,9 +34,10 @@ class KaminarioFCDriver(common.KaminarioCinderDriver):
|
|||||||
1.0 - Initial driver
|
1.0 - Initial driver
|
||||||
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
||||||
1.2 - Added replication support
|
1.2 - Added replication support
|
||||||
|
1.3 - Added retype support
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = '1.2'
|
VERSION = '1.3'
|
||||||
|
|
||||||
@kaminario_logger
|
@kaminario_logger
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -49,7 +50,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver):
|
|||||||
def initialize_connection(self, volume, connector):
|
def initialize_connection(self, volume, connector):
|
||||||
"""Attach K2 volume to host."""
|
"""Attach K2 volume to host."""
|
||||||
# Check wwpns in host connector.
|
# Check wwpns in host connector.
|
||||||
if not connector['wwpns']:
|
if not connector.get('wwpns'):
|
||||||
msg = _("No wwpns found in host connector.")
|
msg = _("No wwpns found in host connector.")
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.KaminarioCinderDriverException(reason=msg)
|
raise exception.KaminarioCinderDriverException(reason=msg)
|
||||||
@ -153,7 +154,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver):
|
|||||||
if self.lookup_service is not None:
|
if self.lookup_service is not None:
|
||||||
# use FC san lookup.
|
# use FC san lookup.
|
||||||
dev_map = self.lookup_service.get_device_mapping_from_network(
|
dev_map = self.lookup_service.get_device_mapping_from_network(
|
||||||
connector['wwpns'],
|
connector.get('wwpns'),
|
||||||
all_target_wwns)
|
all_target_wwns)
|
||||||
|
|
||||||
for fabric_name in dev_map:
|
for fabric_name in dev_map:
|
||||||
@ -167,7 +168,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver):
|
|||||||
init_targ_map[initiator]))
|
init_targ_map[initiator]))
|
||||||
target_wwns = list(set(target_wwns))
|
target_wwns = list(set(target_wwns))
|
||||||
else:
|
else:
|
||||||
initiator_wwns = connector['wwpns']
|
initiator_wwns = connector.get('wwpns', [])
|
||||||
target_wwns = all_target_wwns
|
target_wwns = all_target_wwns
|
||||||
|
|
||||||
for initiator in initiator_wwns:
|
for initiator in initiator_wwns:
|
||||||
|
@ -36,9 +36,10 @@ class KaminarioISCSIDriver(common.KaminarioCinderDriver):
|
|||||||
1.0 - Initial driver
|
1.0 - Initial driver
|
||||||
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
1.1 - Added manage/unmanage and extra-specs support for nodedup
|
||||||
1.2 - Added replication support
|
1.2 - Added replication support
|
||||||
|
1.3 - Added retype support
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = '1.2'
|
VERSION = '1.3'
|
||||||
|
|
||||||
@kaminario_logger
|
@kaminario_logger
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
deprecations:
|
||||||
|
- Deprecated Kaminario iSCSI and FC Cinder drivers 'kaminario_nodedup_substring'
|
||||||
|
option in favour of 'kaminario:thin_prov_type' in extra-specs.
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add retype feature in Kaminario iSCSI and FC Cinder drivers.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user