From 601a45d2c9c8d812c841bd47d3abf4a206467fd9 Mon Sep 17 00:00:00 2001 From: "Michal Jastrzebski (inc0)" Date: Wed, 27 May 2015 03:07:44 +0200 Subject: [PATCH] Unlimited option max_resources_per_stack Since biggest issue for memory problems is nested stack max resources validation, this patch creates option to remove limit which skips whole validation whatsoever. Change-Id: I7c851fcad2d4a41b2f9df42244862b04304812b0 Partial-Bug: #1455589 --- heat/common/config.py | 3 ++- heat/engine/resources/stack_resource.py | 2 ++ heat/engine/service.py | 8 ++++++-- heat/tests/engine/test_stack_create.py | 11 +++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/heat/common/config.py b/heat/common/config.py index a2b1e37b5e..dc136081e3 100644 --- a/heat/common/config.py +++ b/heat/common/config.py @@ -115,7 +115,8 @@ engine_opts = [ ' delegated to heat when creating a stack.')), cfg.IntOpt('max_resources_per_stack', default=1000, - help=_('Maximum resources allowed per top-level stack.')), + help=_('Maximum resources allowed per top-level stack. ' + '-1 stands for unlimited.')), cfg.IntOpt('max_stacks_per_tenant', default=100, help=_('Maximum number of stacks any one tenant may have' diff --git a/heat/engine/resources/stack_resource.py b/heat/engine/resources/stack_resource.py index 53912ee5d0..381603133b 100644 --- a/heat/engine/resources/stack_resource.py +++ b/heat/engine/resources/stack_resource.py @@ -224,6 +224,8 @@ class StackResource(resource.Resource): return parsed_template def _validate_nested_resources(self, templ): + if cfg.CONF.max_resources_per_stack == -1: + return root_stack_id = self.stack.root_stack_id() total_resources = (len(templ[templ.RESOURCES]) + self.stack.total_resources(root_stack_id)) diff --git a/heat/engine/service.py b/heat/engine/service.py index f07f51cd3f..8e03454a3b 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -570,8 +570,11 @@ class EngineService(service.Service): " Please delete some stacks.") % tenant_limit raise exception.RequestLimitExceeded(message=message) + max_resources = cfg.CONF.max_resources_per_stack + if max_resources == -1: + return num_resources = len(parsed_template[parsed_template.RESOURCES]) - if num_resources > cfg.CONF.max_resources_per_stack: + if num_resources > max_resources: message = exception.StackResourceLimitExceeded.msg_fmt raise exception.RequestLimitExceeded(message=message) @@ -753,7 +756,8 @@ class EngineService(service.Service): current_stack.env, args.get(rpc_api.PARAM_CLEAR_PARAMETERS, [])) tmpl = templatem.Template(template, files=files, env=env) - if len(tmpl[tmpl.RESOURCES]) > cfg.CONF.max_resources_per_stack: + max_resources = cfg.CONF.max_resources_per_stack + if max_resources != -1 and len(tmpl[tmpl.RESOURCES]) > max_resources: raise exception.RequestLimitExceeded( message=exception.StackResourceLimitExceeded.msg_fmt) stack_name = current_stack.name diff --git a/heat/tests/engine/test_stack_create.py b/heat/tests/engine/test_stack_create.py index a89f3fc755..80f7110290 100644 --- a/heat/tests/engine/test_stack_create.py +++ b/heat/tests/engine/test_stack_create.py @@ -21,6 +21,7 @@ from heat.engine.clients.os import nova from heat.engine import environment from heat.engine import properties from heat.engine import resource as res +from heat.engine.resources.aws.ec2 import instance as instances from heat.engine import service from heat.engine import stack from heat.engine import template as templatem @@ -339,3 +340,13 @@ class StackCreateTest(common.HeatTestCase): ctx, stk) self.assertEqual('Missing required credential: X-Auth-Key', six.text_type(ex)) + + @mock.patch.object(instances.Instance, 'validate') + @mock.patch.object(stack.Stack, 'total_resources') + def test_stack_create_max_unlimited(self, total_res_mock, validate_mock): + total_res_mock.return_value = 9999 + validate_mock.return_value = None + cfg.CONF.set_override('max_resources_per_stack', -1) + stack_name = 'service_create_test_max_unlimited' + stack = tools.get_stack(stack_name, self.ctx) + self.man.create_stack(self.ctx, stack_name, stack.t.t, {}, None, {})