NetApp Solidfire: Fix retype and name exception on migration

While performing retype or migrate on a volume the name exception
occurs due to the check on all backends including the origin.
The retype status exception occurs because the only accepted state
is available, but retype changes the status to retyping.

This change just assures to check the name on the target backend
and also adds retyping as a valid status for migrate condition.

Change-Id: Ic09d65a0a6ecbb529dc0e4b041650ead449e1273
Closes-Bug: 1942090
Closes-Bug: 1932964
This commit is contained in:
Fabio Oliveira 2021-08-30 11:52:41 -03:00
parent a8da1fa83b
commit 853f082884
3 changed files with 88 additions and 9 deletions

View File

@ -3728,6 +3728,32 @@ class SolidFireVolumeTestCase(test.TestCase):
sfv.migrate_volume, ctx, vol, host)
mock_do_intercluster_volume_migration.assert_not_called()
@mock.patch.object(solidfire.SolidFireDriver,
'_do_intercluster_volume_migration')
def test_migrate_volume_retyping_status(
self, mock_do_intercluster_volume_migration):
ctx = context.get_admin_context()
type_fields = {'id': fakes.get_fake_uuid()}
src_vol_type = fake_volume.fake_volume_type_obj(ctx, **type_fields)
vol_fields = {
'id': fakes.get_fake_uuid(),
'volume_type': src_vol_type,
'host': 'fakeHost@fakeBackend#fakePool',
'status': 'retyping'
}
vol = fake_volume.fake_volume_obj(ctx, **vol_fields)
vol.volume_type = src_vol_type
host = {'host': 'fakeHost@fakeBackend#fakePool'}
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
result = sfv.migrate_volume(ctx, vol, host)
mock_do_intercluster_volume_migration.assert_not_called()
self.assertEqual((True, {}), result)
@mock.patch.object(solidfire.SolidFireDriver,
'_do_intercluster_volume_migration')
def test_migrate_volume_same_host_and_backend(
@ -4192,3 +4218,40 @@ class SolidFireVolumeTestCase(test.TestCase):
call('RemoveVolumePair', src_params, '8.0'),
call('DeleteVolume', src_params),
call('PurgeDeletedVolume', src_params)])
@data(True, False)
@mock.patch.object(solidfire.SolidFireDriver, '_create_cluster_reference')
@mock.patch.object(solidfire.SolidFireDriver, '_set_cluster_pairs')
@mock.patch.object(solidfire.SolidFireDriver, '_update_cluster_status')
@mock.patch.object(solidfire.SolidFireDriver, '_issue_api_request')
def test_list_volumes_by_name(self, has_endpoint, mock_issue_api_request,
mock_update_cluster_status,
mock_set_cluster_pairs,
mock_create_cluster_reference):
fake_sf_volume_name = 'fake-vol-name'
vol_fields = {
'id': fakes.get_fake_uuid(),
'name': fake_sf_volume_name
}
vol = fake_volume.fake_volume_obj(
context.get_admin_context(), **vol_fields)
fake_endpoint = None
volumes_list = [vol]
if has_endpoint:
fake_endpoint = self.fake_primary_cluster["endpoint"]
volumes_list = []
mock_issue_api_request.return_value = {
'result': {'volumes': volumes_list}}
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
result = (
sfv._list_volumes_by_name(fake_sf_volume_name,
endpoint=fake_endpoint))
mock_issue_api_request.assert_called_once_with(
'ListVolumes', {'volumeName': fake_sf_volume_name},
version='8.0', endpoint=fake_endpoint)
self.assertEqual(result, volumes_list)

View File

@ -276,9 +276,13 @@ class SolidFireDriver(san.SanISCSIDriver):
by adding xNotPrimary to the retryable exception list
2.2.2 - Fix bug #1896112 SolidFire Driver creates duplicate volume
when API response is lost
2.2.3 - Fix bug #1942090 SolidFire retype fails due to volume status
as retyping.
Fix bug #1932964 SolidFire duplicate volume name exception
on migration and replication.
"""
VERSION = '2.2.2'
VERSION = '2.2.3'
SUPPORTS_ACTIVE_ACTIVE = True
@ -1015,10 +1019,10 @@ class SolidFireDriver(san.SanISCSIDriver):
params['attributes'] = attributes
return self._issue_api_request('ModifyVolume', params)
def _list_volumes_by_name(self, sf_volume_name):
def _list_volumes_by_name(self, sf_volume_name, endpoint=None):
params = {'volumeName': sf_volume_name}
return self._issue_api_request(
'ListVolumes', params, version='8.0')['result']['volumes']
return self._issue_api_request('ListVolumes', params, version='8.0',
endpoint=endpoint)['result']['volumes']
def _wait_volume_is_active(self, sf_volume_name):
@ -1046,9 +1050,10 @@ class SolidFireDriver(san.SanISCSIDriver):
raise SolidFireAPIException(msg)
def _do_volume_create(self, sf_account, params, endpoint=None):
sf_volume_name = params['name']
volumes_found = self._list_volumes_by_name(sf_volume_name)
volumes_found = self._list_volumes_by_name(sf_volume_name,
endpoint=endpoint)
if volumes_found:
raise SolidFireDuplicateVolumeNames(vol_name=sf_volume_name)
@ -2522,9 +2527,10 @@ class SolidFireDriver(san.SanISCSIDriver):
LOG.info("Migrate volume %(vol_id)s to %(host)s.",
{"vol_id": volume.id, "host": host["host"]})
if volume.status != fields.VolumeStatus.AVAILABLE:
msg = _("Volume status must be 'available' to execute "
"storage assisted migration.")
if (volume.status != fields.VolumeStatus.AVAILABLE and
volume.status != fields.VolumeStatus.RETYPING):
msg = _("Volume status must be 'available' or 'retyping' to "
"execute storage assisted migration.")
LOG.error(msg)
raise exception.InvalidVolume(reason=msg)

View File

@ -0,0 +1,10 @@
---
fixes:
- |
NetApp SolidFire driver `Bug #1932964
<https://bugs.launchpad.net/cinder/+bug/1932964>`_:
Fixed a name exception that occurs on any volume migration.
- |
NetApp SolidFire driver `Bug #1942090
<https://bugs.launchpad.net/cinder/+bug/1942090>`_:
Fixed a status exception that occurs on volume retype with migration.