From e47e14f0b9ab04e155241a8c27b91413f7c4c885 Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Mon, 11 Feb 2013 14:44:45 +1100 Subject: [PATCH] Add update support to InstanceGroup Change-Id: Ie4d554f7440d06d408f71ff1b223d34d50b655bc --- heat/engine/resources/autoscaling.py | 38 +++++++++++++++++++++++++--- heat/tests/test_instance_group.py | 33 +++++++++++++++++++++++- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/heat/engine/resources/autoscaling.py b/heat/engine/resources/autoscaling.py index 858f1efd..2630ce05 100644 --- a/heat/engine/resources/autoscaling.py +++ b/heat/engine/resources/autoscaling.py @@ -71,6 +71,8 @@ class InstanceGroup(resource.Resource): 'Schema': {'Type': 'Map', 'Schema': tags_schema}} } + update_allowed_keys = ('Properties',) + update_allowed_properties = ('Size',) def __init__(self, name, json_snippet, stack): super(InstanceGroup, self).__init__(name, json_snippet, stack) @@ -80,10 +82,38 @@ class InstanceGroup(resource.Resource): self.resize(int(self.properties['Size']), raise_on_error=True) def handle_update(self, json_snippet): - # TODO(asalkeld) if the only thing that has changed is the size then - # call resize. Maybe have an attribute of the properties that can mark - # it "update-able" so each resource doesn't have to figure this out. - return self.UPDATE_REPLACE + try: + tmpl_diff = self.update_template_diff(json_snippet) + except NotImplementedError: + logger.error("Could not update %s, invalid key" % self.name) + return self.UPDATE_REPLACE + + try: + prop_diff = self.update_template_diff_properties(json_snippet) + except NotImplementedError: + logger.error("Could not update %s, invalid Property" % self.name) + return self.UPDATE_REPLACE + + # If Properties has changed, update self.properties, so we + # get the new values during any subsequent adjustment + if prop_diff: + self.properties = Properties(self.properties_schema, + json_snippet.get('Properties', {}), + self.stack.resolve_runtime_data, + self.name) + + # Get the current capacity, we may need to adjust if + # Size has changed + if 'Size' in prop_diff: + inst_list = [] + if self.resource_id is not None: + inst_list = sorted(self.resource_id.split(',')) + + if len(inst_list) != int(self.properties['Size']): + self.resize(int(self.properties['Size']), + raise_on_error=True) + + return self.UPDATE_COMPLETE def _make_instance(self, name): diff --git a/heat/tests/test_instance_group.py b/heat/tests/test_instance_group.py index 2e2befa2..92347d41 100644 --- a/heat/tests/test_instance_group.py +++ b/heat/tests/test_instance_group.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. - +import copy import os import unittest @@ -91,6 +91,7 @@ class InstanceGroupTest(unittest.TestCase): resource.handle_update({})) resource.delete() + self.m.VerifyAll() def test_missing_image(self): @@ -110,3 +111,33 @@ class InstanceGroupTest(unittest.TestCase): self.assertEqual(asc.InstanceGroup.CREATE_FAILED, resource.state) self.m.VerifyAll() + + def test_upate_size(self): + t = self.load_template() + properties = t['Resources']['JobServerGroup']['Properties'] + properties['Size'] = '2' + stack = self.parse_stack(t) + + self._stub_create(2) + self.m.ReplayAll() + resource = self.create_instance_group(t, stack, 'JobServerGroup') + self.assertEqual('JobServerGroup-0,JobServerGroup-1', + resource.resource_id) + + self.m.VerifyAll() + self.m.UnsetStubs() + + # Increase min size to 5 + self._stub_create(3) + self.m.ReplayAll() + + update_snippet = copy.deepcopy(resource.parsed_template()) + update_snippet['Properties']['Size'] = '5' + self.assertEqual(asc.AutoScalingGroup.UPDATE_COMPLETE, + resource.handle_update(update_snippet)) + assert_str = ','.join(['JobServerGroup-%s' % x for x in range(5)]) + self.assertEqual(assert_str, + resource.resource_id) + + resource.delete() + self.m.VerifyAll() -- 2.45.2