diff --git a/heat/engine/parser.py b/heat/engine/parser.py index b65782eb9b3..a0b40711cd4 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -516,6 +516,7 @@ def restart_resource(self, resource_name): for res in deps: if not failed: try: + res.state_reset() scheduler.TaskRunner(res.create)() except exception.ResourceFailure as ex: logger.exception('create') diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 72735348c4b..59f5ef05012 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -622,6 +622,13 @@ def _resolve_attribute(self, name): # By default, no attributes resolve pass + def state_reset(self): + """ + Reset state to (INIT, COMPLETE) + """ + self.action = self.INIT + self.status = self.COMPLETE + def state_set(self, action, status, reason="state changed"): if action not in self.ACTIONS: raise ValueError("Invalid action %s" % action) diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index d5ac74c0b8b..048b465a512 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -272,6 +272,18 @@ def test_create_fail_prop_typo(self): self.assertRaises(exception.ResourceFailure, create) self.assertEqual((res.CREATE, res.FAILED), res.state) + def test_create_resource_after_destroy(self): + tmpl = {'Type': 'GenericResourceType'} + rname = 'test_res_id_none' + res = generic_rsrc.ResourceWithProps(rname, tmpl, self.stack) + res.id = 'test_res_id' + (res.action, res.status) = (res.INIT, res.DELETE) + self.assertRaises(exception.ResourceFailure, res.create) + res.destroy() + res.state_reset() + scheduler.TaskRunner(res.create)() + self.assertEqual((res.CREATE, res.COMPLETE), res.state) + def test_update_ok(self): tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)