Stack updated error if creation fails
template https://github.com/openstack/heat-templates/blob/
67301b6ff45b9f1c220ee0a0ab3aecd3a415032b/cfn/F17/
AutoScalingCeilometer.yaml
can have update error when execute on some resources
which did not even created due to creation failed.
Add check logic in _needs_update to make sure even resource still
stay in init complete state can proceed update process by
raise resource.UpdateReplace.
For nested stack, StackResource should have the same status check
logic in _needs_update method to avoid this error occur(nested()
is None due to resource in failed state after create failed).
Change-Id: I3fa6a61436e79409fe7f28cf66dfdfd9f609b576
Closes-Bug: #1459719
(cherry picked from commit 878473d922
)
This commit is contained in:
parent
721fe7babe
commit
382d038892
|
@ -257,7 +257,7 @@ class RackspaceDnsTest(common.HeatTestCase):
|
|||
ut = rsrc_defn.ResourceDefinition(instance.name,
|
||||
instance.type(),
|
||||
uprops)
|
||||
|
||||
instance.state_set(instance.CREATE, instance.COMPLETE)
|
||||
scheduler.TaskRunner(instance.update, ut)()
|
||||
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||
self.m.VerifyAll()
|
||||
|
@ -316,6 +316,7 @@ class RackspaceDnsTest(common.HeatTestCase):
|
|||
ut = rsrc_defn.ResourceDefinition(instance.name,
|
||||
instance.type(),
|
||||
uprops)
|
||||
instance.state_set(instance.CREATE, instance.COMPLETE)
|
||||
|
||||
scheduler.TaskRunner(instance.update, ut)()
|
||||
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||
|
|
|
@ -701,7 +701,8 @@ class Resource(object):
|
|||
|
||||
def _needs_update(self, after, before, after_props, before_props,
|
||||
prev_resource):
|
||||
if self.status == self.FAILED:
|
||||
if self.status == self.FAILED or \
|
||||
(self.action == self.INIT and self.status == self.COMPLETE):
|
||||
raise UpdateReplace(self)
|
||||
|
||||
if prev_resource is not None:
|
||||
|
|
|
@ -557,6 +557,7 @@ backend servers
|
|||
save it to the db.
|
||||
rely on the cfn-hup to reconfigure HAProxy
|
||||
'''
|
||||
|
||||
new_props = json_snippet.properties(self.properties_schema,
|
||||
self.context)
|
||||
|
||||
|
|
|
@ -79,8 +79,17 @@ class StackResource(resource.Resource):
|
|||
|
||||
def _needs_update(self, after, before, after_props, before_props,
|
||||
prev_resource):
|
||||
# Always issue an update to the nested stack and let the individual
|
||||
# Issue an update to the nested stack if the stack resource
|
||||
# is able to update. If return true, let the individual
|
||||
# resources in it decide if they need updating.
|
||||
|
||||
# FIXME (ricolin): seems currently can not call super here
|
||||
if self.nested() is None and (
|
||||
self.status == self.FAILED
|
||||
or (self.action == self.INIT
|
||||
and self.status == self.COMPLETE)):
|
||||
raise resource.UpdateReplace(self)
|
||||
|
||||
return True
|
||||
|
||||
def nested(self, force_reload=False, show_deleted=False):
|
||||
|
|
|
@ -88,7 +88,8 @@ class LBUtilsTest(common.HeatTestCase):
|
|||
'LB_1': lb1,
|
||||
'LB_2': lb2
|
||||
}
|
||||
|
||||
lb1.action = mock.Mock(return_value=lb1.CREATE)
|
||||
lb2.action = mock.Mock(return_value=lb2.CREATE)
|
||||
lb1.handle_update = mock.Mock()
|
||||
lb2.handle_update = mock.Mock()
|
||||
prop_diff = {'Instances': ['ID1', 'ID2', 'ID3']}
|
||||
|
@ -108,6 +109,8 @@ class LBUtilsTest(common.HeatTestCase):
|
|||
|
||||
lb1 = self.stack['neutron_lb_1']
|
||||
lb2 = self.stack['neutron_lb_2']
|
||||
lb1.action = mock.Mock(return_value=lb1.CREATE)
|
||||
lb2.action = mock.Mock(return_value=lb2.CREATE)
|
||||
lbs = {
|
||||
'LB_1': lb1,
|
||||
'LB_2': lb2
|
||||
|
|
|
@ -307,6 +307,7 @@ class LoadbalancerReloadTest(common.HeatTestCase):
|
|||
|
||||
stack = utils.parse_stack(t, params=inline_templates.as_params)
|
||||
lb = stack['ElasticLoadBalancer']
|
||||
lb.state_set(lb.CREATE, lb.COMPLETE)
|
||||
lb.handle_update = mock.Mock(return_value=None)
|
||||
group = stack['WebServerGroup']
|
||||
group._lb_reload()
|
||||
|
|
|
@ -285,6 +285,7 @@ class ResourceTest(common.HeatTestCase):
|
|||
stored_time = res.updated_time
|
||||
|
||||
utmpl = rsrc_defn.ResourceDefinition('test_resource', 'Foo')
|
||||
res.state_set(res.CREATE, res.COMPLETE)
|
||||
scheduler.TaskRunner(res.update, utmpl)()
|
||||
self.assertIsNotNone(res.updated_time)
|
||||
self.assertNotEqual(res.updated_time, stored_time)
|
||||
|
@ -813,6 +814,18 @@ class ResourceTest(common.HeatTestCase):
|
|||
six.text_type(ex))
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_need_update_in_init_complete_state_for_resource(self):
|
||||
tmpl = rsrc_defn.ResourceDefinition('test_resource',
|
||||
'GenericResourceType',
|
||||
{'Foo': 'abc'})
|
||||
res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)
|
||||
res.update_allowed_properties = ('Foo',)
|
||||
self.assertEqual((res.INIT, res.COMPLETE), res.state)
|
||||
|
||||
prop = {'Foo': 'abc'}
|
||||
self.assertRaises(resource.UpdateReplace,
|
||||
res._needs_update, tmpl, tmpl, prop, prop, res)
|
||||
|
||||
def test_update_fail_missing_req_prop(self):
|
||||
tmpl = rsrc_defn.ResourceDefinition('test_resource',
|
||||
'GenericResourceType',
|
||||
|
|
|
@ -510,11 +510,12 @@ class StackResourceTest(common.HeatTestCase):
|
|||
rpcc.return_value.delete_stack.assert_called_once_with(
|
||||
self.parent_resource.context, mock.ANY)
|
||||
|
||||
def test_need_update_in_failed_state_for_nested_resource(self):
|
||||
def test_need_update_for_nested_resource(self):
|
||||
"""
|
||||
The resource in any state and has nested stack,
|
||||
The resource in Create or Update state and has nested stack,
|
||||
should need update.
|
||||
"""
|
||||
self.parent_resource.action = self.parent_resource.CREATE
|
||||
need_update = self.parent_resource._needs_update(
|
||||
self.parent_resource.t,
|
||||
self.parent_resource.t,
|
||||
|
@ -524,6 +525,38 @@ class StackResourceTest(common.HeatTestCase):
|
|||
|
||||
self.assertEqual(True, need_update)
|
||||
|
||||
def test_need_update_in_failed_state_for_nested_resource(self):
|
||||
"""
|
||||
The resource in failed state and has no nested stack,
|
||||
should need update with UpdateReplace.
|
||||
"""
|
||||
self.parent_resource.state_set(self.parent_resource.INIT,
|
||||
self.parent_resource.FAILED)
|
||||
self.parent_resource._nested = None
|
||||
self.assertRaises(resource.UpdateReplace,
|
||||
self.parent_resource._needs_update,
|
||||
self.parent_resource.t,
|
||||
self.parent_resource.t,
|
||||
self.parent_resource.properties,
|
||||
self.parent_resource.properties,
|
||||
self.parent_resource)
|
||||
|
||||
def test_need_update_in_init_complete_state_for_nested_resource(self):
|
||||
"""
|
||||
The resource in failed state and has no nested stack,
|
||||
should need update with UpdateReplace.
|
||||
"""
|
||||
self.parent_resource.state_set(self.parent_resource.INIT,
|
||||
self.parent_resource.COMPLETE)
|
||||
self.parent_resource._nested = None
|
||||
self.assertRaises(resource.UpdateReplace,
|
||||
self.parent_resource._needs_update,
|
||||
self.parent_resource.t,
|
||||
self.parent_resource.t,
|
||||
self.parent_resource.properties,
|
||||
self.parent_resource.properties,
|
||||
self.parent_resource)
|
||||
|
||||
|
||||
class StackResourceLimitTest(common.HeatTestCase):
|
||||
scenarios = [
|
||||
|
|
Loading…
Reference in New Issue