Enhance StackResource update for more use cases
Enhance StackResource.update_with_template to accommodate more possible use cases. This will take care of the nested stack update failure by raising an exception in such case, so the the concrete nested stack resource implementations will have a chance to take some actions upon nested stack update failure. blueprint nested-stack-updates Change-Id: Id31ef67e1d7c4928704c6e169bce13f0f7232932
This commit is contained in:
parent
a4a823ac22
commit
112283f135
@ -174,12 +174,15 @@ class InstanceGroup(stack_resource.StackResource):
|
|||||||
When shrinking, the newest instances will be removed.
|
When shrinking, the newest instances will be removed.
|
||||||
"""
|
"""
|
||||||
new_template = self._create_template(new_capacity)
|
new_template = self._create_template(new_capacity)
|
||||||
result = self.update_with_template(new_template, {})
|
try:
|
||||||
|
self.update_with_template(new_template, {})
|
||||||
|
except exception.Error as ex:
|
||||||
|
logger.error('Failed to resize instance group %s. Error: %s' %
|
||||||
|
(self.name, ex))
|
||||||
for resource in self.nested():
|
for resource in self.nested():
|
||||||
if resource.state == ('CREATE', 'FAILED'):
|
if resource.state == ('CREATE', 'FAILED'):
|
||||||
resource.destroy()
|
resource.destroy()
|
||||||
self._lb_reload()
|
self._lb_reload()
|
||||||
return result
|
|
||||||
|
|
||||||
def _lb_reload(self):
|
def _lb_reload(self):
|
||||||
'''
|
'''
|
||||||
|
@ -113,9 +113,25 @@ class StackResource(resource.Resource):
|
|||||||
environment.Environment(user_params),
|
environment.Environment(user_params),
|
||||||
timeout_mins=timeout_mins,
|
timeout_mins=timeout_mins,
|
||||||
disable_rollback=True,
|
disable_rollback=True,
|
||||||
parent_resource=self)
|
parent_resource=self,
|
||||||
|
owner_id=self.stack.id)
|
||||||
stack.validate()
|
stack.validate()
|
||||||
return self._nested.update(stack)
|
|
||||||
|
nested_stack = self.nested()
|
||||||
|
if nested_stack is None:
|
||||||
|
raise exception.Error(_('Cannot update %s, stack not created')
|
||||||
|
% self.name)
|
||||||
|
|
||||||
|
if not hasattr(type(self), 'attributes_schema'):
|
||||||
|
self.attributes = None
|
||||||
|
self._outputs_to_attribs(child_template)
|
||||||
|
|
||||||
|
nested_stack.update(stack)
|
||||||
|
|
||||||
|
if nested_stack.state != (nested_stack.UPDATE,
|
||||||
|
nested_stack.COMPLETE):
|
||||||
|
raise exception.Error("Nested stack update failed: %s" %
|
||||||
|
nested_stack.status_reason)
|
||||||
|
|
||||||
def delete_nested(self):
|
def delete_nested(self):
|
||||||
'''
|
'''
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import mox
|
||||||
|
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
from heat.common import exception
|
from heat.common import exception
|
||||||
from heat.engine import environment
|
from heat.engine import environment
|
||||||
@ -167,6 +170,35 @@ class StackResourceTest(HeatTestCase):
|
|||||||
self.parent_stack.context, self.stack.id)
|
self.parent_stack.context, self.stack.id)
|
||||||
self.assertEqual(saved_stack.owner_id, self.parent_stack.id)
|
self.assertEqual(saved_stack.owner_id, self.parent_stack.id)
|
||||||
|
|
||||||
|
@utils.stack_delete_after
|
||||||
|
def test_update_with_template_state_err(self):
|
||||||
|
"""
|
||||||
|
update_with_template_state_err method should raise error when update
|
||||||
|
task is done but the nested stack is in (UPDATE, FAILED) state.
|
||||||
|
"""
|
||||||
|
create_creator = self.parent_resource.create_with_template(
|
||||||
|
self.simple_template, {})
|
||||||
|
create_creator.run_to_completion()
|
||||||
|
self.stack = self.parent_resource.nested()
|
||||||
|
|
||||||
|
new_templ = self.simple_template.copy()
|
||||||
|
inst_snippet = new_templ["Resources"]["WebServer"].copy()
|
||||||
|
new_templ["Resources"]["WebServer2"] = inst_snippet
|
||||||
|
|
||||||
|
def change_state(stack):
|
||||||
|
self.stack.state_set(parser.Stack.UPDATE, parser.Stack.FAILED, '')
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.stack, 'update')
|
||||||
|
self.stack.update(mox.IgnoreArg()).WithSideEffects(change_state)
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.parent_resource.update_with_template(new_templ, {})
|
||||||
|
except exception.Error as ex:
|
||||||
|
self.assertEqual('Nested stack update failed: ', ex.message)
|
||||||
|
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
@utils.stack_delete_after
|
@utils.stack_delete_after
|
||||||
def test_load_nested_ok(self):
|
def test_load_nested_ok(self):
|
||||||
self.parent_resource.create_with_template(self.templ,
|
self.parent_resource.create_with_template(self.templ,
|
||||||
|
Loading…
Reference in New Issue
Block a user