Merge "ZFSSA handle non-existent snapshot" into stable/queens
This commit is contained in:
commit
3769a6915a
|
@ -441,7 +441,10 @@ class TestZFSSAISCSIDriver(test.TestCase):
|
|||
}
|
||||
}
|
||||
cache = lun2del['origin']
|
||||
self.drv.zfssa.num_clones.return_value = 0
|
||||
self.drv.zfssa.get_lun_snapshot.return_value = {
|
||||
'name': self.test_snap['name'],
|
||||
'numclones': 0
|
||||
}
|
||||
self.drv._check_origin(lun2del, 'volname')
|
||||
self.drv.zfssa.delete_lun.assert_called_once_with(
|
||||
lcfg.zfssa_pool,
|
||||
|
@ -449,7 +452,10 @@ class TestZFSSAISCSIDriver(test.TestCase):
|
|||
cache['share'])
|
||||
|
||||
def test_create_delete_snapshot(self):
|
||||
self.drv.zfssa.num_clones.return_value = 0
|
||||
self.drv.zfssa.get_lun_snapshot.return_value = {
|
||||
'name': self.test_snap['name'],
|
||||
'numclones': 0
|
||||
}
|
||||
lcfg = self.configuration
|
||||
self.drv.create_snapshot(self.test_snap)
|
||||
self.drv.zfssa.create_snapshot.assert_called_once_with(
|
||||
|
@ -464,6 +470,19 @@ class TestZFSSAISCSIDriver(test.TestCase):
|
|||
self.test_snap['volume_name'],
|
||||
self.test_snap['name'])
|
||||
|
||||
def test_delete_nonexistent_snapshot(self):
|
||||
self.drv.zfssa.get_lun_snapshot.side_effect = \
|
||||
exception.SnapshotNotFound(snapshot_id=self.test_snap['name'])
|
||||
self.drv.delete_snapshot(self.test_snap)
|
||||
self.drv.zfssa.delete_snapshot.assert_not_called()
|
||||
|
||||
def test_delete_snapshot_backend_fail(self):
|
||||
self.drv.zfssa.get_lun_snapshot.side_effect = \
|
||||
exception.VolumeBackendAPIException(data='fakemsg')
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.drv.delete_snapshot,
|
||||
self.test_snap)
|
||||
|
||||
def test_create_volume_from_snapshot(self):
|
||||
lcfg = self.configuration
|
||||
self.drv.zfssa.get_lun.return_value = self.test_vol
|
||||
|
|
|
@ -375,11 +375,17 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
|||
"""Deletes a snapshot."""
|
||||
LOG.debug('zfssa.delete_snapshot: snapshot=%s', snapshot['name'])
|
||||
lcfg = self.configuration
|
||||
numclones = self.zfssa.num_clones(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
snapshot['volume_name'],
|
||||
snapshot['name'])
|
||||
if numclones > 0:
|
||||
try:
|
||||
snap2del = self.zfssa.get_lun_snapshot(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
snapshot['volume_name'],
|
||||
snapshot['name'])
|
||||
except exception.SnapshotNotFound:
|
||||
# If snapshot creation failed, it may exist in the database
|
||||
# but not on the ZFSSA. Exit silently in this case.
|
||||
return
|
||||
|
||||
if snap2del['numclones'] > 0:
|
||||
LOG.error('Snapshot %s: has clones', snapshot['name'])
|
||||
raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
|
||||
|
||||
|
@ -1048,10 +1054,11 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
|||
if (cache['snapshot'].startswith('image-') and
|
||||
cache['share'].startswith('os-cache-vol')):
|
||||
try:
|
||||
numclones = self.zfssa.num_clones(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_cache_project,
|
||||
cache['share'],
|
||||
cache['snapshot'])
|
||||
snap = self.zfssa.get_lun_snapshot(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_cache_project,
|
||||
cache['share'],
|
||||
cache['snapshot'])
|
||||
numclones = snap['numclones']
|
||||
except Exception:
|
||||
LOG.debug('Cache volume is already deleted.')
|
||||
return
|
||||
|
|
|
@ -826,7 +826,15 @@ class ZFSSAApi(object):
|
|||
project + '/luns/' + lun + '/snapshots/' + snapshot)
|
||||
|
||||
ret = self.rclient.get(svc)
|
||||
if ret.status != restclient.Status.OK:
|
||||
if ret.status == restclient.Status.NOT_FOUND:
|
||||
LOG.warning('Snapshot %(snapshot)s of volume %(volume)s not '
|
||||
'found in project %(project)s, pool %(pool)s.',
|
||||
{'snapshot': snapshot,
|
||||
'project': project,
|
||||
'pool': pool,
|
||||
'volume': lun})
|
||||
raise exception.SnapshotNotFound(snapshot_id=snapshot)
|
||||
elif ret.status != restclient.Status.OK:
|
||||
exception_msg = ('Error Getting '
|
||||
'Snapshot: %(snapshot)s of '
|
||||
'Volume: %(lun)s in '
|
||||
|
@ -841,7 +849,7 @@ class ZFSSAApi(object):
|
|||
'ret.status': ret.status,
|
||||
'ret.data': ret.data})
|
||||
LOG.error(exception_msg)
|
||||
raise exception.SnapshotNotFound(snapshot_id=snapshot)
|
||||
raise exception.VolumeBackendAPIException(data=exception_msg)
|
||||
|
||||
val = json.loads(ret.data)['snapshot']
|
||||
ret = {
|
||||
|
@ -1022,32 +1030,6 @@ class ZFSSAApi(object):
|
|||
LOG.error(exception_msg)
|
||||
raise exception.VolumeBackendAPIException(data=exception_msg)
|
||||
|
||||
def num_clones(self, pool, project, lun, snapshot):
|
||||
"""Checks whether snapshot has clones or not."""
|
||||
svc = '/api/storage/v1/pools/' + pool + '/projects/' + \
|
||||
project + '/luns/' + lun + '/snapshots/' + snapshot
|
||||
|
||||
ret = self.rclient.get(svc)
|
||||
if ret.status != restclient.Status.OK:
|
||||
exception_msg = (_('Error Getting '
|
||||
'Snapshot: %(snapshot)s on '
|
||||
'Volume: %(lun)s to '
|
||||
'Pool: %(pool)s '
|
||||
'Project: %(project)s '
|
||||
'Return code: %(ret.status)d '
|
||||
'Message: %(ret.data)s.')
|
||||
% {'snapshot': snapshot,
|
||||
'lun': lun,
|
||||
'pool': pool,
|
||||
'project': project,
|
||||
'ret.status': ret.status,
|
||||
'ret.data': ret.data})
|
||||
LOG.error(exception_msg)
|
||||
raise exception.VolumeBackendAPIException(data=exception_msg)
|
||||
|
||||
val = json.loads(ret.data)
|
||||
return val['snapshot']['numclones']
|
||||
|
||||
def get_initiator_initiatorgroup(self, initiator):
|
||||
"""Returns the initiator group of the initiator."""
|
||||
groups = []
|
||||
|
|
Loading…
Reference in New Issue