Ceph: Fix delete backup with non-existent pool
If a non-existent pool is specified, Ceph will raise ObjectNotFound error when deleting a backup. Cinder should catch this error and delete the db record directly. Change-Id: I41177b9b1f63c6bd2296a5eff70f0058ce3393e5 Closes-bug: #1686897
This commit is contained in:
parent
ae3ce62ae4
commit
675089f86d
|
@ -1202,6 +1202,7 @@ class CephBackupDriver(driver.BackupDriver):
|
||||||
LOG.debug('Delete started for backup=%s', backup.id)
|
LOG.debug('Delete started for backup=%s', backup.id)
|
||||||
|
|
||||||
delete_failed = False
|
delete_failed = False
|
||||||
|
has_pool = True
|
||||||
try:
|
try:
|
||||||
self._try_delete_base_image(backup)
|
self._try_delete_base_image(backup)
|
||||||
except self.rbd.ImageNotFound:
|
except self.rbd.ImageNotFound:
|
||||||
|
@ -1210,9 +1211,15 @@ class CephBackupDriver(driver.BackupDriver):
|
||||||
"not found. Deleting backup metadata.",
|
"not found. Deleting backup metadata.",
|
||||||
{'backup': backup.id, 'volume': backup.volume_id})
|
{'backup': backup.id, 'volume': backup.volume_id})
|
||||||
delete_failed = True
|
delete_failed = True
|
||||||
|
except self.rados.ObjectNotFound:
|
||||||
|
LOG.warning("The pool %(pool)s doesn't exist.",
|
||||||
|
{'pool': backup.container})
|
||||||
|
delete_failed = True
|
||||||
|
has_pool = False
|
||||||
|
|
||||||
with rbd_driver.RADOSClient(self, backup.container) as client:
|
if has_pool:
|
||||||
VolumeMetadataBackup(client, backup.id).remove_if_exists()
|
with rbd_driver.RADOSClient(self, backup.container) as client:
|
||||||
|
VolumeMetadataBackup(client, backup.id).remove_if_exists()
|
||||||
|
|
||||||
if delete_failed:
|
if delete_failed:
|
||||||
LOG.info("Delete of backup '%(backup)s' for volume '%(volume)s' "
|
LOG.info("Delete of backup '%(backup)s' for volume '%(volume)s' "
|
||||||
|
|
|
@ -91,6 +91,7 @@ def common_mocks(f):
|
||||||
inst.mock_rbd = mock_rbd
|
inst.mock_rbd = mock_rbd
|
||||||
inst.mock_rbd.ImageBusy = MockImageBusyException
|
inst.mock_rbd.ImageBusy = MockImageBusyException
|
||||||
inst.mock_rbd.ImageNotFound = MockImageNotFoundException
|
inst.mock_rbd.ImageNotFound = MockImageNotFoundException
|
||||||
|
inst.mock_rados.ObjectNotFound = MockObjectNotFoundException
|
||||||
|
|
||||||
inst.service.rbd = inst.mock_rbd
|
inst.service.rbd = inst.mock_rbd
|
||||||
inst.service.rados = inst.mock_rados
|
inst.service.rados = inst.mock_rados
|
||||||
|
@ -828,6 +829,20 @@ class BackupCephTestCase(test.TestCase):
|
||||||
self.service.delete(self.backup)
|
self.service.delete(self.backup)
|
||||||
self.assertEqual([MockImageNotFoundException], RAISED_EXCEPTIONS)
|
self.assertEqual([MockImageNotFoundException], RAISED_EXCEPTIONS)
|
||||||
|
|
||||||
|
@common_mocks
|
||||||
|
@mock.patch('cinder.backup.drivers.ceph.VolumeMetadataBackup', spec=True)
|
||||||
|
def test_delete_pool_not_found(self, mock_meta_backup):
|
||||||
|
with mock.patch.object(
|
||||||
|
self.service, '_try_delete_base_image') as mock_del_base:
|
||||||
|
mock_del_base.side_effect = self.mock_rados.ObjectNotFound
|
||||||
|
# ObjectNotFound exception is caught so that db entry can be
|
||||||
|
# cleared
|
||||||
|
self.service.delete(self.backup)
|
||||||
|
self.assertEqual([MockObjectNotFoundException],
|
||||||
|
RAISED_EXCEPTIONS)
|
||||||
|
mock_del_base.assert_called_once_with(self.backup)
|
||||||
|
mock_meta_backup.return_value.remove_if_exists.assert_not_called()
|
||||||
|
|
||||||
@common_mocks
|
@common_mocks
|
||||||
def test_diff_restore_allowed_with_image_not_exists(self):
|
def test_diff_restore_allowed_with_image_not_exists(self):
|
||||||
"""Test diff restore not allowed when backup not diff-format."""
|
"""Test diff restore not allowed when backup not diff-format."""
|
||||||
|
|
Loading…
Reference in New Issue