From f1a00677be45fe909d29194695fb3e1e3c20f90d Mon Sep 17 00:00:00 2001 From: Alex O'Rourke Date: Thu, 15 Oct 2015 14:49:07 -0700 Subject: [PATCH] Remove db access from 3PAR and LH cg functions The HP 3PAR and HP LeftHand drivers no longer need to access the db in order to grab snapshots and volumes for the following functions: * delete_consistencygroup * create_cgsnapshot * delete_cgsnapshot This patch removes all db access at the driver level for both 3PAR and LeftHand drivers. Change-Id: I2e29366573f53cf6e61939381bde5d04f188f42d --- cinder/tests/unit/test_hpe3par.py | 101 +++++------------ cinder/tests/unit/test_hpelefthand.py | 107 ++++++------------ cinder/volume/drivers/hpe/hpe_3par_common.py | 85 ++++++++------ cinder/volume/drivers/hpe/hpe_3par_fc.py | 9 +- cinder/volume/drivers/hpe/hpe_3par_iscsi.py | 9 +- .../volume/drivers/hpe/hpe_lefthand_iscsi.py | 95 ++++++++-------- 6 files changed, 171 insertions(+), 235 deletions(-) diff --git a/cinder/tests/unit/test_hpe3par.py b/cinder/tests/unit/test_hpe3par.py index 5597ae2a1..fe8b4215b 100644 --- a/cinder/tests/unit/test_hpe3par.py +++ b/cinder/tests/unit/test_hpe3par.py @@ -265,11 +265,6 @@ class HPE3PARBaseDriver(object): 'state': 1, 'uuid': '29c214aa-62b9-41c8-b198-543f6cf24edf'}] - cgsnapshot = {'consistencygroup_id': CONSIS_GROUP_ID, - 'description': 'cgsnapshot', - 'id': CGSNAPSHOT_ID, - 'readOnly': False} - TASK_DONE = 1 TASK_ACTIVE = 2 STATUS_DONE = {'status': 1} @@ -508,6 +503,20 @@ class HPE3PARBaseDriver(object): standard_logout = [ mock.call.logout()] + class fake_consistencygroup_object(object): + volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' + name = 'cg_name' + cgsnapshot_id = None + host = 'fakehost@foo#OpenStackCPG' + id = '6044fedf-c889-4752-900f-2039d247a5df' + description = 'consistency group' + + class fake_cgsnapshot_object(object): + consistencygroup_id = '6044fedf-c889-4752-900f-2039d247a5df' + description = 'cgsnapshot' + id = 'e91c5ed5-daee-4e84-8724-1c9e31e7a1f2' + readOnly = False + def setup_configuration(self): configuration = mock.Mock() configuration.hpe3par_debug = False @@ -3006,14 +3015,6 @@ class HPE3PARBaseDriver(object): self.assertEqual(fixed_hostname, safe_host) def test_create_consistency_group(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() comment = Comment({ @@ -3027,7 +3028,7 @@ class HPE3PARBaseDriver(object): mock_create_client.return_value = mock_client mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3045,14 +3046,6 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_create_consistency_group_from_src(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() volume = self.volume @@ -3077,7 +3070,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3114,8 +3107,9 @@ class HPE3PARBaseDriver(object): mock_client.reset_mock() # create a snapshot of the consistency group + cgsnapshot = self.fake_cgsnapshot_object() self.driver.create_cgsnapshot(context.get_admin_context(), - self.cgsnapshot, []) + cgsnapshot, []) expected = [ mock.call.createSnapshotOfVolumeSet( @@ -3126,7 +3120,7 @@ class HPE3PARBaseDriver(object): # create a consistency group from the cgsnapshot self.driver.create_consistencygroup_from_src( context.get_admin_context(), group, - [volume], cgsnapshot=self.cgsnapshot, + [volume], cgsnapshot=cgsnapshot, snapshots=[self.snapshot]) mock_client.assert_has_calls( @@ -3136,14 +3130,6 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_delete_consistency_group(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() comment = Comment({ @@ -3157,7 +3143,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3191,14 +3177,6 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_update_consistency_group_add_vol(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() volume = self.volume @@ -3213,7 +3191,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3249,14 +3227,6 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_update_consistency_group_remove_vol(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() volume = self.volume @@ -3271,7 +3241,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3325,14 +3295,6 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_create_cgsnapshot(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() volume = self.volume @@ -3356,7 +3318,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3393,8 +3355,9 @@ class HPE3PARBaseDriver(object): mock_client.reset_mock() # create a snapshot of the consistency group + cgsnapshot = self.fake_cgsnapshot_object() self.driver.create_cgsnapshot(context.get_admin_context(), - self.cgsnapshot, []) + cgsnapshot, []) expected = [ mock.call.createSnapshotOfVolumeSet( @@ -3409,17 +3372,9 @@ class HPE3PARBaseDriver(object): self.standard_logout) def test_delete_cgsnapshot(self): - class fake_consitencygroup_object(object): - volume_type_id = '49fa96b5-828e-4653-b622-873a1b7e6f1c' - name = 'cg_name' - cgsnapshot_id = None - host = self.FAKE_CINDER_HOST - id = self.CONSIS_GROUP_ID - description = 'consistency group' - mock_client = self.setup_driver() volume = self.volume - cgsnapshot = self.cgsnapshot + cgsnapshot = self.fake_cgsnapshot_object() cg_comment = Comment({ 'display_name': 'cg_name', @@ -3440,7 +3395,7 @@ class HPE3PARBaseDriver(object): mock_client.getCPG.return_value = {'domain': None} # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() self.driver.create_consistencygroup(context.get_admin_context(), group) @@ -3487,7 +3442,7 @@ class HPE3PARBaseDriver(object): optional=cgsnap_optional)] # delete the snapshot of the consistency group - cgsnapshot['status'] = 'deleting' + cgsnapshot.status = 'deleting' self.driver.delete_cgsnapshot(context.get_admin_context(), cgsnapshot, []) diff --git a/cinder/tests/unit/test_hpelefthand.py b/cinder/tests/unit/test_hpelefthand.py index 5d4379dd6..07266ca49 100644 --- a/cinder/tests/unit/test_hpelefthand.py +++ b/cinder/tests/unit/test_hpelefthand.py @@ -103,10 +103,18 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): CONSIS_GROUP_ID = '3470cc4c-63b3-4c7a-8120-8a0693b45838' CGSNAPSHOT_ID = '5351d914-6c90-43e7-9a8e-7e84610927da' - cgsnapshot = {'consistencygroup_id': CONSIS_GROUP_ID, - 'description': 'cgsnapshot', - 'id': CGSNAPSHOT_ID, - 'readOnly': False} + class fake_consistencygroup_object(object): + volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' + name = 'cg_name' + cgsnapshot_id = None + id = '3470cc4c-63b3-4c7a-8120-8a0693b45838' + description = 'consistency group' + + class fake_cgsnapshot_object(object): + consistencygroup_id = '3470cc4c-63b3-4c7a-8120-8a0693b45838' + description = 'cgsnapshot' + id = '5351d914-6c90-43e7-9a8e-7e84610927da' + readOnly = False def default_mock_conf(self): @@ -140,9 +148,8 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): _mock_client.return_value.getCluster.return_value = { 'spaceTotal': units.Gi * 500, 'spaceAvailable': units.Gi * 250} - db = mock.Mock() self.driver = hpe_lefthand_iscsi.HPELeftHandISCSIDriver( - configuration=config, db=db) + configuration=config) self.driver.do_setup(None) self.cluster_name = config.hpelefthand_clustername return _mock_client.return_value @@ -1609,13 +1616,6 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_client.assert_has_calls(expected) def test_create_consistencygroup(self): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - ctxt = context.get_admin_context() # set up driver with default config mock_client = self.setup_driver() @@ -1625,57 +1625,42 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) def test_delete_consistencygroup(self): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - ctxt = context.get_admin_context() # set up driver with default config mock_client = self.setup_driver() mock_volume = mock.MagicMock() - expected_volumes = [mock_volume] - self.driver.db.volume_get_all_by_group.return_value = expected_volumes + volumes = [mock_volume] with mock.patch.object(hpe_lefthand_iscsi.HPELeftHandISCSIDriver, '_create_client') as mock_do_setup: mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) # delete the consistency group group.status = 'deleting' - cg, vols = self.driver.delete_consistencygroup(ctxt, group, []) + cg, vols = self.driver.delete_consistencygroup(ctxt, group, + volumes) self.assertEqual('deleting', cg['status']) def test_update_consistencygroup_add_vol_delete_cg(self): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - ctxt = context.get_admin_context() # set up driver with default config mock_client = self.setup_driver() mock_volume = mock.MagicMock() - expected_volumes = [mock_volume] - self.driver.db.volume_get_all_by_group.return_value = expected_volumes + volumes = [mock_volume] mock_client.getVolumes.return_value = {'total': 1, 'members': []} @@ -1688,7 +1673,7 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) @@ -1698,25 +1683,18 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): # delete the consistency group group.status = 'deleting' - cg, vols = self.driver.delete_consistencygroup(ctxt, group, []) + cg, vols = self.driver.delete_consistencygroup(ctxt, group, + volumes) self.assertEqual('deleting', cg['status']) def test_update_consistencygroup_remove_vol_delete_cg(self): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - ctxt = context.get_admin_context() # set up driver with default config mock_client = self.setup_driver() mock_volume = mock.MagicMock() - expected_volumes = [mock_volume] - self.driver.db.volume_get_all_by_group.return_value = expected_volumes + volumes = [mock_volume] mock_client.getVolumes.return_value = {'total': 1, 'members': []} @@ -1729,7 +1707,7 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) @@ -1743,18 +1721,11 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): # delete the consistency group group.status = 'deleting' - cg, vols = self.driver.delete_consistencygroup(ctxt, group, []) + cg, vols = self.driver.delete_consistencygroup(ctxt, group, + volumes) self.assertEqual('deleting', cg['status']) - @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') - def test_create_cgsnapshot(self, mock_snap_list): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - + def test_create_cgsnapshot(self): ctxt = context.get_admin_context() # set up driver with default config @@ -1766,14 +1737,13 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_snap = mock.MagicMock() mock_snap.volumeName = self.volume_name expected_snaps = [mock_snap] - mock_snap_list.return_value = expected_snaps with mock.patch.object(hpe_lefthand_iscsi.HPELeftHandISCSIDriver, '_create_client') as mock_do_setup: mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) @@ -1782,19 +1752,12 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): ctxt, group, add_volumes=[self.volume], remove_volumes=None) # create the conistency group snapshot + cgsnapshot = self.fake_cgsnapshot_object() cgsnap, snaps = self.driver.create_cgsnapshot( - ctxt, self.cgsnapshot, []) + ctxt, cgsnapshot, expected_snaps) self.assertEqual('available', cgsnap['status']) - @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') - def test_delete_cgsnapshot(self, mock_snap_list): - class fake_consitencygroup_object(object): - volume_type_id = '371c64d5-b92a-488c-bc14-1e63cef40e08' - name = 'cg_name' - cgsnapshot_id = None - id = self.CONSIS_GROUP_ID - description = 'consistency group' - + def test_delete_cgsnapshot(self): ctxt = context.get_admin_context() # set up driver with default config @@ -1806,14 +1769,13 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): mock_snap = mock.MagicMock() mock_snap.volumeName = self.volume_name expected_snaps = [mock_snap] - mock_snap_list.return_value = expected_snaps with mock.patch.object(hpe_lefthand_iscsi.HPELeftHandISCSIDriver, '_create_client') as mock_do_setup: mock_do_setup.return_value = mock_client # create a consistency group - group = fake_consitencygroup_object() + group = self.fake_consistencygroup_object() cg = self.driver.create_consistencygroup(ctxt, group) self.assertEqual('available', cg['status']) @@ -1822,7 +1784,8 @@ class TestHPELeftHandISCSIDriver(HPELeftHandBaseDriver, test.TestCase): ctxt, group, add_volumes=[self.volume], remove_volumes=None) # delete the consistency group snapshot - self.cgsnapshot['status'] = 'deleting' + cgsnapshot = self.fake_cgsnapshot_object() + cgsnapshot.status = 'deleting' cgsnap, snaps = self.driver.delete_cgsnapshot( - ctxt, self.cgsnapshot, []) + ctxt, cgsnapshot, expected_snaps) self.assertEqual('deleting', cgsnap['status']) diff --git a/cinder/volume/drivers/hpe/hpe_3par_common.py b/cinder/volume/drivers/hpe/hpe_3par_common.py index b7a3812f5..401128ed0 100644 --- a/cinder/volume/drivers/hpe/hpe_3par_common.py +++ b/cinder/volume/drivers/hpe/hpe_3par_common.py @@ -61,7 +61,6 @@ from cinder import context from cinder import exception from cinder import flow_utils from cinder.i18n import _, _LE, _LI, _LW -from cinder import objects from cinder.volume import qos_specs from cinder.volume import utils as volume_utils from cinder.volume import volume_types @@ -214,10 +213,11 @@ class HPE3PARCommon(object): 3.0.0 - Rebranded HP to HPE. 3.0.1 - Fixed find_existing_vluns bug #1515033 3.0.2 - Python 3 support + 3.0.3 - Remove db access for consistency groups """ - VERSION = "3.0.2" + VERSION = "3.0.3" stats = {} @@ -258,7 +258,6 @@ class HPE3PARCommon(object): self.config = config self.client = None self.uuid = uuid.uuid4() - self.db = importutils.import_module('cinder.db') def get_version(self): return self.VERSION @@ -423,7 +422,7 @@ class HPE3PARCommon(object): if cgsnapshot and snapshots: self.create_consistencygroup(context, group) vvs_name = self._get_3par_vvs_name(group.id) - cgsnap_name = self._get_3par_snap_name(cgsnapshot['id']) + cgsnap_name = self._get_3par_snap_name(cgsnapshot.id) for i, (volume, snapshot) in enumerate(zip(volumes, snapshots)): snap_name = cgsnap_name + "-" + six.text_type(i) volume_name = self._get_3par_vol_name(volume['id']) @@ -439,7 +438,7 @@ class HPE3PARCommon(object): return None, None - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" try: @@ -456,14 +455,23 @@ class HPE3PARCommon(object): {"volume_set": cg_name, "error": e}) - volumes = self.db.volume_get_all_by_group(context, group.id) + volume_model_updates = [] for volume in volumes: - self.delete_volume(volume) - volume.status = 'deleted' + volume_update = {'id': volume.id} + try: + self.delete_volume(volume) + volume_update['status'] = 'deleted' + except Exception as ex: + LOG.error(_LE("There was an error deleting volume %(id)s: " + "%(error)."), + {'id': volume.id, + 'error': six.text_type(ex)}) + volume_update['status'] = 'error' + volume_model_updates.append(volume_update) model_update = {'status': group.status} - return model_update, volumes + return model_update, volume_model_updates def update_consistencygroup(self, context, group, add_volumes=None, remove_volumes=None): @@ -493,17 +501,17 @@ class HPE3PARCommon(object): return None, None, None - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" - cg_id = cgsnapshot['consistencygroup_id'] - snap_shot_name = self._get_3par_snap_name(cgsnapshot['id']) + ( + cg_id = cgsnapshot.consistencygroup_id + snap_shot_name = self._get_3par_snap_name(cgsnapshot.id) + ( "-@count@") copy_of_name = self._get_3par_vvs_name(cg_id) - extra = {'cgsnapshot_id': cgsnapshot['id']} + extra = {'cgsnapshot_id': cgsnapshot.id} extra['consistency_group_id'] = cg_id - extra['description'] = cgsnapshot['description'] + extra['description'] = cgsnapshot.description optional = {'comment': json.dumps(extra), 'readOnly': False} @@ -515,48 +523,55 @@ class HPE3PARCommon(object): optional['retentionHours'] = ( int(self.config.hpe3par_snapshot_retention)) - self.client.createSnapshotOfVolumeSet(snap_shot_name, copy_of_name, - optional=optional) - - snapshots = objects.SnapshotList().get_all_for_cgsnapshot( - context, cgsnapshot['id']) + try: + self.client.createSnapshotOfVolumeSet(snap_shot_name, copy_of_name, + optional=optional) + except Exception as ex: + msg = (_('There was an error creating the cgsnapshot: %s'), + six.text_type(ex)) + LOG.error(msg) + raise exception.InvalidInput(reason=msg) + snapshot_model_updates = [] for snapshot in snapshots: - snapshot.status = 'available' + snapshot_update = {'id': snapshot['id'], + 'status': 'available'} + snapshot_model_updates.append(snapshot_update) model_update = {'status': 'available'} - return model_update, snapshots + return model_update, snapshot_model_updates - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" - cgsnap_name = self._get_3par_snap_name(cgsnapshot['id']) - - snapshots = objects.SnapshotList().get_all_for_cgsnapshot( - context, cgsnapshot['id']) + cgsnap_name = self._get_3par_snap_name(cgsnapshot.id) + snapshot_model_updates = [] for i, snapshot in enumerate(snapshots): + snapshot_update = {'id': snapshot['id']} try: snap_name = cgsnap_name + "-" + six.text_type(i) self.client.deleteVolume(snap_name) - except hpeexceptions.HTTPForbidden as ex: - LOG.error(_LE("Exception: %s."), ex) - raise exception.NotAuthorized() + snapshot_update['status'] = 'deleted' except hpeexceptions.HTTPNotFound as ex: # We'll let this act as if it worked # it helps clean up the cinder entries. LOG.warning(_LW("Delete Snapshot id not found. Removing from " "cinder: %(id)s Ex: %(msg)s"), {'id': snapshot['id'], 'msg': ex}) - except hpeexceptions.HTTPConflict as ex: - LOG.error(_LE("Exception: %s."), ex) - raise exception.SnapshotIsBusy(snapshot_name=snapshot['id']) - snapshot['status'] = 'deleted' + snapshot_update['status'] = 'error' + except Exception as ex: + LOG.error(_LE("There was an error deleting snapshot %(id)s: " + "%(error)."), + {'id': snapshot['id'], + 'error': six.text_type(ex)}) + snapshot_update['status'] = 'error' + snapshot_model_updates.append(snapshot_update) - model_update = {'status': cgsnapshot['status']} + model_update = {'status': cgsnapshot.status} - return model_update, snapshots + return model_update, snapshot_model_updates def manage_existing(self, volume, existing_ref): """Manage an existing 3PAR volume. diff --git a/cinder/volume/drivers/hpe/hpe_3par_fc.py b/cinder/volume/drivers/hpe/hpe_3par_fc.py index dbc8120e8..384f5f798 100644 --- a/cinder/volume/drivers/hpe/hpe_3par_fc.py +++ b/cinder/volume/drivers/hpe/hpe_3par_fc.py @@ -90,10 +90,11 @@ class HPE3PARFCDriver(driver.TransferVD, 2.0.20 - Update driver to use ABC metaclasses 2.0.21 - Added update_migrated_volume. bug # 1492023 3.0.0 - Rebranded HP to HPE. + 3.0.1 - Remove db access for consistency groups """ - VERSION = "3.0.0" + VERSION = "3.0.1" def __init__(self, *args, **kwargs): super(HPE3PARFCDriver, self).__init__(*args, **kwargs) @@ -458,7 +459,7 @@ class HPE3PARFCDriver(driver.TransferVD, def delete_consistencygroup(self, context, group, volumes): common = self._login() try: - return common.delete_consistencygroup(context, group) + return common.delete_consistencygroup(context, group, volumes) finally: self._logout(common) @@ -474,14 +475,14 @@ class HPE3PARFCDriver(driver.TransferVD, def create_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: - return common.create_cgsnapshot(context, cgsnapshot) + return common.create_cgsnapshot(context, cgsnapshot, snapshots) finally: self._logout(common) def delete_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: - return common.delete_cgsnapshot(context, cgsnapshot) + return common.delete_cgsnapshot(context, cgsnapshot, snapshots) finally: self._logout(common) diff --git a/cinder/volume/drivers/hpe/hpe_3par_iscsi.py b/cinder/volume/drivers/hpe/hpe_3par_iscsi.py index 35246128f..bdd310fff 100644 --- a/cinder/volume/drivers/hpe/hpe_3par_iscsi.py +++ b/cinder/volume/drivers/hpe/hpe_3par_iscsi.py @@ -101,10 +101,11 @@ class HPE3PARISCSIDriver(driver.TransferVD, 2.0.23 - Added update_migrated_volume. bug # 1492023 3.0.0 - Rebranded HP to HPE. 3.0.1 - Python 3 support + 3.0.2 - Remove db access for consistency groups """ - VERSION = "3.0.1" + VERSION = "3.0.2" def __init__(self, *args, **kwargs): super(HPE3PARISCSIDriver, self).__init__(*args, **kwargs) @@ -756,7 +757,7 @@ class HPE3PARISCSIDriver(driver.TransferVD, def delete_consistencygroup(self, context, group, volumes): common = self._login() try: - return common.delete_consistencygroup(context, group) + return common.delete_consistencygroup(context, group, volumes) finally: self._logout(common) @@ -772,14 +773,14 @@ class HPE3PARISCSIDriver(driver.TransferVD, def create_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: - return common.create_cgsnapshot(context, cgsnapshot) + return common.create_cgsnapshot(context, cgsnapshot, snapshots) finally: self._logout(common) def delete_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: - return common.delete_cgsnapshot(context, cgsnapshot) + return common.delete_cgsnapshot(context, cgsnapshot, snapshots) finally: self._logout(common) diff --git a/cinder/volume/drivers/hpe/hpe_lefthand_iscsi.py b/cinder/volume/drivers/hpe/hpe_lefthand_iscsi.py index 2bdd34b2c..d6268d08e 100644 --- a/cinder/volume/drivers/hpe/hpe_lefthand_iscsi.py +++ b/cinder/volume/drivers/hpe/hpe_lefthand_iscsi.py @@ -43,7 +43,6 @@ from oslo_utils import units from cinder import context from cinder import exception from cinder.i18n import _, _LE, _LI, _LW -from cinder import objects from cinder.volume import driver from cinder.volume import utils from cinder.volume import volume_types @@ -140,9 +139,10 @@ class HPELeftHandISCSIDriver(driver.ISCSIDriver): 1.0.13 - Added update_migrated_volume #1493546 1.0.14 - Removed the old CLIQ based driver 2.0.0 - Rebranded HP to HPE + 2.0.1 - Remove db access for consistency groups """ - VERSION = "2.0.0" + VERSION = "2.0.1" device_stats = {} @@ -306,16 +306,23 @@ class HPELeftHandISCSIDriver(driver.ISCSIDriver): def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" - # TODO(aorourke): Can't eliminate the DB calls here due to CG API. - # Will fix in M release - volumes = self.db.volume_get_all_by_group(context, group.id) + volume_model_updates = [] for volume in volumes: - self.delete_volume(volume) - volume.status = 'deleted' + volume_update = {'id': volume.id} + try: + self.delete_volume(volume) + volume_update['status'] = 'deleted' + except Exception as ex: + LOG.error(_LE("There was an error deleting volume %(id)s: " + "%(error)."), + {'id': volume.id, + 'error': six.text_type(ex)}) + volume_update['status'] = 'error' + volume_model_updates.append(volume_update) model_update = {'status': group.status} - return model_update, volumes + return model_update, volume_model_updates def update_consistencygroup(self, context, group, add_volumes=None, remove_volumes=None): @@ -333,13 +340,9 @@ class HPELeftHandISCSIDriver(driver.ISCSIDriver): """Creates a consistency group snapshot.""" client = self._login() try: - # TODO(aorourke): Can't eliminate the DB calls here due to CG API. - # Will fix in M release - snapshots = objects.SnapshotList().get_all_for_cgsnapshot( - context, cgsnapshot['id']) - snap_set = [] - snapshot_base_name = "snapshot-" + cgsnapshot['id'] + snapshot_base_name = "snapshot-" + cgsnapshot.id + snapshot_model_updates = [] for i, snapshot in enumerate(snapshots): volume = snapshot.volume volume_name = volume['name'] @@ -359,11 +362,13 @@ class HPELeftHandISCSIDriver(driver.ISCSIDriver): 'volumeId': volume_id, 'snapshotName': snapshot_name} snap_set.append(snap_set_member) - snapshot.status = 'available' + snapshot_update = {'id': snapshot['id'], + 'status': 'available'} + snapshot_model_updates.append(snapshot_update) source_volume_id = snap_set[0]['volumeId'] optional = {'inheritAccess': True} - description = cgsnapshot.get('description', None) + description = cgsnapshot.description if description: optional['description'] = description @@ -383,46 +388,42 @@ class HPELeftHandISCSIDriver(driver.ISCSIDriver): model_update = {'status': 'available'} - return model_update, snapshots + return model_update, snapshot_model_updates def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a consistency group snapshot.""" client = self._login() - try: - snap_name_base = "snapshot-" + cgsnapshot['id'] - - # TODO(aorourke): Can't eliminate the DB calls here due to CG API. - # Will fix in M release - snapshots = objects.SnapshotList().get_all_for_cgsnapshot( - context, cgsnapshot['id']) + snap_name_base = "snapshot-" + cgsnapshot.id - for i, snapshot in enumerate(snapshots): - try: - snap_name = snap_name_base + "-" + six.text_type(i) - snap_info = client.getSnapshotByName(snap_name) - client.deleteSnapshot(snap_info['id']) - except hpeexceptions.HTTPNotFound: - LOG.error(_LE("Snapshot did not exist. It will not be " - "deleted.")) - except hpeexceptions.HTTPServerError as ex: - in_use_msg = ('cannot be deleted because it is a clone ' - 'point') - if in_use_msg in ex.get_description(): - raise exception.SnapshotIsBusy(snapshot_name=snap_name) - - raise exception.VolumeBackendAPIException( - data=six.text_type(ex)) + snapshot_model_updates = [] + for i, snapshot in enumerate(snapshots): + snapshot_update = {'id': snapshot['id']} + try: + snap_name = snap_name_base + "-" + six.text_type(i) + snap_info = client.getSnapshotByName(snap_name) + client.deleteSnapshot(snap_info['id']) + snapshot_update['status'] = 'deleted' + except hpeexceptions.HTTPServerError as ex: + in_use_msg = ('cannot be deleted because it is a clone ' + 'point') + if in_use_msg in ex.get_description(): + LOG.error(_LE("The snapshot cannot be deleted because " + "it is a clone point.")) + snapshot_update['status'] = 'error' + except Exception as ex: + LOG.error(_LE("There was an error deleting snapshot %(id)s: " + "%(error)."), + {'id': snapshot['id'], + 'error': six.text_type(ex)}) + snapshot_update['status'] = 'error' + snapshot_model_updates.append(snapshot_update) - except Exception as ex: - raise exception.VolumeBackendAPIException( - data=six.text_type(ex)) - finally: - self._logout(client) + self._logout(client) - model_update = {'status': cgsnapshot['status']} + model_update = {'status': cgsnapshot.status} - return model_update, snapshots + return model_update, snapshot_model_updates def create_snapshot(self, snapshot): """Creates a snapshot.""" -- 2.45.2