NetApp SolidFire: Fix force_detach

Fixes force_detach for SolidFire driver.

Change-Id: Iaf8a3f0bed5af053d5ea7796d84d5d77f1608458
Closes-Bug: #1788458
This commit is contained in:
Miriam Yumi 2018-08-22 13:23:05 -03:00 committed by Miriam Yumi Peixoto
parent 11f90d9573
commit 62bdcbf7ab
3 changed files with 69 additions and 16 deletions

View File

@ -1275,6 +1275,45 @@ class SolidFireVolumeTestCase(test.TestCase):
sfv._sf_terminate_connection(testvol, connector, False) sfv._sf_terminate_connection(testvol, connector, False)
rem_vag.assert_called_with(vol_id, vag_id) rem_vag.assert_called_with(vol_id, vag_id)
def test_sf_term_conn_without_connector(self):
# Verify we correctly force the deletion of a volume.
mod_conf = self.configuration
mod_conf.sf_enable_vag = True
sfv = solidfire.SolidFireDriver(configuration=mod_conf)
testvol = {'project_id': 'testprjid',
'name': 'testvol',
'size': 1,
'id': 'a720b3c0-d1f0-11e1-9b23-0800200c9a66',
'volume_type_id': None,
'provider_location': '10.10.7.1:3260 iqn.2010-01.com.'
'solidfire:87hg.uuid-2cc06226-cc'
'74-4cb7-bd55-14aed659a0cc.4060 0',
'provider_auth': 'CHAP stack-1-a60e2611875f40199931f2'
'c76370d66b 2FE0CQ8J196R',
'provider_geometry': '4096 4096',
'created_at': timeutils.utcnow(),
'provider_id': "1 1 1",
'multiattach': False
}
provider_id = testvol['provider_id']
vol_id = int(provider_id.split()[0])
vag_id = 1
vags = [{'attributes': {},
'deletedVolumes': [],
'initiators': ['iqn.2012-07.org.fake:01'],
'name': 'fakeiqn',
'volumeAccessGroupID': vag_id,
'volumes': [1, 2],
'virtualNetworkIDs': []}]
with mock.patch.object(sfv,
'_get_vags_by_volume',
return_value=vags), \
mock.patch.object(sfv,
'_remove_volume_from_vags') as rem_vags:
sfv._sf_terminate_connection(testvol, None, False)
rem_vags.assert_called_with(vol_id)
def test_safe_create_vag_simple(self): def test_safe_create_vag_simple(self):
# Test the sunny day call straight into _create_vag. # Test the sunny day call straight into _create_vag.
sfv = solidfire.SolidFireDriver(configuration=self.configuration) sfv = solidfire.SolidFireDriver(configuration=self.configuration)
@ -1516,7 +1555,7 @@ class SolidFireVolumeTestCase(test.TestCase):
'volumes': [vol_id, 43]}] 'volumes': [vol_id, 43]}]
with mock.patch.object(sfv, with mock.patch.object(sfv,
'_base_get_vags', '_get_vags_by_volume',
return_value=vags), \ return_value=vags), \
mock.patch.object(sfv, mock.patch.object(sfv,
'_remove_volume_from_vag') as rem_vol: '_remove_volume_from_vag') as rem_vol:

View File

@ -1201,6 +1201,13 @@ class SolidFireDriver(san.SanISCSIDriver):
matching_vags = [vag for vag in vags if vag['name'] == vag_name] matching_vags = [vag for vag in vags if vag['name'] == vag_name]
return matching_vags return matching_vags
def _get_vags_by_volume(self, vol_id):
params = {"volumeID": vol_id}
vags = self._issue_api_request(
'GetVolumeStats',
params)['result']['volumeStats']['volumeAccessGroups']
return vags
def _add_initiator_to_vag(self, iqn, vag_id): def _add_initiator_to_vag(self, iqn, vag_id):
# Added a vag_id return as there is a chance that we might have to # Added a vag_id return as there is a chance that we might have to
# create a new VAG if our target VAG is deleted underneath us. # create a new VAG if our target VAG is deleted underneath us.
@ -1258,9 +1265,8 @@ class SolidFireDriver(san.SanISCSIDriver):
def _remove_volume_from_vags(self, vol_id): def _remove_volume_from_vags(self, vol_id):
# Due to all sorts of uncertainty around multiattach, on volume # Due to all sorts of uncertainty around multiattach, on volume
# deletion we make a best attempt at removing the vol_id from VAGs. # deletion we make a best attempt at removing the vol_id from VAGs.
vags = self._base_get_vags() vags = self._get_vags_by_volume(vol_id)
targets = [v for v in vags if vol_id in v['volumes']] for vag in vags:
for vag in targets:
self._remove_volume_from_vag(vol_id, vag['volumeAccessGroupID']) self._remove_volume_from_vag(vol_id, vag['volumeAccessGroupID'])
def _remove_vag(self, vag_id): def _remove_vag(self, vag_id):
@ -2337,21 +2343,26 @@ class SolidFireISCSI(iscsi_driver.SanISCSITarget):
If the VAG is empty then the VAG is also removed. If the VAG is empty then the VAG is also removed.
""" """
if self.configuration.sf_enable_vag: if self.configuration.sf_enable_vag:
iqn = properties['initiator']
vag = self._get_vags_by_name(iqn)
provider_id = volume['provider_id'] provider_id = volume['provider_id']
vol_id = int(provider_id.split()[0]) vol_id = int(provider_id.split()[0])
if vag and not volume['multiattach']: if properties:
# Multiattach causes problems with removing volumes from VAGs. iqn = properties['initiator']
# Compromise solution for now is to remove multiattach volumes vag = self._get_vags_by_name(iqn)
# from VAGs during volume deletion.
vag = vag[0] if vag and not volume['multiattach']:
vag_id = vag['volumeAccessGroupID'] # Multiattach causes problems with removing volumes from
if [vol_id] == vag['volumes']: # VAGs.
self._remove_vag(vag_id) # Compromise solution for now is to remove multiattach
elif vol_id in vag['volumes']: # volumes from VAGs during volume deletion.
self._remove_volume_from_vag(vol_id, vag_id) vag = vag[0]
vag_id = vag['volumeAccessGroupID']
if [vol_id] == vag['volumes']:
self._remove_vag(vag_id)
elif vol_id in vag['volumes']:
self._remove_volume_from_vag(vol_id, vag_id)
else:
self._remove_volume_from_vags(vol_id)
return super(SolidFireISCSI, self).terminate_connection(volume, return super(SolidFireISCSI, self).terminate_connection(volume,
properties, properties,

View File

@ -0,0 +1,3 @@
---
fixes:
- Fixes force_detach behavior for volumes in NetApp SolidFire driver.