Fix race condition in deleting volumes

We check at the top of the delete_volume call for existence of the
volume, but then time passes and it's possible the volume does not, in
fact, exist. Catch the 404 and move on with our life.

Change-Id: I0873a238e519b08c09c2a17dba331401f7fc4bfb
This commit is contained in:
Monty Taylor 2016-03-22 08:25:43 -05:00 committed by David Shrewsbury
parent 8a7c609352
commit 0870ffe949
2 changed files with 27 additions and 2 deletions

View File

@ -24,6 +24,7 @@ from dogpile import cache
import requestsexceptions
import cinderclient.client
import cinderclient.exceptions as cinder_exceptions
import glanceclient
import glanceclient.exc
import heatclient.client
@ -2429,8 +2430,14 @@ class OpenStackCloud(object):
return False
with _utils.shade_exceptions("Error in deleting volume"):
self.manager.submitTask(
_tasks.VolumeDelete(volume=volume['id']))
try:
self.manager.submitTask(
_tasks.VolumeDelete(volume=volume['id']))
except cinder_exceptions.NotFound:
self.log.debug(
"Volume {id} not found when deleting. Ignoring.".format(
id=volume['id']))
return False
self.list_volumes.invalidate(self)
if wait:

View File

@ -13,6 +13,7 @@
# under the License.
import cinderclient.exceptions as cinder_exc
import mock
import testtools
@ -188,3 +189,20 @@ class TestVolume(base.TestCase):
"Error in detaching volume %s" % errored_volume['id']
):
self.cloud.detach_volume(server, volume)
@mock.patch.object(shade.OpenStackCloud, 'get_volume')
@mock.patch.object(shade.OpenStackCloud, 'cinder_client')
def test_delete_volume_deletes(self, mock_cinder, mock_get):
volume = dict(id='volume001', status='attached')
mock_get.side_effect = iter([volume, None])
self.assertTrue(self.cloud.delete_volume(volume['id']))
@mock.patch.object(shade.OpenStackCloud, 'get_volume')
@mock.patch.object(shade.OpenStackCloud, 'cinder_client')
def test_delete_volume_gone_away(self, mock_cinder, mock_get):
volume = dict(id='volume001', status='attached')
mock_get.side_effect = iter([volume])
mock_cinder.volumes.delete.side_effect = cinder_exc.NotFound('N/A')
self.assertFalse(self.cloud.delete_volume(volume['id']))