From: Alon Marx Date: Wed, 20 Jan 2016 20:14:14 +0000 (+0200) Subject: Remove a vol in error state from a CG X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=80620b1fea79a24f4b22fdfb9213e2aec69ef826;p=openstack-build%2Fcinder-build.git Remove a vol in error state from a CG Before calling update_consistencygroup, a validation is done if volumes are in valid states for action. Divide the states allowed for adding and removing volumes from a CG, and allow volume removal in states error and error_deleting. Also added missing verification in manager update_consistencygroup in case state has changed from cinder-api to cinder-volume. Change-Id: I6f5fa8e9af67e17ab49e7f3423d4469640df790c Closes-Bug: #1519377 --- diff --git a/cinder/consistencygroup/api.py b/cinder/consistencygroup/api.py index c10a1a0b4..40a7861e9 100644 --- a/cinder/consistencygroup/api.py +++ b/cinder/consistencygroup/api.py @@ -43,8 +43,14 @@ CONF = cfg.CONF LOG = logging.getLogger(__name__) CGQUOTAS = quota.CGQUOTAS -VALID_REMOVE_VOL_FROM_CG_STATUS = (c_fields.ConsistencyGroupStatus.AVAILABLE, - c_fields.ConsistencyGroupStatus.IN_USE) +VALID_REMOVE_VOL_FROM_CG_STATUS = ( + 'available', + 'in-use', + 'error', + 'error_deleting') +VALID_ADD_VOL_TO_CG_STATUS = ( + 'available', + 'in-use') def wrap_check_policy(func): @@ -648,7 +654,7 @@ class API(base.Base): 'volume_type': add_vol_type_id}) raise exception.InvalidVolume(reason=msg) if (add_vol_ref['status'] not in - VALID_REMOVE_VOL_FROM_CG_STATUS): + VALID_ADD_VOL_TO_CG_STATUS): msg = (_("Cannot add volume %(volume_id)s to consistency " "group %(group_id)s because volume is in an " "invalid state: %(status)s. Valid states are: " @@ -656,7 +662,7 @@ class API(base.Base): {'volume_id': add_vol_ref['id'], 'group_id': group.id, 'status': add_vol_ref['status'], - 'valid': VALID_REMOVE_VOL_FROM_CG_STATUS}) + 'valid': VALID_ADD_VOL_TO_CG_STATUS}) raise exception.InvalidVolume(reason=msg) # group.host and add_vol_ref['host'] are in this format: diff --git a/cinder/tests/unit/api/contrib/test_consistencygroups.py b/cinder/tests/unit/api/contrib/test_consistencygroups.py index 658d851ab..ecb5a2a17 100644 --- a/cinder/tests/unit/api/contrib/test_consistencygroups.py +++ b/cinder/tests/unit/api/contrib/test_consistencygroups.py @@ -668,7 +668,13 @@ class ConsistencyGroupsAPITestCase(test.TestCase): remove_volume_id2 = utils.create_volume( self.ctxt, volume_type_id=volume_type_id, - consistencygroup_id=consistencygroup.id)['id'] + consistencygroup_id=consistencygroup.id, + status='error')['id'] + remove_volume_id3 = utils.create_volume( + self.ctxt, + volume_type_id=volume_type_id, + consistencygroup_id=consistencygroup.id, + status='error_deleting')['id'] self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE, consistencygroup.status) @@ -678,6 +684,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): cg_vol_ids = [cg_vol['id'] for cg_vol in cg_volumes] self.assertIn(remove_volume_id, cg_vol_ids) self.assertIn(remove_volume_id2, cg_vol_ids) + self.assertIn(remove_volume_id3, cg_vol_ids) add_volume_id = utils.create_volume( self.ctxt, @@ -692,7 +699,8 @@ class ConsistencyGroupsAPITestCase(test.TestCase): name = 'newcg' description = 'New Consistency Group Description' add_volumes = add_volume_id + "," + add_volume_id2 - remove_volumes = remove_volume_id + "," + remove_volume_id2 + remove_volumes = ','.join( + [remove_volume_id, remove_volume_id2, remove_volume_id3]) body = {"consistencygroup": {"name": name, "description": description, "add_volumes": add_volumes, diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index 91c903161..6eac458d7 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -78,7 +78,14 @@ LOG = logging.getLogger(__name__) QUOTAS = quota.QUOTAS CGQUOTAS = quota.CGQUOTAS -VALID_REMOVE_VOL_FROM_CG_STATUS = ('available', 'in-use',) +VALID_REMOVE_VOL_FROM_CG_STATUS = ( + 'available', + 'in-use', + 'error', + 'error_deleting') +VALID_ADD_VOL_TO_CG_STATUS = ( + 'available', + 'in-use') VALID_CREATE_CG_SRC_SNAP_STATUS = ('available',) VALID_CREATE_CG_SRC_CG_STATUS = ('available',) @@ -2805,14 +2812,14 @@ class VolumeManager(manager.SchedulerDependentManager): resource={'type': 'consistency_group', 'id': group.id}) raise - if add_vol_ref['status'] not in ['in-use', 'available']: + if add_vol_ref['status'] not in VALID_ADD_VOL_TO_CG_STATUS: msg = (_("Cannot add volume %(volume_id)s to consistency " "group %(group_id)s because volume is in an invalid " "state: %(status)s. Valid states are: %(valid)s.") % {'volume_id': add_vol_ref['id'], 'group_id': group.id, 'status': add_vol_ref['status'], - 'valid': VALID_REMOVE_VOL_FROM_CG_STATUS}) + 'valid': VALID_ADD_VOL_TO_CG_STATUS}) raise exception.InvalidVolume(reason=msg) # self.host is 'host@backend' # volume_ref['host'] is 'host@backend#pool' @@ -2834,6 +2841,15 @@ class VolumeManager(manager.SchedulerDependentManager): resource={'type': 'consistency_group', 'id': group.id}) raise + if remove_vol_ref['status'] not in VALID_REMOVE_VOL_FROM_CG_STATUS: + msg = (_("Cannot remove volume %(volume_id)s from consistency " + "group %(group_id)s because volume is in an invalid " + "state: %(status)s. Valid states are: %(valid)s.") % + {'volume_id': remove_vol_ref['id'], + 'group_id': group.id, + 'status': remove_vol_ref['status'], + 'valid': VALID_REMOVE_VOL_FROM_CG_STATUS}) + raise exception.InvalidVolume(reason=msg) remove_volumes_ref.append(remove_vol_ref) self._notify_about_consistencygroup_usage( diff --git a/releasenotes/notes/remove-vol-in-error-from-cg-1ed0fde04ab2b5be.yaml b/releasenotes/notes/remove-vol-in-error-from-cg-1ed0fde04ab2b5be.yaml new file mode 100644 index 000000000..82efff690 --- /dev/null +++ b/releasenotes/notes/remove-vol-in-error-from-cg-1ed0fde04ab2b5be.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - Previously the only way to remove volumes in error + states from a consistency-group was to delete the + consistency group and create it again. Now it is + possible to remove volumes in error and error_deleting + states.