"Invalid action %s" % action)
return
+ stack_status = self.COMPLETE
+ reason = 'Stack %s completed successfully' % action.lower()
self.state_set(action, self.IN_PROGRESS, 'Stack %s started' % action)
- failures = []
-
backup_stack = self._backup_stack(False)
if backup_stack is not None:
backup_stack.delete()
if backup_stack.status != backup_stack.COMPLETE:
errs = backup_stack.status_reason
- failures.append('Error deleting backup resources: %s' % errs)
+ failure = 'Error deleting backup resources: %s' % errs
+ self.state_set(action, self.FAILED,
+ 'Failed to %s : %s' % (action, failure))
+ return
- for res in reversed(self):
- try:
- res.destroy()
- except exception.ResourceFailure as ex:
- logger.error('Failed to delete %s error: %s' % (str(res),
- str(ex)))
- failures.append(str(res))
+ action_task = scheduler.DependencyTaskGroup(self.dependencies,
+ resource.Resource.destroy,
+ reverse=True)
+ try:
+ scheduler.TaskRunner(action_task)(timeout=self.timeout_secs())
+ except exception.ResourceFailure as ex:
+ stack_status = self.FAILED
+ reason = 'Resource %s failed: %s' % (action.lower(), str(ex))
+ except scheduler.Timeout:
+ stack_status = self.FAILED
+ reason = '%s timed out' % action.title()
- if failures:
- self.state_set(action, self.FAILED,
- 'Failed to %s : %s' % (action, ', '.join(failures)))
- else:
- self.state_set(action, self.COMPLETE, '%s completed' % action)
+ self.state_set(action, stack_status, reason)
+ if stack_status != self.FAILED:
db_api.stack_delete(self.context, self.id)
self.id = None
for res in reversed(deps):
try:
- res.destroy()
+ scheduler.TaskRunner(res.destroy)()
except exception.ResourceFailure as ex:
failed = True
logger.error('delete: %s' % str(ex))
from heat.db import api as db_api
from heat.common import identifier
from heat.common import short_id
+from heat.engine import scheduler
from heat.engine import resources
from heat.engine import timestamp
# import class to avoid name collisions and ugly aliasing
self.state_set(action, self.IN_PROGRESS)
deletion_policy = self.t.get('DeletionPolicy', 'Delete')
+ handle_data = None
if deletion_policy == 'Delete':
if callable(getattr(self, 'handle_delete', None)):
- self.handle_delete()
+ handle_data = self.handle_delete()
+ yield
elif deletion_policy == 'Snapshot':
if callable(getattr(self, 'handle_snapshot_delete', None)):
- self.handle_snapshot_delete(initial_state)
+ handle_data = self.handle_snapshot_delete(initial_state)
+ yield
+
+ if (deletion_policy != 'Retain' and
+ callable(getattr(self, 'check_delete_complete', None))):
+ while not self.check_delete_complete(handle_data):
+ yield
+
except Exception as ex:
logger.exception('Delete %s', str(self))
failure = exception.ResourceFailure(ex, self, self.action)
else:
self.state_set(action, self.COMPLETE)
+ @scheduler.wrappertask
def destroy(self):
'''
Delete the resource and remove it from the database.
'''
- self.delete()
+ yield self.delete()
if self.id is None:
return
scheduler.TaskRunner(rsrc.update, snippet)()
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_mem_alarm_high_update_replace(self):
updater = scheduler.TaskRunner(rsrc.update, snippet)
self.assertRaises(resource.UpdateReplace, updater)
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_suspend_resume(self):
self.assertEqual(wr.state, watchrule.WatchRule.NODATA)
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
rsrc.FnGetAtt, 'Foo')
finally:
- rsrc.destroy()
+ scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
# TODO(sbaker), figure out why this is an empty string
#self.assertEqual('', association.FnGetRefId())
- association.delete()
- rsrc.delete()
+ scheduler.TaskRunner(association.delete)()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
rsrc.FnGetAtt, 'Foo')
finally:
- rsrc.destroy()
+ scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
rsrc = self.create_eip(t, stack, 'the_eip')
association = self.create_association(t, stack, 'IPAssoc')
- association.delete()
- rsrc.delete()
+ scheduler.TaskRunner(association.delete)()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
get().AndRaise(instances.clients.novaclient.exceptions.NotFound(404))
mox.Replay(get)
- instance.delete()
+ scheduler.TaskRunner(instance.delete)()
self.assertTrue(instance.resource_id is None)
self.assertEqual(instance.state, (instance.DELETE, instance.COMPLETE))
self.m.VerifyAll()
scheduler.TaskRunner._sleep(mox.IsA(int)).WithSideEffects(check_empty)
scheduler.TaskRunner._sleep(mox.IsA(int)).WithSideEffects(post_success)
- scheduler.TaskRunner._sleep(mox.IsA(int)).AndReturn(None)
+ scheduler.TaskRunner._sleep(mox.IsA(int)).MultipleTimes().AndReturn(
+ None)
self.m.ReplayAll()
self.stack.create()
ref_id = rsrc.FnGetRefId()
self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
self.assertEqual(False, rsrc.FnGetAtt('enable_dhcp'))
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'
})
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_gateway_router(self):
'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
})
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
fip.FnGetAtt('id'))
self.assertRaises(resource.UpdateReplace,
fip.handle_update, {}, {}, {})
- self.assertEqual(fip.delete(), None)
+ scheduler.TaskRunner(fip.delete)()
fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
- self.assertEqual(fip.delete(), None)
+ scheduler.TaskRunner(fip.delete)()
self.m.VerifyAll()
self.assertRaises(resource.UpdateReplace,
fipa.handle_update, {}, {}, {})
- self.assertEqual(fipa.delete(), None)
- self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
- self.assertEqual(fip.delete(), None)
+ scheduler.TaskRunner(fipa.delete)()
+ scheduler.TaskRunner(p.delete)()
+ scheduler.TaskRunner(fip.delete)()
fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
- self.assertEqual(fipa.delete(), None)
+ scheduler.TaskRunner(fipa.delete)()
self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
- self.assertEqual(fip.delete(), None)
+ scheduler.TaskRunner(fip.delete)()
self.m.VerifyAll()
get().AndRaise(novaclient.exceptions.NotFound(404))
mox.Replay(get)
- cs.delete()
+ scheduler.TaskRunner(cs.delete)()
self.assertTrue(cs.resource_id is None)
self.assertEqual(cs.state, (cs.DELETE, cs.COMPLETE))
self.m.VerifyAll()
res.id = 'test_res_id'
(res.action, res.status) = (res.INIT, res.DELETE)
self.assertRaises(exception.ResourceFailure, res.create)
- res.destroy()
+ scheduler.TaskRunner(res.destroy)()
res.state_reset()
scheduler.TaskRunner(res.create)()
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_public_read(self):
properties['AccessControl'] = 'PublicRead'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3Bucket')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_public_read_write(self):
properties['AccessControl'] = 'PublicReadWrite'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3Bucket')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_authenticated_read(self):
properties['AccessControl'] = 'AuthenticatedRead'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3Bucket')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_website(self):
t = template_format.parse(swift_template)
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3BucketWebsite')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_delete_exception(self):
t = template_format.parse(swift_template)
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3Bucket')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
bucket['DeletionPolicy'] = 'Retain'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'S3Bucket')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
from heat.common import template_format
from heat.engine import parser
from heat.engine import resource
+from heat.engine import scheduler
from heat.tests.common import HeatTestCase
from heat.tests.fakes import FakeKeystoneClient
from heat.tests.v1_1 import fakes
self.assertResourceState(sg, utils.PhysName('test_stack', 'the_sg'))
- self.assertEqual(None, sg.delete())
+ scheduler.TaskRunner(sg.delete)()
sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again')
sg.resource_id = 2
self.assertResourceState(sg, 'aaaa')
- self.assertEqual(None, sg.delete())
+ scheduler.TaskRunner(sg.delete)()
sg.state_set(sg.CREATE, sg.COMPLETE, 'to delete again')
sg.resource_id = 'aaaa'
get().AndRaise(servers.clients.novaclient.exceptions.NotFound(404))
mox.Replay(get)
- server.delete()
+ scheduler.TaskRunner(server.delete)()
self.assertTrue(server.resource_id is None)
self.assertEqual(server.state, (server.DELETE, server.COMPLETE))
self.m.VerifyAll()
server.state_set(server.CREATE, server.COMPLETE, 'to delete again')
- server.delete()
+ scheduler.TaskRunner(server.delete)()
self.assertEqual(server.state, (server.DELETE, server.COMPLETE))
self.m.VerifyAll()
from heat.common import template_format
from heat.engine.resources import instance as instances
from heat.engine import parser
+from heat.engine import scheduler
from heat.openstack.common import uuidutils
from heat.tests.common import HeatTestCase
from heat.tests import utils
self.assertNotEqual(encrypted_key, "fake secret")
decrypted_key = cs.my_secret
self.assertEqual(decrypted_key, "fake secret")
- cs.destroy()
+ scheduler.TaskRunner(cs.destroy)()
def test_resource_data_delete(self):
stack = self._setup_test_stack('stack', UUID1)[1]
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_public_read(self):
properties['X-Container-Read'] = '.r:*'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'SwiftContainer')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_public_read_write(self):
properties['X-Container-Write'] = '.r:*'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'SwiftContainer')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_website(self):
t = template_format.parse(swift_template)
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'SwiftContainerWebsite')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_delete_exception(self):
t = template_format.parse(swift_template)
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'SwiftContainer')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
container['DeletionPolicy'] = 'Retain'
stack = utils.parse_stack(t)
rsrc = self.create_resource(t, stack, 'SwiftContainer')
- rsrc.delete()
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
self.assertEqual(None, rsrc.handle_resume())
rsrc.resource_id = None
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
rsrc.resource_id = self.fc.access
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
self.assertRaises(exception.InvalidTemplateAttribute,
rsrc.FnGetAtt, 'Foo')
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
def test_access_key_deleted(self):
self.fc.delete_ec2_keypair(self.fc.user_id,
rsrc.resource_id).AndRaise(NotFound('Gone'))
self.m.ReplayAll()
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
self.assertRaises(exception.ResourceFailure, create)
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
- self.assertEqual(None, rsrc.delete())
+ scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
rsrc.handle_update, {}, {}, {})
fv.status = 'in-use'
- self.assertRaises(exception.ResourceFailure, rsrc.destroy)
+ self.assertRaises(exception.ResourceFailure,
+ scheduler.TaskRunner(rsrc.destroy))
fv.status = 'available'
- self.assertEqual(rsrc.destroy(), None)
+ scheduler.TaskRunner(rsrc.destroy)()
# Test when volume already deleted
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE)
- self.assertEqual(rsrc.destroy(), None)
+ scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
scheduler.TaskRunner(stack.create)()
self.assertEqual(rsrc.state, (rsrc.CREATE, rsrc.COMPLETE))
- self.assertEqual(stack.delete(), None)
+ scheduler.TaskRunner(stack.delete)()
self.m.VerifyAll()
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
scheduler.TaskRunner(stack['DataVolume'].create)()
rsrc = self.create_attachment(t, stack, 'MountPoint')
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
self.assertEqual(fv.status, 'available')
rsrc = self.create_attachment(t, stack, 'MountPoint')
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
rsrc = self.create_volume(t, stack, 'DataVolume')
- self.assertEqual(rsrc.destroy(), None)
+ scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
rsrc = self.create_volume(t, stack, 'DataVolume')
- self.assertRaises(exception.ResourceFailure, rsrc.destroy)
+ self.assertRaises(exception.ResourceFailure,
+ scheduler.TaskRunner(rsrc.destroy))
self.m.VerifyAll()
create = scheduler.TaskRunner(rsrc.create)
self.assertRaises(exception.ResourceFailure, create)
- self.assertEqual(rsrc.destroy(), None)
+ scheduler.TaskRunner(rsrc.destroy)()
self.m.VerifyAll()
self.assertRaises(resource.UpdateReplace, rsrc.handle_update,
{}, {}, {})
- self.assertEqual(rsrc.delete(), None)
+ scheduler.TaskRunner(rsrc.delete)()
self.m.VerifyAll()
from heat.engine import parser
from heat.engine import clients
from heat.engine import resource
+from heat.engine import scheduler
from heat.tests.common import HeatTestCase
from heat.tests import fakes
from heat.tests import utils
self.assertRaises(resource.UpdateReplace,
vpc.handle_update, {}, {}, {})
- self.assertEqual(None, vpc.delete())
+ scheduler.TaskRunner(vpc.delete)()
self.m.VerifyAll()
self.assertEqual('moon', subnet.FnGetAtt('AvailabilityZone'))
- self.assertEqual(None, subnet.delete())
+ scheduler.TaskRunner(subnet.delete)()
subnet.state_set(subnet.CREATE, subnet.COMPLETE, 'to delete again')
- self.assertEqual(None, subnet.delete())
- self.assertEqual(None, stack['the_vpc'].delete())
+ scheduler.TaskRunner(subnet.delete)()
+ scheduler.TaskRunner(stack['the_vpc'].delete)()
self.m.VerifyAll()
rsrc.handle_update, {}, {}, {})
finally:
- stack.delete()
+ scheduler.TaskRunner(stack.delete)()
self.m.VerifyAll()
self.mock_show_subnet()
self.mock_show_security_group(group='INVALID-NO-REF')
self.mock_delete_subnet()
+ neutronclient.Client.delete_port(None).AndReturn(None)
self.mock_delete_network()
self.m.ReplayAll()
reason = rsrc.status_reason
self.assertTrue(reason.startswith('InvalidTemplateAttribute:'))
finally:
- stack.delete()
+ scheduler.TaskRunner(stack.delete)()
self.m.VerifyAll()
resource.UpdateReplace,
association.handle_update, {}, {}, {})
- association.delete()
- route_table.delete()
+ scheduler.TaskRunner(association.delete)()
+ scheduler.TaskRunner(route_table.delete)()
stack.delete()
self.m.VerifyAll()
# Avoid the stack create exercising the timeout code at the same time
self.m.StubOutWithMock(self.stack, 'timeout_secs')
- self.stack.timeout_secs().AndReturn(None)
+ self.stack.timeout_secs().MultipleTimes().AndReturn(None)
self.m.StubOutWithMock(scheduler, 'wallclock')