Merge "delete_stack add wait argument"

This commit is contained in:
Jenkins 2016-04-23 13:07:19 +00:00 committed by Gerrit Code Review
commit ae82bf039f
3 changed files with 57 additions and 2 deletions

View File

@ -967,10 +967,11 @@ class OpenStackCloud(object):
marker=marker)
return self.get_stack(name_or_id)
def delete_stack(self, name_or_id):
def delete_stack(self, name_or_id, wait=False):
"""Delete a Heat Stack
:param string name_or_id: Stack name or id.
:param boolean wait: Whether to wait for the delete to finish
:returns: True if delete succeeded, False if the stack was not found.
@ -982,9 +983,33 @@ class OpenStackCloud(object):
self.log.debug("Stack %s not found for deleting" % name_or_id)
return False
if wait:
# find the last event to use as the marker
events = event_utils.get_events(self.heat_client,
name_or_id,
event_args={'sort_dir': 'desc',
'limit': 1})
marker = events[0].id if events else None
with _utils.heat_exceptions("Failed to delete stack {id}".format(
id=name_or_id)):
self.manager.submitTask(_tasks.StackDelete(id=stack['id']))
if wait:
try:
event_utils.poll_for_events(self.heat_client,
stack_name=name_or_id,
action='DELETE',
marker=marker)
except (heat_exceptions.NotFound, heat_exceptions.CommandError):
# heatclient might raise NotFound or CommandError on
# not found during poll_for_events
pass
stack = self.get_stack(name_or_id)
if stack and stack['stack_status'] == 'DELETE_FAILED':
raise OpenStackCloudException(
"Failed to delete stack {id}: {reason}".format(
id=name_or_id, reason=stack['stack_status_reason']))
return True
def get_name(self):

View File

@ -83,7 +83,8 @@ class TestStack(base.TestCase):
self.skipTest('Orchestration service not supported by cloud')
def _cleanup_stack(self):
self.cloud.delete_stack(self.stack_name)
self.cloud.delete_stack(self.stack_name, wait=True)
self.assertIsNone(self.cloud.get_stack(self.stack_name))
def test_stack_validation(self):
test_template = tempfile.NamedTemporaryFile(delete=False)

View File

@ -108,6 +108,35 @@ class TestStack(base.TestCase):
):
self.cloud.delete_stack('stack_name')
@mock.patch.object(event_utils, 'poll_for_events')
@mock.patch.object(shade.OpenStackCloud, 'get_stack')
@mock.patch.object(shade.OpenStackCloud, 'heat_client')
def test_delete_stack_wait(self, mock_heat, mock_get, mock_poll):
stack = {'id': 'stack_id', 'name': 'stack_name'}
mock_get.side_effect = (stack, None)
self.assertTrue(self.cloud.delete_stack('stack_name', wait=True))
mock_heat.stacks.delete.assert_called_once_with(stack['id'])
self.assertEqual(2, mock_get.call_count)
self.assertEqual(1, mock_poll.call_count)
@mock.patch.object(event_utils, 'poll_for_events')
@mock.patch.object(shade.OpenStackCloud, 'get_stack')
@mock.patch.object(shade.OpenStackCloud, 'heat_client')
def test_delete_stack_wait_failed(self, mock_heat, mock_get, mock_poll):
stack = {'id': 'stack_id', 'name': 'stack_name'}
stack_failed = {'id': 'stack_id', 'name': 'stack_name',
'stack_status': 'DELETE_FAILED',
'stack_status_reason': 'ouch'}
mock_get.side_effect = (stack, stack_failed)
with testtools.ExpectedException(
shade.OpenStackCloudException,
"Failed to delete stack stack_name: ouch"
):
self.cloud.delete_stack('stack_name', wait=True)
mock_heat.stacks.delete.assert_called_once_with(stack['id'])
self.assertEqual(2, mock_get.call_count)
self.assertEqual(1, mock_poll.call_count)
@mock.patch.object(template_utils, 'get_template_contents')
@mock.patch.object(shade.OpenStackCloud, 'heat_client')
def test_create_stack(self, mock_heat, mock_template):