From: Xing Yang Date: Tue, 25 Aug 2015 04:46:53 +0000 (-0400) Subject: CG driver function should not access db X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=f18cb6374e68e4d904125e9d99b809354fbdf9ee;p=openstack-build%2Fcinder-build.git CG driver function should not access db Currently the following CG driver interfaces don't pass in volumes or snapshots to the driver. As a result, drivers have to retrieve info from db. In this patch, these interfaces are changed so that drivers don't have to access db. Removing the access to db from driver CG functions will be handled by separate patches. * create_consistencygroup * delete_consistencygroup * create_cgsnapshot * delete_cgsnapshot Change-Id: I63287fd43927fc09dad77292ecfe561917f7bda5 Closes-Bug: #1501466 --- diff --git a/cinder/tests/unit/test_dellsc.py b/cinder/tests/unit/test_dellsc.py index 10fb791d3..3f27de76b 100644 --- a/cinder/tests/unit/test_dellsc.py +++ b/cinder/tests/unit/test_dellsc.py @@ -1281,7 +1281,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): group = {'id': 'fc8f2fec-fab2-4e34-9148-c094c913b9a3', 'status': 'deleted'} model_update, volumes = self.driver.delete_consistencygroup(context, - group) + group, + []) mock_find_replay_profile.assert_called_once_with(group['id']) mock_delete_replay_profile.assert_called_once_with(self.SCRPLAYPROFILE) mock_delete_volume.assert_called_once_with(mock_volume) @@ -1310,7 +1311,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): group = {'id': 'fc8f2fec-fab2-4e34-9148-c094c913b9a3', 'status': 'deleted'} model_update, volumes = self.driver.delete_consistencygroup(context, - group) + group, + []) mock_find_replay_profile.assert_called_once_with(group['id']) self.assertFalse(mock_delete_replay_profile.called) mock_delete_volume.assert_called_once_with(mock_volume) @@ -1413,7 +1415,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): context = {} cggrp = {'consistencygroup_id': 'fc8f2fec-fab2-4e34-9148-c094c913b9a3', 'id': '100'} - model_update, snapshots = self.driver.create_cgsnapshot(context, cggrp) + model_update, snapshots = self.driver.create_cgsnapshot(context, cggrp, + []) mock_find_replay_profile.assert_called_once_with( cggrp['consistencygroup_id']) mock_snap_cg_replay.assert_called_once_with(self.SCRPLAYPROFILE, @@ -1436,7 +1439,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_cgsnapshot, context, - cggrp) + cggrp, + []) mock_find_replay_profile.assert_called_once_with( cggrp['consistencygroup_id']) @@ -1458,7 +1462,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_cgsnapshot, context, - cggrp) + cggrp, + []) mock_find_replay_profile.assert_called_once_with( cggrp['consistencygroup_id']) mock_snap_cg_replay.assert_called_once_with(self.SCRPLAYPROFILE, @@ -1488,7 +1493,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): 'id': '100', 'status': 'deleted'} model_update, snapshots = self.driver.delete_cgsnapshot(context, - cgsnap) + cgsnap, + []) mock_find_replay_profile.assert_called_once_with( cgsnap['consistencygroup_id']) mock_delete_cg_replay.assert_called_once_with(self.SCRPLAYPROFILE, @@ -1518,7 +1524,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): 'id': '100', 'status': 'deleted'} model_update, snapshots = self.driver.delete_cgsnapshot(context, - cgsnap) + cgsnap, + []) mock_find_replay_profile.assert_called_once_with( cgsnap['consistencygroup_id']) @@ -1546,7 +1553,8 @@ class DellSCSanISCSIDriverTestCase(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_cgsnapshot, context, - cgsnap) + cgsnap, + []) mock_find_replay_profile.assert_called_once_with( cgsnap['consistencygroup_id']) mock_delete_cg_replay.assert_called_once_with(self.SCRPLAYPROFILE, diff --git a/cinder/tests/unit/test_emc_vmax.py b/cinder/tests/unit/test_emc_vmax.py index 2050375e8..021e57a75 100644 --- a/cinder/tests/unit/test_emc_vmax.py +++ b/cinder/tests/unit/test_emc_vmax.py @@ -3124,7 +3124,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -3137,7 +3137,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): def test_delete_CG_with_volumes_no_fast_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_utils.EMCVMAXUtils, @@ -3163,7 +3163,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage, _mock_cg, _mock_members, _mock_rg): self.driver.create_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -3176,7 +3176,7 @@ class EMCVMAXISCSIDriverNoFastTestCase(test.TestCase): def test_delete_snapshot_for_CG_no_fast_success( self, _mock_volume_type, _mock_storage): self.driver.delete_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -3991,7 +3991,7 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -4004,7 +4004,7 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): def test_delete_CG_with_volumes_fast_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_utils.EMCVMAXUtils, @@ -4030,7 +4030,7 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage, _mock_cg, _mock_members, _mock_rg): self.driver.create_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -4043,7 +4043,7 @@ class EMCVMAXISCSIDriverFastTestCase(test.TestCase): def test_delete_snapshot_for_CG_no_fast_success( self, _mock_volume_type, _mock_storage): self.driver.delete_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -4464,7 +4464,7 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -4477,7 +4477,7 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): def test_delete_CG_with_volumes_no_fast_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_utils.EMCVMAXUtils, @@ -4503,7 +4503,7 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage, _mock_cg, _mock_members, _mock_rg): self.driver.create_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -4516,7 +4516,7 @@ class EMCVMAXFCDriverNoFastTestCase(test.TestCase): def test_delete_snapshot_for_CG_no_fast_success( self, _mock_volume_type, _mock_storage): self.driver.delete_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) def test_manage_existing_get_size(self): volume = {} @@ -5215,7 +5215,7 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -5228,7 +5228,7 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): def test_delete_CG_with_volumes_fast_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_utils.EMCVMAXUtils, @@ -5254,7 +5254,7 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): self, _mock_volume_type, _mock_storage, _mock_cg, _mock_members, _mock_rg): self.driver.create_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -5267,7 +5267,7 @@ class EMCVMAXFCDriverFastTestCase(test.TestCase): def test_delete_snapshot_for_CG_no_fast_success( self, _mock_volume_type, _mock_storage): self.driver.delete_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) # Bug 1385450 def test_create_clone_without_license(self): @@ -5621,7 +5621,7 @@ class EMCV3DriverTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -5634,7 +5634,7 @@ class EMCV3DriverTestCase(test.TestCase): def test_delete_CG_with_volumes_v3_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( volume_types, @@ -5713,7 +5713,7 @@ class EMCV3DriverTestCase(test.TestCase): provisionv3 = self.driver.common.provisionv3 provisionv3.create_group_replica = mock.Mock(return_value=(0, None)) self.driver.create_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) repServ = self.conn.EnumerateInstanceNames("EMC_ReplicationService")[0] provisionv3.create_group_replica.assert_called_once_with( self.conn, repServ, @@ -5732,7 +5732,7 @@ class EMCV3DriverTestCase(test.TestCase): def test_delete_cgsnapshot_v3_success( self, _mock_volume_type, _mock_storage): self.driver.delete_cgsnapshot( - self.data.test_ctxt, self.data.test_CG_snapshot) + self.data.test_ctxt, self.data.test_CG_snapshot, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -6206,7 +6206,7 @@ class EMCV2MultiPoolDriverTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -6219,7 +6219,7 @@ class EMCV2MultiPoolDriverTestCase(test.TestCase): def test_delete_CG_with_volumes_multi_pool_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) def _cleanup(self): bExists = os.path.exists(self.config_file_path) @@ -6511,7 +6511,7 @@ class EMCV3MultiSloDriverTestCase(test.TestCase): self, _mock_volume_type, _mock_storage_system, _mock_db_volumes, _mock_members): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, @@ -6524,7 +6524,7 @@ class EMCV3MultiSloDriverTestCase(test.TestCase): def test_delete_CG_with_volumes_multi_slo_success( self, _mock_volume_type, _mock_storage_system): self.driver.delete_consistencygroup( - self.data.test_ctxt, self.data.test_CG) + self.data.test_ctxt, self.data.test_CG, []) def _cleanup(self): bExists = os.path.exists(self.config_file_path) @@ -6804,7 +6804,8 @@ class EMCV2MultiPoolDriverMultipleEcomsTestCase(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_consistencygroup, self.data.test_ctxt, - self.data.test_CG) + self.data.test_CG, + []) @mock.patch.object( emc_vmax_common.EMCVMAXCommon, diff --git a/cinder/tests/unit/test_emc_vnxdirect.py b/cinder/tests/unit/test_emc_vnxdirect.py index cf37e66d0..6a8d0a677 100644 --- a/cinder/tests/unit/test_emc_vnxdirect.py +++ b/cinder/tests/unit/test_emc_vnxdirect.py @@ -3695,7 +3695,8 @@ Time Remaining: 0 second(s) self.driver.db.volume_get_all_by_group.return_value =\ self.testData.CONSISTENCY_GROUP_VOLUMES() self.driver.delete_consistencygroup(None, - self.testData.test_cg) + self.testData.test_cg, + []) expect_cmd = [ mock.call( *self.testData.DELETE_CONSISTENCYGROUP_CMD( @@ -3716,7 +3717,7 @@ Time Remaining: 0 second(s) self.testData.SNAPS_IN_SNAP_GROUP()) snapshot_obj.consistencygroup_id = cg_name get_all_for_cgsnapshot.return_value = [snapshot_obj] - self.driver.create_cgsnapshot(None, self.testData.test_cgsnapshot) + self.driver.create_cgsnapshot(None, self.testData.test_cgsnapshot, []) expect_cmd = [ mock.call( *self.testData.CREATE_CG_SNAPSHOT( @@ -3736,7 +3737,8 @@ Time Remaining: 0 second(s) snapshot_obj.consistencygroup_id = cg_name get_all_for_cgsnapshot.return_value = [snapshot_obj] self.driver.delete_cgsnapshot(None, - self.testData.test_cgsnapshot) + self.testData.test_cgsnapshot, + []) expect_cmd = [ mock.call( *self.testData.DELETE_CG_SNAPSHOT( diff --git a/cinder/tests/unit/test_emc_xtremio.py b/cinder/tests/unit/test_emc_xtremio.py index 2486843c9..f90a93c23 100644 --- a/cinder/tests/unit/test_emc_xtremio.py +++ b/cinder/tests/unit/test_emc_xtremio.py @@ -466,7 +466,7 @@ class EMCXIODriverISCSITestCase(test.TestCase): self.driver.db = mock.Mock() (self.driver.db. volume_get_all_by_group.return_value) = [mock.MagicMock()] - self.driver.create_cgsnapshot(d.context, d.cgsnapshot) + self.driver.create_cgsnapshot(d.context, d.cgsnapshot, []) snapset_name = self.driver._get_cgsnap_name(d.cgsnapshot) self.assertEqual(snapset_name, '192eb39b6c2f420cbae33cfd117f0345192eb39b6c2f420cbae' @@ -476,8 +476,8 @@ class EMCXIODriverISCSITestCase(test.TestCase): 'name': snapset_name, 'index': 1} xms_data['snapshot-sets'] = {snapset_name: snapset1, 1: snapset1} - self.driver.delete_cgsnapshot(d.context, d.cgsnapshot) - self.driver.delete_consistencygroup(d.context, d.group) + self.driver.delete_cgsnapshot(d.context, d.cgsnapshot, []) + self.driver.delete_consistencygroup(d.context, d.group, []) xms_data['snapshot-sets'] = {} @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') @@ -496,7 +496,7 @@ class EMCXIODriverISCSITestCase(test.TestCase): self.driver.create_consistencygroup(d.context, d.group) self.driver.create_volume(d.test_volume) - self.driver.create_cgsnapshot(d.context, d.cgsnapshot) + self.driver.create_cgsnapshot(d.context, d.cgsnapshot, []) xms_data['volumes'][2]['ancestor-vol-id'] = (xms_data['volumes'][1] ['vol-id']) snapset_name = self.driver._get_cgsnap_name(d.cgsnapshot) diff --git a/cinder/tests/unit/test_gpfs.py b/cinder/tests/unit/test_gpfs.py index e47ef0ead..e7de73e9a 100644 --- a/cinder/tests/unit/test_gpfs.py +++ b/cinder/tests/unit/test_gpfs.py @@ -1672,7 +1672,7 @@ class GPFSDriverTestCase(test.TestCase): self.driver.db.volume_get_all_by_group = mock.Mock() self.driver.db.volume_get_all_by_group.return_value = volumes - self.driver.delete_consistencygroup(ctxt, group) + self.driver.delete_consistencygroup(ctxt, group, []) fsdev = self.driver._gpfs_device cgname = "consisgroup-%s" % group['id'] cmd = ['mmunlinkfileset', fsdev, cgname, '-f'] @@ -1692,7 +1692,7 @@ class GPFSDriverTestCase(test.TestCase): mock_exec.side_effect = ( processutils.ProcessExecutionError(stdout='test', stderr='test')) self.assertRaises(exception.VolumeBackendAPIException, - self.driver.delete_consistencygroup, ctxt, group) + self.driver.delete_consistencygroup, ctxt, group, []) @mock.patch('cinder.volume.drivers.ibm.gpfs.GPFSDriver.create_snapshot') def test_create_cgsnapshot(self, mock_create_snap): @@ -1703,7 +1703,8 @@ class GPFSDriverTestCase(test.TestCase): snapshot1 = self._fake_snapshot() snapshots = [snapshot1] self.driver.db.snapshot_get_all_for_cgsnapshot.return_value = snapshots - model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap) + model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap, + []) self.driver.create_snapshot.assert_called_once_with(snapshot1) self.assertEqual({'status': cgsnap['status']}, model_update) self.assertEqual('available', snapshot1['status']) @@ -1718,7 +1719,8 @@ class GPFSDriverTestCase(test.TestCase): self.driver.db.snapshot_get_all_for_cgsnapshot = mock.Mock() snapshots = [] self.driver.db.snapshot_get_all_for_cgsnapshot.return_value = snapshots - model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap) + model_update, snapshots = self.driver.create_cgsnapshot(ctxt, cgsnap, + []) self.assertFalse(self.driver.create_snapshot.called) self.assertEqual({'status': cgsnap['status']}, model_update) self.driver.db.snapshot_get_all_for_cgsnapshot.\ @@ -1733,7 +1735,8 @@ class GPFSDriverTestCase(test.TestCase): snapshot1 = self._fake_snapshot() snapshots = [snapshot1] self.driver.db.snapshot_get_all_for_cgsnapshot.return_value = snapshots - model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap) + model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap, + []) self.driver.delete_snapshot.assert_called_once_with(snapshot1) self.assertEqual({'status': cgsnap['status']}, model_update) self.assertEqual('deleted', snapshot1['status']) @@ -1748,7 +1751,8 @@ class GPFSDriverTestCase(test.TestCase): self.driver.db.snapshot_get_all_for_cgsnapshot = mock.Mock() snapshots = [] self.driver.db.snapshot_get_all_for_cgsnapshot.return_value = snapshots - model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap) + model_update, snapshots = self.driver.delete_cgsnapshot(ctxt, cgsnap, + []) self.assertFalse(self.driver.delete_snapshot.called) self.assertEqual({'status': cgsnap['status']}, model_update) self.driver.db.snapshot_get_all_for_cgsnapshot.\ diff --git a/cinder/tests/unit/test_hp3par.py b/cinder/tests/unit/test_hp3par.py index c80d8b807..5a6c01939 100644 --- a/cinder/tests/unit/test_hp3par.py +++ b/cinder/tests/unit/test_hp3par.py @@ -3106,7 +3106,7 @@ class HP3PARBaseDriver(object): # create a snapshot of the consistency group self.driver.create_cgsnapshot(context.get_admin_context(), - self.cgsnapshot) + self.cgsnapshot, []) expected = [ mock.call.createSnapshotOfVolumeSet( @@ -3171,7 +3171,7 @@ class HP3PARBaseDriver(object): # remove the consistency group group.status = 'deleting' self.driver.delete_consistencygroup(context.get_admin_context(), - group) + group, []) expected = [ mock.call.deleteVolumeSet( @@ -3391,7 +3391,7 @@ class HP3PARBaseDriver(object): # create a snapshot of the consistency group self.driver.create_cgsnapshot(context.get_admin_context(), - self.cgsnapshot) + self.cgsnapshot, []) expected = [ mock.call.createSnapshotOfVolumeSet( @@ -3476,7 +3476,7 @@ class HP3PARBaseDriver(object): # create a snapshot of the consistency group self.driver.create_cgsnapshot(context.get_admin_context(), - cgsnapshot) + cgsnapshot, []) expected = [ mock.call.createSnapshotOfVolumeSet( @@ -3487,7 +3487,7 @@ class HP3PARBaseDriver(object): # delete the snapshot of the consistency group cgsnapshot['status'] = 'deleting' self.driver.delete_cgsnapshot(context.get_admin_context(), - cgsnapshot) + cgsnapshot, []) mock_client.assert_has_calls( [mock.call.getWsApiVersion()] + diff --git a/cinder/tests/unit/test_hplefthand.py b/cinder/tests/unit/test_hplefthand.py index 727b1e8d5..e1eee13dd 100644 --- a/cinder/tests/unit/test_hplefthand.py +++ b/cinder/tests/unit/test_hplefthand.py @@ -2186,7 +2186,7 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, 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, []) self.assertEqual('deleting', cg['status']) @mock.patch('hplefthandclient.version', "1.0.6") @@ -2228,7 +2228,7 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, 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, []) self.assertEqual('deleting', cg['status']) @mock.patch('hplefthandclient.version', "1.0.6") @@ -2274,7 +2274,7 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, 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, []) self.assertEqual('deleting', cg['status']) @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') @@ -2315,7 +2315,7 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): # create the conistency group snapshot cgsnap, snaps = self.driver.create_cgsnapshot( - ctxt, self.cgsnapshot) + ctxt, self.cgsnapshot, []) self.assertEqual('available', cgsnap['status']) @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') @@ -2357,5 +2357,5 @@ class TestHPLeftHandRESTISCSIDriver(HPLeftHandBaseDriver, test.TestCase): # delete the consistency group snapshot self.cgsnapshot['status'] = 'deleting' cgsnap, snaps = self.driver.delete_cgsnapshot( - ctxt, self.cgsnapshot) + ctxt, self.cgsnapshot, []) self.assertEqual('deleting', cgsnap['status']) diff --git a/cinder/tests/unit/test_ibm_xiv_ds8k.py b/cinder/tests/unit/test_ibm_xiv_ds8k.py index de831cb42..049bc16e7 100644 --- a/cinder/tests/unit/test_ibm_xiv_ds8k.py +++ b/cinder/tests/unit/test_ibm_xiv_ds8k.py @@ -721,7 +721,7 @@ class XIVDS8KVolumeDriverTest(test.TestCase): # Delete consistency group model_update, volumes = \ - self.driver.delete_consistencygroup(ctxt, CONSISTGROUP) + self.driver.delete_consistencygroup(ctxt, CONSISTGROUP, []) # Verify the result self.assertEqual('deleted', @@ -751,7 +751,7 @@ class XIVDS8KVolumeDriverTest(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_consistencygroup, - ctxt, CONSISTGROUP) + ctxt, CONSISTGROUP, []) def test_create_cgsnapshot(self): """Test that create_cgsnapshot return successfully.""" @@ -768,7 +768,7 @@ class XIVDS8KVolumeDriverTest(test.TestCase): # Create consistency group snapshot model_update, snapshots = \ - self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT) + self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT, []) # Verify the result self.assertEqual('available', @@ -779,8 +779,8 @@ class XIVDS8KVolumeDriverTest(test.TestCase): snap['status']) # Clean the environment - self.driver.delete_cgsnapshot(ctxt, CG_SNAPSHOT) - self.driver.delete_consistencygroup(ctxt, CONSISTGROUP) + self.driver.delete_cgsnapshot(ctxt, CG_SNAPSHOT, []) + self.driver.delete_consistencygroup(ctxt, CONSISTGROUP, []) def test_create_cgsnapshot_fail_on_no_pool_space_left(self): """Test that create_cgsnapshot return fail when no pool space left.""" @@ -801,11 +801,11 @@ class XIVDS8KVolumeDriverTest(test.TestCase): self.assertRaises(exception.VolumeBackendAPIException, self.driver.create_cgsnapshot, - ctxt, CG_SNAPSHOT) + ctxt, CG_SNAPSHOT, []) # Clean the environment self.driver.volumes = None - self.driver.delete_consistencygroup(ctxt, CONSISTGROUP) + self.driver.delete_consistencygroup(ctxt, CONSISTGROUP, []) def test_delete_cgsnapshot(self): """Test that delete_cgsnapshot return successfully.""" @@ -821,11 +821,11 @@ class XIVDS8KVolumeDriverTest(test.TestCase): self.driver.create_volume(VOLUME) # Create consistency group snapshot - self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT) + self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT, []) # Delete consistency group snapshot model_update, snapshots = \ - self.driver.delete_cgsnapshot(ctxt, CG_SNAPSHOT) + self.driver.delete_cgsnapshot(ctxt, CG_SNAPSHOT, []) # Verify the result self.assertEqual('deleted', @@ -836,7 +836,7 @@ class XIVDS8KVolumeDriverTest(test.TestCase): snap['status']) # Clean the environment - self.driver.delete_consistencygroup(ctxt, CONSISTGROUP) + self.driver.delete_consistencygroup(ctxt, CONSISTGROUP, []) def test_delete_cgsnapshot_fail_on_snapshot_not_delete(self): """Test delete_cgsnapshot when the snapshot cannot be deleted.""" @@ -856,11 +856,11 @@ class XIVDS8KVolumeDriverTest(test.TestCase): self.driver.create_volume(volume) # Create consistency group snapshot - self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT) + self.driver.create_cgsnapshot(ctxt, CG_SNAPSHOT, []) self.assertRaises(exception.VolumeBackendAPIException, self.driver.delete_cgsnapshot, - ctxt, CG_SNAPSHOT) + ctxt, CG_SNAPSHOT, []) def test_update_consistencygroup_without_volumes(self): """Test update_consistencygroup when there are no volumes specified.""" diff --git a/cinder/tests/unit/test_prophetstor_dpl.py b/cinder/tests/unit/test_prophetstor_dpl.py index ada7b8125..56c4060d3 100644 --- a/cinder/tests/unit/test_prophetstor_dpl.py +++ b/cinder/tests/unit/test_prophetstor_dpl.py @@ -691,7 +691,7 @@ class TestProphetStorDPLDriver(test.TestCase): self.DPL_MOCK.delete_vdev.return_value = DATA_OUTPUT self.DPL_MOCK.delete_cg.return_value = DATA_OUTPUT model_update, volumes = self.dpldriver.delete_consistencygroup( - self.context, DATA_IN_GROUP) + self.context, DATA_IN_GROUP, []) self.DPL_MOCK.delete_vg.assert_called_once_with( self._conver_uuid2hex(DATA_IN_GROUP['id'])) self.DPL_MOCK.delete_vdev.assert_called_once_with( @@ -748,7 +748,7 @@ class TestProphetStorDPLDriver(test.TestCase): get_all_for_cgsnapshot.return_value = [snapshot_obj] self.DPL_MOCK.create_vdev_snapshot.return_value = DATA_OUTPUT model_update, snapshots = self.dpldriver.create_cgsnapshot( - self.context, snapshot_obj) + self.context, snapshot_obj, []) self.assertDictMatch({'status': 'available'}, model_update) @mock.patch('cinder.objects.snapshot.SnapshotList.get_all_for_cgsnapshot') @@ -759,7 +759,7 @@ class TestProphetStorDPLDriver(test.TestCase): get_all_for_cgsnapshot.return_value = [snapshot_obj] self.DPL_MOCK.delete_cgsnapshot.return_value = DATA_OUTPUT model_update, snapshots = self.dpldriver.delete_cgsnapshot( - self.context, DATA_IN_CG_SNAPSHOT) + self.context, DATA_IN_CG_SNAPSHOT, []) self.DPL_MOCK.delete_vdev_snapshot.assert_called_once_with( self._conver_uuid2hex(DATA_IN_CG_SNAPSHOT['consistencygroup_id']), self._conver_uuid2hex(DATA_IN_CG_SNAPSHOT['id']), diff --git a/cinder/tests/unit/test_pure.py b/cinder/tests/unit/test_pure.py index 166907f72..83d385d62 100644 --- a/cinder/tests/unit/test_pure.py +++ b/cinder/tests/unit/test_pure.py @@ -776,7 +776,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.driver.db.volume_get_all_by_group.return_value = expected_volumes model_update, volumes = \ - self.driver.delete_consistencygroup(mock_context, mock_cgroup) + self.driver.delete_consistencygroup(mock_context, mock_cgroup, []) expected_name = self.driver._get_pgroup_name_from_id(mock_cgroup.id) self.array.destroy_pgroup.assert_called_with(expected_name) @@ -789,7 +789,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): code=400, text="Protection group has been destroyed." ) - self.driver.delete_consistencygroup(mock_context, mock_cgroup) + self.driver.delete_consistencygroup(mock_context, mock_cgroup, []) self.array.destroy_pgroup.assert_called_with(expected_name) mock_delete_volume.assert_called_with(self.driver, mock_volume) @@ -798,7 +798,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): code=400, text="Protection group does not exist" ) - self.driver.delete_consistencygroup(mock_context, mock_cgroup) + self.driver.delete_consistencygroup(mock_context, mock_cgroup, []) self.array.destroy_pgroup.assert_called_with(expected_name) mock_delete_volume.assert_called_with(self.driver, mock_volume) @@ -810,7 +810,8 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.assertRaises(self.purestorage_module.PureHTTPError, self.driver.delete_consistencygroup, mock_context, - mock_volume) + mock_volume, + []) self.array.destroy_pgroup.side_effect = \ self.purestorage_module.PureHTTPError( @@ -820,12 +821,13 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.assertRaises(self.purestorage_module.PureHTTPError, self.driver.delete_consistencygroup, mock_context, - mock_volume) + mock_volume, + []) self.array.destroy_pgroup.side_effect = None self.assert_error_propagates( [self.array.destroy_pgroup], - self.driver.delete_consistencygroup, mock_context, mock_cgroup) + self.driver.delete_consistencygroup, mock_context, mock_cgroup, []) def _create_mock_cg(self): mock_group = mock.MagicMock() @@ -910,7 +912,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): mock_snap_list.return_value = expected_snaps model_update, snapshots = \ - self.driver.create_cgsnapshot(mock_context, mock_cgsnap) + self.driver.create_cgsnapshot(mock_context, mock_cgsnap, []) cg_id = mock_cgsnap.consistencygroup_id expected_pgroup_name = self.driver._get_pgroup_name_from_id(cg_id) @@ -924,7 +926,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.assert_error_propagates( [self.array.create_pgroup_snapshot], - self.driver.create_cgsnapshot, mock_context, mock_cgsnap) + self.driver.create_cgsnapshot, mock_context, mock_cgsnap, []) @mock.patch(BASE_DRIVER_OBJ + "._get_pgroup_snap_name", spec=pure.PureBaseVolumeDriver._get_pgroup_snap_name) @@ -941,7 +943,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): mock_snap_list.return_value = expected_snaps model_update, snapshots = \ - self.driver.delete_cgsnapshot(mock_context, mock_cgsnap) + self.driver.delete_cgsnapshot(mock_context, mock_cgsnap, []) self.array.destroy_pgroup.assert_called_with(snap_name) self.assertEqual({'status': mock_cgsnap.status}, model_update) @@ -953,7 +955,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): code=400, text="Protection group snapshot has been destroyed." ) - self.driver.delete_cgsnapshot(mock_context, mock_cgsnap) + self.driver.delete_cgsnapshot(mock_context, mock_cgsnap, []) self.array.destroy_pgroup.assert_called_with(snap_name) self.array.destroy_pgroup.side_effect = \ @@ -961,7 +963,7 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): code=400, text="Protection group snapshot does not exist" ) - self.driver.delete_cgsnapshot(mock_context, mock_cgsnap) + self.driver.delete_cgsnapshot(mock_context, mock_cgsnap, []) self.array.destroy_pgroup.assert_called_with(snap_name) self.array.destroy_pgroup.side_effect = \ @@ -972,7 +974,8 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.assertRaises(self.purestorage_module.PureHTTPError, self.driver.delete_cgsnapshot, mock_context, - mock_cgsnap) + mock_cgsnap, + []) self.array.destroy_pgroup.side_effect = \ self.purestorage_module.PureHTTPError( @@ -982,13 +985,14 @@ class PureBaseVolumeDriverTestCase(PureDriverTestCase): self.assertRaises(self.purestorage_module.PureHTTPError, self.driver.delete_cgsnapshot, mock_context, - mock_cgsnap) + mock_cgsnap, + []) self.array.destroy_pgroup.side_effect = None self.assert_error_propagates( [self.array.destroy_pgroup], - self.driver.delete_cgsnapshot, mock_context, mock_cgsnap) + self.driver.delete_cgsnapshot, mock_context, mock_cgsnap, []) def test_manage_existing(self): ref_name = 'vol1' diff --git a/cinder/tests/unit/test_storwize_svc.py b/cinder/tests/unit/test_storwize_svc.py index b85f683aa..647c536af 100644 --- a/cinder/tests/unit/test_storwize_svc.py +++ b/cinder/tests/unit/test_storwize_svc.py @@ -3499,7 +3499,8 @@ class StorwizeSVCDriverTestCase(test.TestCase): consistencygroup_id=cg['id']) cg_snapshot = self._create_cgsnapshot_in_db(cg['id']) - model_update = self.driver.create_cgsnapshot(self.ctxt, cg_snapshot) + model_update = self.driver.create_cgsnapshot(self.ctxt, cg_snapshot, + []) self.assertEqual('available', model_update[0]['status'], "CGSnapshot created failed") @@ -3507,7 +3508,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): for snapshot in model_update[1]: self.assertEqual('available', snapshot['status']) - model_update = self.driver.delete_consistencygroup(self.ctxt, cg) + model_update = self.driver.delete_consistencygroup(self.ctxt, cg, []) self.assertEqual('deleted', model_update[0]['status']) for volume in model_update[1]: diff --git a/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py b/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py index 660ff2287..172e457f6 100644 --- a/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py +++ b/cinder/tests/unit/volume/drivers/emc/scaleio/mocks.py @@ -65,7 +65,7 @@ class ScaleIODriver(scaleio.ScaleIODriver): def promote_replica(self, context, volume): pass - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): pass def create_consistencygroup_from_src(self, context, group, volumes, @@ -84,10 +84,10 @@ class ScaleIODriver(scaleio.ScaleIODriver): def unmanage(self, volume): pass - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): pass - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): pass diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py index bb6d08e69..ee52fad85 100644 --- a/cinder/volume/driver.py +++ b/cinder/volume/driver.py @@ -1484,12 +1484,12 @@ class SnapshotVD(object): @six.add_metaclass(abc.ABCMeta) class ConsistencyGroupVD(object): @abc.abstractmethod - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" return @abc.abstractmethod - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" return @@ -1499,7 +1499,7 @@ class ConsistencyGroupVD(object): return @abc.abstractmethod - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" return @@ -2048,7 +2048,24 @@ class VolumeDriver(ConsistencyGroupVD, TransferVD, ManageableVD, ExtendVD, """Disallow connection from connector for a snapshot.""" def create_consistencygroup(self, context, group): - """Creates a consistencygroup.""" + """Creates a consistencygroup. + + :param context: the context of the caller. + :param group: the dictionary of the consistency group to be created. + :return model_update + + model_update will be in this format: {'status': xxx, ......}. + + If the status in model_update is 'error', the manager will throw + an exception and it will be caught in the try-except block in the + manager. If the driver throws an exception, the manager will also + catch it in the try-except block. The group status in the db will + be changed to 'error'. + + For a successful operation, the driver can either build the + model_update and return it or return None. The group status will + be set to 'available'. + """ raise NotImplementedError() def create_consistencygroup_from_src(self, context, group, volumes, @@ -2071,8 +2088,8 @@ class VolumeDriver(ConsistencyGroupVD, TransferVD, ManageableVD, ExtendVD, cinder.db.sqlalchemy.models.Volume to be precise. It cannot be assigned to volumes_model_update. volumes_model_update is a list of dictionaries. It has to be built by the driver. An entry will be - in this format: ['id': xxx, 'status': xxx, ......]. model_update - will be in this format: ['status': xxx, ......]. + in this format: {'id': xxx, 'status': xxx, ......}. model_update + will be in this format: {'status': xxx, ......}. To be consistent with other volume operations, the manager will assume the operation is successful if no exception is thrown by @@ -2082,8 +2099,48 @@ class VolumeDriver(ConsistencyGroupVD, TransferVD, ManageableVD, ExtendVD, """ raise NotImplementedError() - def delete_consistencygroup(self, context, group): - """Deletes a consistency group.""" + def delete_consistencygroup(self, context, group, volumes): + """Deletes a consistency group. + + :param context: the context of the caller. + :param group: the dictionary of the consistency group to be deleted. + :param volumes: a list of volume dictionaries in the group. + :return model_update, volumes_model_update + + param volumes is retrieved directly from the db. It is a list of + cinder.db.sqlalchemy.models.Volume to be precise. It cannot be + assigned to volumes_model_update. volumes_model_update is a list of + dictionaries. It has to be built by the driver. An entry will be + in this format: {'id': xxx, 'status': xxx, ......}. model_update + will be in this format: {'status': xxx, ......}. + + The driver should populate volumes_model_update and model_update + and return them. + + The manager will check volumes_model_update and update db accordingly + for each volume. If the driver successfully deleted some volumes + but failed to delete others, it should set statuses of the volumes + accordingly so that the manager can update db correctly. + + If the status in any entry of volumes_model_update is 'error_deleting' + or 'error', the status in model_update will be set to the same if it + is not already 'error_deleting' or 'error'. + + If the status in model_update is 'error_deleting' or 'error', the + manager will raise an exception and the status of the group will be + set to 'error' in the db. If volumes_model_update is not returned by + the driver, the manager will set the status of every volume in the + group to 'error' in the except block. + + If the driver raises an exception during the operation, it will be + caught by the try-except block in the manager. The statuses of the + group and all volumes in it will be set to 'error'. + + For a successful operation, the driver can either build the + model_update and volumes_model_update and return them or + return None, None. The statuses of the group and all volumes + will be set to 'deleted' after the manager deletes them from db. + """ raise NotImplementedError() def update_consistencygroup(self, context, group, @@ -2114,12 +2171,92 @@ class VolumeDriver(ConsistencyGroupVD, TransferVD, ManageableVD, ExtendVD, """ raise NotImplementedError() - def create_cgsnapshot(self, context, cgsnapshot): - """Creates a cgsnapshot.""" + def create_cgsnapshot(self, context, cgsnapshot, snapshots): + """Creates a cgsnapshot. + + :param context: the context of the caller. + :param cgsnapshot: the dictionary of the cgsnapshot to be created. + :param snapshots: a list of snapshot dictionaries in the cgsnapshot. + :return model_update, snapshots_model_update + + param snapshots is retrieved directly from the db. It is a list of + cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be + assigned to snapshots_model_update. snapshots_model_update is a list + of dictionaries. It has to be built by the driver. An entry will be + in this format: {'id': xxx, 'status': xxx, ......}. model_update + will be in this format: {'status': xxx, ......}. + + The driver should populate snapshots_model_update and model_update + and return them. + + The manager will check snapshots_model_update and update db accordingly + for each snapshot. If the driver successfully deleted some snapshots + but failed to delete others, it should set statuses of the snapshots + accordingly so that the manager can update db correctly. + + If the status in any entry of snapshots_model_update is 'error', the + status in model_update will be set to the same if it is not already + 'error'. + + If the status in model_update is 'error', the manager will raise an + exception and the status of cgsnapshot will be set to 'error' in the + db. If snapshots_model_update is not returned by the driver, the + manager will set the status of every snapshot to 'error' in the except + block. + + If the driver raises an exception during the operation, it will be + caught by the try-except block in the manager and the statuses of + cgsnapshot and all snapshots will be set to 'error'. + + For a successful operation, the driver can either build the + model_update and snapshots_model_update and return them or + return None, None. The statuses of cgsnapshot and all snapshots + will be set to 'available' at the end of the manager function. + """ raise NotImplementedError() - def delete_cgsnapshot(self, context, cgsnapshot): - """Deletes a cgsnapshot.""" + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): + """Deletes a cgsnapshot. + + :param context: the context of the caller. + :param cgsnapshot: the dictionary of the cgsnapshot to be deleted. + :param snapshots: a list of snapshot dictionaries in the cgsnapshot. + :return model_update, snapshots_model_update + + param snapshots is retrieved directly from the db. It is a list of + cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be + assigned to snapshots_model_update. snapshots_model_update is a list + of dictionaries. It has to be built by the driver. An entry will be + in this format: {'id': xxx, 'status': xxx, ......}. model_update + will be in this format: {'status': xxx, ......}. + + The driver should populate snapshots_model_update and model_update + and return them. + + The manager will check snapshots_model_update and update db accordingly + for each snapshot. If the driver successfully deleted some snapshots + but failed to delete others, it should set statuses of the snapshots + accordingly so that the manager can update db correctly. + + If the status in any entry of snapshots_model_update is + 'error_deleting' or 'error', the status in model_update will be set to + the same if it is not already 'error_deleting' or 'error'. + + If the status in model_update is 'error_deleting' or 'error', the + manager will raise an exception and the status of cgsnapshot will be + set to 'error' in the db. If snapshots_model_update is not returned by + the driver, the manager will set the status of every snapshot to + 'error' in the except block. + + If the driver raises an exception during the operation, it will be + caught by the try-except block in the manager and the statuses of + cgsnapshot and all snapshots will be set to 'error'. + + For a successful operation, the driver can either build the + model_update and snapshots_model_update and return them or + return None, None. The statuses of cgsnapshot and all snapshots + will be set to 'deleted' after the manager deletes them from db. + """ raise NotImplementedError() def clone_image(self, volume, image_location, image_id, image_meta, diff --git a/cinder/volume/drivers/dell/dell_storagecenter_common.py b/cinder/volume/drivers/dell/dell_storagecenter_common.py index 46299d347..4e010a1de 100644 --- a/cinder/volume/drivers/dell/dell_storagecenter_common.py +++ b/cinder/volume/drivers/dell/dell_storagecenter_common.py @@ -430,7 +430,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD, raise exception.VolumeBackendAPIException( _('Unable to create consistency group %s') % gid) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Delete the Dell SC profile associated with this consistency group. :param context: the context of the caller. @@ -497,7 +497,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD, raise exception.VolumeBackendAPIException( _('Unable to update consistency group %s') % gid) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Takes a snapshot of the consistency group. :param context: the context of the caller. @@ -530,7 +530,7 @@ class DellCommonDriver(driver.ConsistencyGroupVD, driver.ManageableVD, raise exception.VolumeBackendAPIException( _('Unable to snap Consistency Group %s') % cgid) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot. If profile isn't found return success. If failed to delete the diff --git a/cinder/volume/drivers/emc/emc_cli_fc.py b/cinder/volume/drivers/emc/emc_cli_fc.py index 95118dc53..90e261ba4 100644 --- a/cinder/volume/drivers/emc/emc_cli_fc.py +++ b/cinder/volume/drivers/emc/emc_cli_fc.py @@ -230,17 +230,17 @@ class EMCCLIFCDriver(driver.FibreChannelDriver): """Creates a consistencygroup.""" return self.cli.create_consistencygroup(context, group) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" return self.cli.delete_consistencygroup( self, context, group) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" return self.cli.create_cgsnapshot( self, context, cgsnapshot) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" return self.cli.delete_cgsnapshot(self, context, cgsnapshot) diff --git a/cinder/volume/drivers/emc/emc_cli_iscsi.py b/cinder/volume/drivers/emc/emc_cli_iscsi.py index 7fa8e1c71..379a993ef 100644 --- a/cinder/volume/drivers/emc/emc_cli_iscsi.py +++ b/cinder/volume/drivers/emc/emc_cli_iscsi.py @@ -209,17 +209,17 @@ class EMCCLIISCSIDriver(driver.ISCSIDriver): """Creates a consistencygroup.""" return self.cli.create_consistencygroup(context, group) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" return self.cli.delete_consistencygroup( self, context, group) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" return self.cli.create_cgsnapshot( self, context, cgsnapshot) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" return self.cli.delete_cgsnapshot(self, context, cgsnapshot) diff --git a/cinder/volume/drivers/emc/emc_vmax_fc.py b/cinder/volume/drivers/emc/emc_vmax_fc.py index 13404bc42..3c16d7e0d 100644 --- a/cinder/volume/drivers/emc/emc_vmax_fc.py +++ b/cinder/volume/drivers/emc/emc_vmax_fc.py @@ -313,17 +313,16 @@ class EMCVMAXFCDriver(driver.FibreChannelDriver): """Creates a consistencygroup.""" self.common.create_consistencygroup(context, group) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" - volumes = self.db.volume_get_all_by_group(context, group['id']) return self.common.delete_consistencygroup( context, group, volumes) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" return self.common.create_cgsnapshot(context, cgsnapshot, self.db) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" return self.common.delete_cgsnapshot(context, cgsnapshot, self.db) diff --git a/cinder/volume/drivers/emc/emc_vmax_iscsi.py b/cinder/volume/drivers/emc/emc_vmax_iscsi.py index b120a736e..f0ceb187e 100644 --- a/cinder/volume/drivers/emc/emc_vmax_iscsi.py +++ b/cinder/volume/drivers/emc/emc_vmax_iscsi.py @@ -331,17 +331,16 @@ class EMCVMAXISCSIDriver(driver.ISCSIDriver): """Creates a consistencygroup.""" self.common.create_consistencygroup(context, group) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" - volumes = self.db.volume_get_all_by_group(context, group['id']) return self.common.delete_consistencygroup( context, group, volumes) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" return self.common.create_cgsnapshot(context, cgsnapshot, self.db) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" return self.common.delete_cgsnapshot(context, cgsnapshot, self.db) diff --git a/cinder/volume/drivers/emc/xtremio.py b/cinder/volume/drivers/emc/xtremio.py index a147d8c8b..6578b05f2 100644 --- a/cinder/volume/drivers/emc/xtremio.py +++ b/cinder/volume/drivers/emc/xtremio.py @@ -565,7 +565,7 @@ class XtremIOVolumeDriver(san.SanDriver): ver='v2') return {'status': 'available'} - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" self.client.req('consistency-groups', 'DELETE', name=group['id'], ver='v2') @@ -647,7 +647,7 @@ class XtremIOVolumeDriver(san.SanDriver): .replace('-', ''), 'snap': cgsnapshot['id'].replace('-', '')} - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" data = {'consistency-group-id': cgsnapshot['consistencygroup_id'], 'snapshot-set-name': self._get_cgsnap_name(cgsnapshot)} @@ -663,7 +663,7 @@ class XtremIOVolumeDriver(san.SanDriver): return model_update, snapshots - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" self.client.req('snapshot-sets', 'DELETE', name=self._get_cgsnap_name(cgsnapshot), ver='v2') diff --git a/cinder/volume/drivers/ibm/gpfs.py b/cinder/volume/drivers/ibm/gpfs.py index 691ea3f32..ba6693178 100644 --- a/cinder/volume/drivers/ibm/gpfs.py +++ b/cinder/volume/drivers/ibm/gpfs.py @@ -1158,7 +1158,7 @@ class GPFSDriver(driver.ConsistencyGroupVD, driver.ExtendVD, model_update = {'status': 'available'} return model_update - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Delete consistency group of GPFS volumes.""" cgname = "consisgroup-%s" % group['id'] fsdev = self._gpfs_device @@ -1194,7 +1194,7 @@ class GPFSDriver(driver.ConsistencyGroupVD, driver.ExtendVD, return model_update, volumes - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Create snapshot of a consistency group of GPFS volumes.""" snapshots = self.db.snapshot_get_all_for_cgsnapshot( context, cgsnapshot['id']) @@ -1207,7 +1207,7 @@ class GPFSDriver(driver.ConsistencyGroupVD, driver.ExtendVD, return model_update, snapshots - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Delete snapshot of a consistency group of GPFS volumes.""" snapshots = self.db.snapshot_get_all_for_cgsnapshot( context, cgsnapshot['id']) diff --git a/cinder/volume/drivers/ibm/storwize_svc/__init__.py b/cinder/volume/drivers/ibm/storwize_svc/__init__.py index 9fe37c8da..9c3e62066 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/__init__.py +++ b/cinder/volume/drivers/ibm/storwize_svc/__init__.py @@ -1053,7 +1053,7 @@ class StorwizeSVCDriver(san.SanDriver, model_update = {'status': 'available'} return model_update - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group. IBM Storwize will delete the volumes of the CG. @@ -1076,7 +1076,7 @@ class StorwizeSVCDriver(san.SanDriver, {'vol': volume['name'], 'exception': err}) return model_update, volumes - def create_cgsnapshot(self, ctxt, cgsnapshot): + def create_cgsnapshot(self, ctxt, cgsnapshot, snapshots): """Creates a cgsnapshot.""" # Use cgsnapshot id as cg name cg_name = 'cg_snap-' + cgsnapshot['id'] @@ -1096,7 +1096,7 @@ class StorwizeSVCDriver(san.SanDriver, return model_update, snapshots_model - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" cgsnapshot_id = cgsnapshot['id'] cg_name = 'cg_snap-' + cgsnapshot_id diff --git a/cinder/volume/drivers/ibm/xiv_ds8k.py b/cinder/volume/drivers/ibm/xiv_ds8k.py index 3e9abffc3..afbdc9544 100644 --- a/cinder/volume/drivers/ibm/xiv_ds8k.py +++ b/cinder/volume/drivers/ibm/xiv_ds8k.py @@ -247,17 +247,17 @@ class XIVDS8KDriver(san.SanDriver, return self.xiv_ds8k_proxy.create_consistencygroup(context, group) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" return self.xiv_ds8k_proxy.delete_consistencygroup(context, group) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a consistency group snapshot.""" return self.xiv_ds8k_proxy.create_cgsnapshot(context, cgsnapshot) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a consistency group snapshot.""" return self.xiv_ds8k_proxy.delete_cgsnapshot(context, cgsnapshot) diff --git a/cinder/volume/drivers/prophetstor/dplcommon.py b/cinder/volume/drivers/prophetstor/dplcommon.py index 18109769e..8fa790ab6 100644 --- a/cinder/volume/drivers/prophetstor/dplcommon.py +++ b/cinder/volume/drivers/prophetstor/dplcommon.py @@ -887,7 +887,7 @@ class DPLCOMMONDriver(driver.ConsistencyGroupVD, driver.ExtendVD, 'reason': six.text_type(e)} raise exception.VolumeBackendAPIException(data=msg) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Delete a consistency group.""" ret = 0 volumes = self.db.volume_get_all_by_group( @@ -916,7 +916,7 @@ class DPLCOMMONDriver(driver.ConsistencyGroupVD, driver.ExtendVD, model_update['status'] = 'deleted' return model_update, volumes - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" snapshots = objects.SnapshotList().get_all_for_cgsnapshot( context, cgsnapshot['id']) @@ -943,7 +943,7 @@ class DPLCOMMONDriver(driver.ConsistencyGroupVD, driver.ExtendVD, return model_update, snapshots - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" snapshots = objects.SnapshotList().get_all_for_cgsnapshot( context, cgsnapshot['id']) diff --git a/cinder/volume/drivers/pure.py b/cinder/volume/drivers/pure.py index 4cb1663b1..66c6c8214 100644 --- a/cinder/volume/drivers/pure.py +++ b/cinder/volume/drivers/pure.py @@ -399,7 +399,7 @@ class PureBaseVolumeDriver(san.SanDriver): return None, None @log_debug_trace - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" try: @@ -446,7 +446,7 @@ class PureBaseVolumeDriver(san.SanDriver): return None, None, None @log_debug_trace - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a cgsnapshot.""" cg_id = cgsnapshot.consistencygroup_id @@ -481,7 +481,7 @@ class PureBaseVolumeDriver(san.SanDriver): "Snapshot: %s"), err.text) @log_debug_trace - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a cgsnapshot.""" pgsnap_name = self._get_pgroup_snap_name(cgsnapshot) diff --git a/cinder/volume/drivers/san/hp/hp_3par_fc.py b/cinder/volume/drivers/san/hp/hp_3par_fc.py index 40d55c61c..4a03b408f 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_fc.py +++ b/cinder/volume/drivers/san/hp/hp_3par_fc.py @@ -454,7 +454,7 @@ class HP3PARFCDriver(driver.TransferVD, finally: self._logout(common) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): common = self._login() try: return common.delete_consistencygroup(context, group) @@ -470,14 +470,14 @@ class HP3PARFCDriver(driver.TransferVD, finally: self._logout(common) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: return common.create_cgsnapshot(context, cgsnapshot) finally: self._logout(common) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: return common.delete_cgsnapshot(context, cgsnapshot) diff --git a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py index f4fc7ecfc..39d474ce2 100644 --- a/cinder/volume/drivers/san/hp/hp_3par_iscsi.py +++ b/cinder/volume/drivers/san/hp/hp_3par_iscsi.py @@ -751,7 +751,7 @@ class HP3PARISCSIDriver(driver.TransferVD, finally: self._logout(common) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): common = self._login() try: return common.delete_consistencygroup(context, group) @@ -767,14 +767,14 @@ class HP3PARISCSIDriver(driver.TransferVD, finally: self._logout(common) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: return common.create_cgsnapshot(context, cgsnapshot) finally: self._logout(common) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): common = self._login() try: return common.delete_cgsnapshot(context, cgsnapshot) diff --git a/cinder/volume/drivers/san/hp/hp_lefthand_iscsi.py b/cinder/volume/drivers/san/hp/hp_lefthand_iscsi.py index 09c929755..01ed065be 100644 --- a/cinder/volume/drivers/san/hp/hp_lefthand_iscsi.py +++ b/cinder/volume/drivers/san/hp/hp_lefthand_iscsi.py @@ -129,7 +129,7 @@ class HPLeftHandISCSIDriver(driver.TransferVD, context, group, volumes, cgsnapshot, snapshots, source_cg, source_vols) - def delete_consistencygroup(self, context, group): + def delete_consistencygroup(self, context, group, volumes): """Deletes a consistency group.""" return self.proxy.delete_consistencygroup(context, group) @@ -139,11 +139,11 @@ class HPLeftHandISCSIDriver(driver.TransferVD, return self.proxy.update_consistencygroup(context, group, add_volumes, remove_volumes) - def create_cgsnapshot(self, context, cgsnapshot): + def create_cgsnapshot(self, context, cgsnapshot, snapshots): """Creates a consistency group snapshot.""" return self.proxy.create_cgsnapshot(context, cgsnapshot) - def delete_cgsnapshot(self, context, cgsnapshot): + def delete_cgsnapshot(self, context, cgsnapshot, snapshots): """Deletes a consistency group snapshot.""" return self.proxy.delete_cgsnapshot(context, cgsnapshot) diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index 74e3b9af2..db0a68568 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -2297,7 +2297,7 @@ class VolumeManager(manager.SchedulerDependentManager): context = context.elevated() status = 'available' - model_update = False + model_update = None self._notify_about_consistencygroup_usage( context, group, "create.start") @@ -2310,8 +2310,15 @@ class VolumeManager(manager.SchedulerDependentManager): group) if model_update: - group.update(model_update) - group.save() + if model_update['status'] == 'error': + msg = (_('Create consistency group failed.')) + LOG.error(msg, + resource={'type': 'consistency_group', + 'id': group.id}) + raise exception.VolumeDriverException(message=msg) + else: + group.update(model_update) + group.save() except Exception: with excutils.save_and_reraise_exception(): group.status = 'error' @@ -2602,14 +2609,16 @@ class VolumeManager(manager.SchedulerDependentManager): self._notify_about_consistencygroup_usage( context, group, "delete.start") + volumes_model_update = None + model_update = None try: utils.require_driver_initialized(self.driver) - model_update, volumes = self.driver.delete_consistencygroup( - context, group) + model_update, volumes_model_update = ( + self.driver.delete_consistencygroup(context, group, volumes)) - if volumes: - for volume in volumes: + if volumes_model_update: + for volume in volumes_model_update: update = {'status': volume['status']} self.db.volume_update(context, volume['id'], update) @@ -2633,8 +2642,14 @@ class VolumeManager(manager.SchedulerDependentManager): except Exception: with excutils.save_and_reraise_exception(): - group.status = 'error_deleting' + group.status = 'error' group.save() + # Update volume status to 'error' if driver returns + # None for volumes_model_update. + if not volumes_model_update: + for vol in volumes: + self.db.volume_update( + context, vol['id'], {'status': 'error'}) # Get reservations for group try: @@ -2843,6 +2858,8 @@ class VolumeManager(manager.SchedulerDependentManager): self._notify_about_cgsnapshot_usage( context, cgsnapshot, "create.start") + snapshots_model_update = None + model_update = None try: utils.require_driver_initialized(self.driver) @@ -2855,23 +2872,26 @@ class VolumeManager(manager.SchedulerDependentManager): for snapshot in snapshots: snapshot.context = caller_context - model_update, snapshots = \ - self.driver.create_cgsnapshot(context, cgsnapshot) + model_update, snapshots_model_update = ( + self.driver.create_cgsnapshot(context, cgsnapshot, + snapshots)) - if snapshots: - for snapshot in snapshots: + if snapshots_model_update: + for snap_model in snapshots_model_update: # Update db if status is error - if snapshot['status'] == 'error': - update = {'status': snapshot['status']} - - # TODO(thangp): Switch over to use snapshot.update() - # after cgsnapshot-objects bugs are fixed - self.db.snapshot_update(context, snapshot['id'], - update) - # If status for one snapshot is error, make sure - # the status for the cgsnapshot is also error - if model_update['status'] != 'error': - model_update['status'] = snapshot['status'] + if snap_model['status'] == 'error': + # NOTE(xyang): snapshots is a list of snapshot objects. + # snapshots_model_update should be a list of dicts. + snap = next((item for item in snapshots if + item.id == snap_model['id']), None) + if snap: + snap.status = snap_model['status'] + snap.save() + + if (snap_model['status'] in ['error_deleting', 'error'] and + model_update['status'] not in + ['error_deleting', 'error']): + model_update['status'] = snap_model['status'] if model_update: if model_update['status'] == 'error': @@ -2880,10 +2900,16 @@ class VolumeManager(manager.SchedulerDependentManager): LOG.error(msg) raise exception.VolumeDriverException(message=msg) - except Exception: + except exception.CinderException: with excutils.save_and_reraise_exception(): cgsnapshot.status = 'error' cgsnapshot.save() + # Update snapshot status to 'error' if driver returns + # None for snapshots_model_update. + if not snapshots_model_update: + for snapshot in snapshots: + snapshot.status = 'error' + snapshot.save() for snapshot in snapshots: volume_id = snapshot['volume_id'] @@ -2934,6 +2960,8 @@ class VolumeManager(manager.SchedulerDependentManager): self._notify_about_cgsnapshot_usage( context, cgsnapshot, "delete.start") + snapshots_model_update = None + model_update = None try: utils.require_driver_initialized(self.driver) @@ -2944,23 +2972,26 @@ class VolumeManager(manager.SchedulerDependentManager): # but it is not a requirement for all drivers. cgsnapshot.context = caller_context for snapshot in snapshots: - snapshot['context'] = caller_context - - model_update, snapshots = \ - self.driver.delete_cgsnapshot(context, cgsnapshot) - - if snapshots: - for snapshot in snapshots: - update = {'status': snapshot['status']} + snapshot.context = caller_context - # TODO(thangp): Switch over to use snapshot.update() - # after cgsnapshot-objects bugs are fixed - self.db.snapshot_update(context, snapshot['id'], - update) - if snapshot['status'] in ['error_deleting', 'error'] and \ - model_update['status'] not in \ - ['error_deleting', 'error']: - model_update['status'] = snapshot['status'] + model_update, snapshots_model_update = ( + self.driver.delete_cgsnapshot(context, cgsnapshot, + snapshots)) + + if snapshots_model_update: + for snap_model in snapshots_model_update: + # NOTE(xyang): snapshots is a list of snapshot objects. + # snapshots_model_update should be a list of dicts. + snap = next((item for item in snapshots if + item.id == snap_model['id']), None) + if snap: + snap.status = snap_model['status'] + snap.save() + + if (snap_model['status'] in ['error_deleting', 'error'] and + model_update['status'] not in + ['error_deleting', 'error']): + model_update['status'] = snap_model['status'] if model_update: if model_update['status'] in ['error_deleting', 'error']: @@ -2972,10 +3003,16 @@ class VolumeManager(manager.SchedulerDependentManager): cgsnapshot.update(model_update) cgsnapshot.save() - except Exception: + except exception.CinderException: with excutils.save_and_reraise_exception(): - cgsnapshot.status = 'error_deleting' + cgsnapshot.status = 'error' cgsnapshot.save() + # Update snapshot status to 'error' if driver returns + # None for snapshots_model_update. + if not snapshots_model_update: + for snapshot in snapshots: + snapshot.status = 'error' + snapshot.save() for snapshot in snapshots: # Get reservations @@ -3002,7 +3039,7 @@ class VolumeManager(manager.SchedulerDependentManager): self.db.volume_glance_metadata_delete_by_snapshot(context, snapshot['id']) - # TODO(thangp): Switch over to use snapshot.delete() + # TODO(thangp): Switch over to use snapshot.destroy() # after cgsnapshot-objects bugs are fixed self.db.snapshot_destroy(context, snapshot['id'])