Fix HNAS driver always handling mountable snapshots

HNAS driver always handles snapshots as if mount_snaphot_support
is always True.
The driver always create exports in snapshot_create and tries to
delete it in snapshot_delete. Also, the driver tries to add rules
for exports in snapshot_update_access without checking if the export
exists.

Fixing it by checking the key 'mount_snapshot_support' in shares and
checking if the snapshot has an export before adding or removing
rules.

Change-Id: If25d68d04400f0e9015f6ad6aff845f9c5d47f94
Closes-bug: #1660420
Closes-bug: #1660421
This commit is contained in:
Alyson Rosa 2017-02-01 14:09:32 -02:00 committed by Rodrigo Barbieri
parent 6b4171bff2
commit c4b65df374
2 changed files with 45 additions and 28 deletions

View File

@ -395,12 +395,16 @@ class HitachiHNASDriver(driver.ShareDriver):
LOG.info(_LI("Snapshot %(id)s successfully created."),
{'id': snapshot['id']})
return {
'provider_location': os.path.join('/snapshots', hnas_share_id,
snapshot['id']),
'export_locations': export_locations,
output = {
'provider_location': os.path.join(
'/snapshots', hnas_share_id, snapshot['id'])
}
if export_locations:
output['export_locations'] = export_locations
return output
def delete_snapshot(self, context, snapshot, share_server=None):
"""Deletes snapshot.
@ -417,7 +421,7 @@ class HitachiHNASDriver(driver.ShareDriver):
{'snap_id': snapshot['id'],
'snap_share_id': snapshot['share_id']})
self._delete_snapshot(snapshot['share']['share_proto'],
self._delete_snapshot(snapshot['share'],
hnas_share_id, hnas_snapshot_id)
LOG.info(_LI("Snapshot %(id)s successfully deleted."),
@ -992,14 +996,17 @@ class HitachiHNASDriver(driver.ShareDriver):
self.hnas.update_nfs_access_rule(saved_list,
share_id=hnas_share_id)
self._create_export(hnas_share_id, share_proto,
snapshot_id=snapshot['id'])
export_locations = self._get_export_locations(share_proto,
snapshot['id'],
is_snapshot=True)
export_locations = []
if snapshot['share'].get('mount_snapshot_support'):
self._create_export(hnas_share_id, share_proto,
snapshot_id=snapshot['id'])
export_locations = self._get_export_locations(
share_proto, snapshot['id'], is_snapshot=True)
return export_locations
def _delete_snapshot(self, share_proto, hnas_share_id, snapshot_id):
def _delete_snapshot(self, share, hnas_share_id, snapshot_id):
"""Deletes snapshot.
It receives the hnas_share_id only to join the path for snapshot.
@ -1007,11 +1014,13 @@ class HitachiHNASDriver(driver.ShareDriver):
:param snapshot_id: ID of snapshot.
"""
self._check_fs_mounted()
share_proto = share['share_proto']
if share_proto.lower() == 'nfs':
self.hnas.nfs_export_del(snapshot_id=snapshot_id)
elif share_proto.lower() == 'cifs':
self.hnas.cifs_share_del(snapshot_id)
if share.get('mount_snapshot_support'):
if share_proto.lower() == 'nfs':
self.hnas.nfs_export_del(snapshot_id=snapshot_id)
elif share_proto.lower() == 'cifs':
self.hnas.cifs_share_del(snapshot_id)
path = os.path.join('/snapshots', hnas_share_id, snapshot_id)
self.hnas.tree_delete(path)
@ -1318,8 +1327,7 @@ class HitachiHNASDriver(driver.ShareDriver):
"""
hnas_snapshot_id = self._get_hnas_snapshot_id(snapshot)
self._check_protocol(snapshot['share']['id'],
snapshot['share']['share_proto'])
self._ensure_snapshot(snapshot, hnas_snapshot_id)
access_rules, add_rules, delete_rules = utils.change_rules_to_readonly(
access_rules, add_rules, delete_rules)

View File

@ -494,7 +494,8 @@ class HitachiHNASTestCase(test.TestCase):
share['id'])
self.assertFalse(ssh.HNASSSHBackend.nfs_export_del.called)
@ddt.data(snapshot_nfs, snapshot_cifs)
@ddt.data(snapshot_nfs, snapshot_cifs, snapshot_mount_support_nfs,
snapshot_mount_support_cifs)
def test_create_snapshot(self, snapshot):
hnas_id = snapshot['share_id']
export_locations = [
@ -504,11 +505,12 @@ class HitachiHNASTestCase(test.TestCase):
self._get_export(
snapshot['id'], snapshot['share']['share_proto'],
self._driver.hnas_admin_network_ip, True, is_snapshot=True)]
expected = {
'provider_location': '/snapshots/' + hnas_id + '/' +
snapshot['id'],
'export_locations': export_locations,
}
expected = {'provider_location': '/snapshots/' + hnas_id + '/' +
snapshot['id']}
if snapshot['share'].get('mount_snapshot_support'):
expected['export_locations'] = export_locations
self.mock_object(ssh.HNASSSHBackend, "get_nfs_host_list", mock.Mock(
return_value=['172.24.44.200(rw)']))
@ -583,7 +585,8 @@ class HitachiHNASTestCase(test.TestCase):
ssh.HNASSSHBackend.create_directory.assert_called_once_with(
'/snapshots/' + hnas_id + '/' + snapshot_nfs['id'])
@ddt.data(snapshot_nfs, snapshot_cifs)
@ddt.data(snapshot_nfs, snapshot_cifs,
snapshot_mount_support_nfs, snapshot_mount_support_cifs)
def test_delete_snapshot(self, snapshot):
hnas_share_id = snapshot['share_id']
hnas_snapshot_id = snapshot['id']
@ -603,11 +606,17 @@ class HitachiHNASTestCase(test.TestCase):
ssh.HNASSSHBackend.delete_directory.assert_called_once_with(
'/snapshots/' + hnas_share_id)
if snapshot['share']['share_proto'].lower() == 'nfs':
ssh.HNASSSHBackend.nfs_export_del.assert_called_once_with(
snapshot_id=hnas_snapshot_id)
if snapshot['share'].get('mount_snapshot_support'):
ssh.HNASSSHBackend.nfs_export_del.assert_called_once_with(
snapshot_id=hnas_snapshot_id)
else:
ssh.HNASSSHBackend.nfs_export_del.assert_not_called()
else:
ssh.HNASSSHBackend.cifs_share_del.assert_called_once_with(
hnas_snapshot_id)
if snapshot['share'].get('mount_snapshot_support'):
ssh.HNASSSHBackend.cifs_share_del.assert_called_once_with(
hnas_snapshot_id)
else:
ssh.HNASSSHBackend.cifs_share_del.assert_not_called()
def test_delete_managed_snapshot(self):
hnas_id = manage_snapshot['share_id']