From ed39bfec99a8bd8718f77b6a51160aa927fe87bb Mon Sep 17 00:00:00 2001 From: Nikesh Mahalka Date: Fri, 29 Jul 2016 14:42:57 -0400 Subject: [PATCH] Support retype in K2 cinder driver Add retype feature for Kaminario K2 iSCSI and FC cinder drivers. Use deprecation mechanism for option 'kaminario_nodedup_substring'. Use get on connector dict for 'host' and 'wwpns'. Implements: blueprint k2-retype Co-Authored-By: Sreedhar Varma Co-Authored-By: Lakshman Co-Authored-By: VenkataKrishna Reddy Change-Id: I5cf20742e2ec8c1f785f3d6352de11e9198908a1 --- .../unit/volume/drivers/test_kaminario.py | 43 ++++++++++++ .../drivers/kaminario/kaminario_common.py | 67 +++++++++++++++++-- .../volume/drivers/kaminario/kaminario_fc.py | 9 +-- .../drivers/kaminario/kaminario_iscsi.py | 3 +- ...io_nodedup_substring-659a47acea97ef5a.yaml | 5 ++ ...inario-cinder-driver-ac522bc73e27faad.yaml | 4 ++ 6 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/deprecated-kaminario_nodedup_substring-659a47acea97ef5a.yaml create mode 100644 releasenotes/notes/kaminario-cinder-driver-ac522bc73e27faad.yaml diff --git a/cinder/tests/unit/volume/drivers/test_kaminario.py b/cinder/tests/unit/volume/drivers/test_kaminario.py index 581684e5633..6e2ad96346a 100644 --- a/cinder/tests/unit/volume/drivers/test_kaminario.py +++ b/cinder/tests/unit/volume/drivers/test_kaminario.py @@ -403,6 +403,49 @@ class TestKaminarioISCSI(test.TestCase): result = self.driver._get_is_replica(self.vol.volume_type) 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): diff --git a/cinder/volume/drivers/kaminario/kaminario_common.py b/cinder/volume/drivers/kaminario/kaminario_common.py index 87290188e11..7d4ef60fc6b 100644 --- a/cinder/volume/drivers/kaminario/kaminario_common.py +++ b/cinder/volume/drivers/kaminario/kaminario_common.py @@ -41,9 +41,11 @@ kaminario1_opts = [ default='K2-nodedup', help="If volume-type name contains this substring " "nodedup volume will be created, otherwise " - "dedup volume wil be created. Note: this option is " - "deprecated in favour of 'kaminario:thin_prov_type' in " - "extra-specs and will be removed in the Ocata release.")] + "dedup volume wil be created.", + deprecated_for_removal=True, + 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 = [ cfg.BoolOpt('auto_calc_max_oversubscription_ratio', default=False, @@ -562,7 +564,7 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver): All other characters are replaced with '_'. 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 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 " "deprecated in favour of 'kaminario:thin_prov_" "type' in extra-specs and will be removed in " - "the Ocata release.")) + "the 10.0.0 release.")) return False else: return True @@ -789,3 +791,58 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver): raise exception.ManageExistingInvalidReference( existing_ref=existing_ref, 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) diff --git a/cinder/volume/drivers/kaminario/kaminario_fc.py b/cinder/volume/drivers/kaminario/kaminario_fc.py index 15a45bc7901..dcbf1f0ca7a 100644 --- a/cinder/volume/drivers/kaminario/kaminario_fc.py +++ b/cinder/volume/drivers/kaminario/kaminario_fc.py @@ -34,9 +34,10 @@ class KaminarioFCDriver(common.KaminarioCinderDriver): 1.0 - Initial driver 1.1 - Added manage/unmanage and extra-specs support for nodedup 1.2 - Added replication support + 1.3 - Added retype support """ - VERSION = '1.2' + VERSION = '1.3' @kaminario_logger def __init__(self, *args, **kwargs): @@ -49,7 +50,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver): def initialize_connection(self, volume, connector): """Attach K2 volume to host.""" # Check wwpns in host connector. - if not connector['wwpns']: + if not connector.get('wwpns'): msg = _("No wwpns found in host connector.") LOG.error(msg) raise exception.KaminarioCinderDriverException(reason=msg) @@ -153,7 +154,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver): if self.lookup_service is not None: # use FC san lookup. dev_map = self.lookup_service.get_device_mapping_from_network( - connector['wwpns'], + connector.get('wwpns'), all_target_wwns) for fabric_name in dev_map: @@ -167,7 +168,7 @@ class KaminarioFCDriver(common.KaminarioCinderDriver): init_targ_map[initiator])) target_wwns = list(set(target_wwns)) else: - initiator_wwns = connector['wwpns'] + initiator_wwns = connector.get('wwpns', []) target_wwns = all_target_wwns for initiator in initiator_wwns: diff --git a/cinder/volume/drivers/kaminario/kaminario_iscsi.py b/cinder/volume/drivers/kaminario/kaminario_iscsi.py index c0527771c8c..6c0df6cfca2 100644 --- a/cinder/volume/drivers/kaminario/kaminario_iscsi.py +++ b/cinder/volume/drivers/kaminario/kaminario_iscsi.py @@ -36,9 +36,10 @@ class KaminarioISCSIDriver(common.KaminarioCinderDriver): 1.0 - Initial driver 1.1 - Added manage/unmanage and extra-specs support for nodedup 1.2 - Added replication support + 1.3 - Added retype support """ - VERSION = '1.2' + VERSION = '1.3' @kaminario_logger def __init__(self, *args, **kwargs): diff --git a/releasenotes/notes/deprecated-kaminario_nodedup_substring-659a47acea97ef5a.yaml b/releasenotes/notes/deprecated-kaminario_nodedup_substring-659a47acea97ef5a.yaml new file mode 100644 index 00000000000..3ae9edf31fe --- /dev/null +++ b/releasenotes/notes/deprecated-kaminario_nodedup_substring-659a47acea97ef5a.yaml @@ -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. + diff --git a/releasenotes/notes/kaminario-cinder-driver-ac522bc73e27faad.yaml b/releasenotes/notes/kaminario-cinder-driver-ac522bc73e27faad.yaml new file mode 100644 index 00000000000..b67837b140b --- /dev/null +++ b/releasenotes/notes/kaminario-cinder-driver-ac522bc73e27faad.yaml @@ -0,0 +1,4 @@ +--- +features: + - Add retype feature in Kaminario iSCSI and FC Cinder drivers. +