From 6aca29e05bb0cfe469ed17f4ab9bb9351b2f108a Mon Sep 17 00:00:00 2001 From: Rakesh H S Date: Tue, 2 Sep 2014 20:06:53 +0530 Subject: [PATCH] fixes stack deletion failure, when vol in deleting when an delete operation is requested on a stack, and the volume in stack is already in 'deleting' state, heat fails to delete the stack and goes to DELETE_FAILED state instantly. Instead of going to DELETE_FAILED state instantly, heat needs to safely wait for the volume to complete its deletion process, so that heat can then go ahead and complete stack deletion successfully. Closes-Bug: #1362708 Change-Id: I088eab90bee4bc804abe9e505fd61b17b266def1 --- heat/engine/resources/volume.py | 6 ++++-- heat/tests/test_volume.py | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 69d85b941..790c28ff1 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -160,8 +160,10 @@ class Volume(resource.Resource): if vol.status == 'in-use': raise exception.Error(_('Volume in use')) - - vol.delete() + # if the volume is already in deleting status, + # just wait for the deletion to complete + if vol.status != 'deleting': + vol.delete() while True: yield vol.get() diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index dda747728..bbc4e8275 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -488,6 +488,33 @@ class VolumeTest(BaseVolumeTest): self.m.VerifyAll() + def test_volume_deleting_delete(self): + fv = FakeVolume('creating', 'available') + stack_name = 'test_volume_deleting_stack' + + self._mock_create_volume(fv, stack_name) + + self.cinder_fc.volumes.get('vol-123').AndReturn(fv) + self.m.ReplayAll() + + stack = utils.parse_stack(self.t, stack_name=stack_name) + + rsrc = self.create_volume(self.t, stack, 'DataVolume') + self.assertEqual('available', fv.status) + + # make sure that delete was not called + self.m.StubOutWithMock(fv, 'delete') + + self.m.StubOutWithMock(fv, 'get') + fv.get().AndReturn(None) + fv.get().AndRaise(cinder_exp.NotFound('Not found')) + self.m.ReplayAll() + + fv.status = 'deleting' + scheduler.TaskRunner(rsrc.destroy)() + + self.m.VerifyAll() + def test_volume_update_not_supported(self): stack_name = 'test_volume_stack' fv = FakeVolume('creating', 'available')