]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Enhance StackResource update for more use cases
authorLiang Chen <cbjchen@cn.ibm.com>
Thu, 22 Aug 2013 05:41:52 +0000 (13:41 +0800)
committerLiang Chen <cbjchen@cn.ibm.com>
Sat, 24 Aug 2013 03:14:44 +0000 (11:14 +0800)
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

heat/engine/resources/autoscaling.py
heat/engine/stack_resource.py
heat/tests/test_stack_resource.py

index 79ad56ae3579a8fdecb4ff884a8b0258b2cb2c61..2eaf409085c4e8054deb6bb347b2e8deeff486af 100644 (file)
@@ -174,12 +174,15 @@ class InstanceGroup(stack_resource.StackResource):
         When shrinking, the newest instances will be removed.
         """
         new_template = self._create_template(new_capacity)
-        result = self.update_with_template(new_template, {})
-        for resource in self.nested():
-            if resource.state == ('CREATE', 'FAILED'):
-                resource.destroy()
+        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():
+                if resource.state == ('CREATE', 'FAILED'):
+                    resource.destroy()
         self._lb_reload()
-        return result
 
     def _lb_reload(self):
         '''
index 6ff3339baa15253f7a03b1b28577ce355239b5db..b4ff15ad40727da1824a38b13c6330c72b2679d1 100644 (file)
@@ -113,9 +113,25 @@ class StackResource(resource.Resource):
                              environment.Environment(user_params),
                              timeout_mins=timeout_mins,
                              disable_rollback=True,
-                             parent_resource=self)
+                             parent_resource=self,
+                             owner_id=self.stack.id)
         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):
         '''
index 834652636a1af1b2e071811e89b51c405da6e492..5e3bf2c9aabbdc5f19ce1968373476c8cd6feb2e 100644 (file)
@@ -12,6 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+
+import mox
+
 from heat.common import template_format
 from heat.common import exception
 from heat.engine import environment
@@ -167,6 +170,35 @@ class StackResourceTest(HeatTestCase):
             self.parent_stack.context, self.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
     def test_load_nested_ok(self):
         self.parent_resource.create_with_template(self.templ,