]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Update nested stacks in parallel
authorZane Bitter <zbitter@redhat.com>
Wed, 4 Sep 2013 08:44:39 +0000 (10:44 +0200)
committerZane Bitter <zbitter@redhat.com>
Wed, 4 Sep 2013 08:44:43 +0000 (10:44 +0200)
This parallelises updates for AWS::CloudFormation::Stack resources, but not
for autoscaling groups. Other types of nested stacks (the old LoadBalancer
and DBInstance resources, and provider templates) have not yet implemented
stack updates.

Change-Id: I86e1d5289487b34712c248bc5e68e62cc4651ec6

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

index 7bdfbd045dc1ad367cfb971ba915a1907a3acbb2..12f791270fb49e71bc500cd061243b39e2b5061c 100644 (file)
@@ -214,7 +214,9 @@ class InstanceGroup(stack_resource.StackResource):
         """
         new_template = self._create_template(new_capacity)
         try:
-            self.update_with_template(new_template, {})
+            updater = self.update_with_template(new_template, {})
+            updater.run_to_completion()
+            self.check_update_complete(updater)
         finally:
             # Reload the LB in any case, so it's only pointing at healthy
             # nodes.
index dc031ab6818b23664b8cd6d20ae7b7f807b16bc1..3879935bd3691d74daf97ab41775172dd532739c 100644 (file)
@@ -73,9 +73,9 @@ class NestedStack(stack_resource.StackResource):
         template_data = urlfetch.get(self.properties[PROP_TEMPLATE_URL])
         template = template_format.parse(template_data)
 
-        self.update_with_template(template,
-                                  self.properties[PROP_PARAMETERS],
-                                  self.properties[PROP_TIMEOUT_MINS])
+        return self.update_with_template(template,
+                                         self.properties[PROP_PARAMETERS],
+                                         self.properties[PROP_TIMEOUT_MINS])
 
 
 def resource_mapping():
index 6743ff2bc55093d66ed55dd3523f7409fb33e4d8..b95088c0d73eefa3f3efaac2c104a023e1385ea9 100644 (file)
@@ -136,12 +136,23 @@ class StackResource(resource.Resource):
             self.attributes = None
             self._outputs_to_attribs(child_template)
 
-        nested_stack.update(stack)
+        updater = scheduler.TaskRunner(nested_stack.update_task, stack)
+        updater.start()
+        return updater
 
+    def check_update_complete(self, updater):
+        if updater is None:
+            return True
+
+        if not updater.step():
+            return False
+
+        nested_stack = self.nested()
         if nested_stack.state != (nested_stack.UPDATE,
                                   nested_stack.COMPLETE):
             raise exception.Error("Nested stack update failed: %s" %
                                   nested_stack.status_reason)
+        return True
 
     def delete_nested(self):
         '''
index 574d406feb95e9ac0a0d90bdeb2446ad281b391a..cd8b13bb7ff4aa97e005d3188e8d60fdf5bff3e1 100644 (file)
@@ -122,7 +122,9 @@ Outputs:
         new_res['Properties']['TemplateURL'] = (
             'https://server.test/new.template')
         prop_diff = {'TemplateURL': 'https://server.test/new.template'}
-        rsrc.handle_update(new_res, {}, prop_diff)
+        updater = rsrc.handle_update(new_res, {}, prop_diff)
+        updater.run_to_completion()
+        self.assertEqual(True, rsrc.check_update_complete(updater))
 
         # Expect the physical resource name staying the same after update,
         # so that the nested was actually updated instead of replaced.
index 5e3bf2c9aabbdc5f19ce1968373476c8cd6feb2e..bf3dff3b16bc826d923d3e8101d4792250f9c8c5 100644 (file)
@@ -159,8 +159,11 @@ class StackResourceTest(HeatTestCase):
         new_templ = self.simple_template.copy()
         inst_snippet = new_templ["Resources"]["WebServer"].copy()
         new_templ["Resources"]["WebServer2"] = inst_snippet
-        update_result = self.parent_resource.update_with_template(
+        updater = self.parent_resource.update_with_template(
             new_templ, {})
+        updater.run_to_completion()
+        self.assertEqual(True,
+                         self.parent_resource.check_update_complete(updater))
         self.assertEqual(self.stack.state, ('UPDATE', 'COMPLETE'))
         self.assertEqual(set(self.stack.resources.keys()),
                          set(["WebServer", "WebServer2"]))
@@ -185,17 +188,22 @@ class StackResourceTest(HeatTestCase):
         inst_snippet = new_templ["Resources"]["WebServer"].copy()
         new_templ["Resources"]["WebServer2"] = inst_snippet
 
-        def change_state(stack):
+        def update_task():
+            yield
             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.StubOutWithMock(self.stack, 'update_task')
+        self.stack.update_task(mox.IgnoreArg()).AndReturn(update_task())
         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)
+        updater = self.parent_resource.update_with_template(new_templ, {})
+        updater.run_to_completion()
+        self.assertEqual((self.stack.UPDATE, self.stack.FAILED),
+                         self.stack.state)
+        ex = self.assertRaises(exception.Error,
+                               self.parent_resource.check_update_complete,
+                               updater)
+        self.assertEqual('Nested stack update failed: ', str(ex))
 
         self.m.VerifyAll()