Merge ~freyes/ubuntu/+source/heat:stable/xena into ~ubuntu-openstack-dev/ubuntu/+source/heat:stable/xena

Proposed by Felipe Reyes
Status: Merged
Merge reported by: Corey Bryant
Merged at revision: 45af92db98c1334c7bcaad1dda8d0486aa5a1deb
Proposed branch: ~freyes/ubuntu/+source/heat:stable/xena
Merge into: ~ubuntu-openstack-dev/ubuntu/+source/heat:stable/xena
Diff against target: 378 lines (+134/-33)
12 files modified
AUTHORS (+1/-0)
ChangeLog (+9/-0)
PKG-INFO (+1/-1)
debian/changelog (+6/-2)
devstack/lib/heat (+10/-1)
heat/engine/resources/openstack/heat/resource_group.py (+12/-6)
heat/engine/resources/openstack/nova/server_group.py (+25/-18)
heat/tests/openstack/nova/test_server_group.py (+13/-3)
heat_integrationtests/functional/test_resource_group.py (+54/-0)
openstack_heat.egg-info/PKG-INFO (+1/-1)
openstack_heat.egg-info/pbr.json (+1/-1)
tox.ini (+1/-0)
Reviewer Review Type Date Requested Status
Corey Bryant Pending
Review via email: mp+416206@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/AUTHORS b/AUTHORS
index 4f34a6b..f8705d9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -49,6 +49,7 @@ Atsushi Sasaki <atsaki01@gmail.com>
49Attila Fazekas <afazekas@redhat.com>49Attila Fazekas <afazekas@redhat.com>
50AvnishPal <avnish.pal@nectechnologies.in>50AvnishPal <avnish.pal@nectechnologies.in>
51BK Box <bk@theboxes.org>51BK Box <bk@theboxes.org>
52Balazs Gibizer <balazs.gibizer@est.tech>
52Bartosz Górski <bartosz.gorski@ntti3.com>53Bartosz Górski <bartosz.gorski@ntti3.com>
53Ben Nemec <bnemec@redhat.com>54Ben Nemec <bnemec@redhat.com>
54Ben Nemec <openstack@nemebean.com>55Ben Nemec <openstack@nemebean.com>
diff --git a/ChangeLog b/ChangeLog
index 3720f19..a35becd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,15 @@
1CHANGES1CHANGES
2=======2=======
33
417.0.1
5------
6
7* Provide install\_command to pip install with upper-constraints
8* Fix timeout calc of nested resource groups
9* Reproduce bug story/2009237
10* Fallback to upstream for Fedora image
11* Fix ServerGroup create
12
417.0.01317.0.0
5------14------
615
diff --git a/PKG-INFO b/PKG-INFO
index 7ef1230..315b8c6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
1Metadata-Version: 1.21Metadata-Version: 1.2
2Name: openstack-heat2Name: openstack-heat
3Version: 17.0.03Version: 17.0.1
4Summary: OpenStack Orchestration4Summary: OpenStack Orchestration
5Home-page: https://docs.openstack.org/heat/latest/5Home-page: https://docs.openstack.org/heat/latest/
6Author: OpenStack6Author: OpenStack
diff --git a/debian/changelog b/debian/changelog
index 41503e0..f83520d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,12 @@
1heat (1:17.0.0-0ubuntu1.1) UNRELEASED; urgency=medium1heat (1:17.0.1-0ubuntu1) UNRELEASED; urgency=medium
22
3 [ Corey Bryant ]
3 * d/gbp.conf: Create stable/xena branch.4 * d/gbp.conf: Create stable/xena branch.
45
5 -- Corey Bryant <corey.bryant@canonical.com> Fri, 15 Oct 2021 14:53:00 -04006 [ Felipe Reyes ]
7 * New stable point release for OpenStack Xena (LP: #1962582).
8
9 -- Felipe Reyes <felipe.reyes@canonical.com> Tue, 01 Mar 2022 14:51:07 +0000
610
7heat (1:17.0.0-0ubuntu1) impish; urgency=medium11heat (1:17.0.0-0ubuntu1) impish; urgency=medium
812
diff --git a/devstack/lib/heat b/devstack/lib/heat
index 5993d7d..5f5f172 100644
--- a/devstack/lib/heat
+++ b/devstack/lib/heat
@@ -471,10 +471,19 @@ function configure_tempest_for_heat {
471 source $TOP_DIR/openrc admin admin471 source $TOP_DIR/openrc admin admin
472 iniset $TEMPEST_CONFIG heat_plugin admin_username $OS_USERNAME472 iniset $TEMPEST_CONFIG heat_plugin admin_username $OS_USERNAME
473 iniset $TEMPEST_CONFIG heat_plugin admin_password $OS_PASSWORD473 iniset $TEMPEST_CONFIG heat_plugin admin_password $OS_PASSWORD
474
475 # NOTE(ianw) OpenDev infra only keeps the latest two Fedora's
476 # around; prefer the mirror but allow fallback
474 if [[ -e /etc/ci/mirror_info.sh ]]; then477 if [[ -e /etc/ci/mirror_info.sh ]]; then
475 source /etc/ci/mirror_info.sh478 source /etc/ci/mirror_info.sh
476 fi479 fi
477 export HEAT_TEST_FEDORA_IMAGE=${NODEPOOL_FEDORA_MIRROR:-https://download.fedoraproject.org/pub/fedora/linux}/releases/33/Cloud/x86_64/images/Fedora-Cloud-Base-33-1.2.x86_64.qcow2480 HEAT_TEST_FEDORA_IMAGE_UPSTREAM=https://download.fedoraproject.org/pub/fedora/linux
481 HEAT_TEST_FEDORA_IMAGE_PATH=releases/33/Cloud/x86_64/images/Fedora-Cloud-Base-33-1.2.x86_64.qcow2
482 if curl --output /dev/null --silent --head --fail "${NODEPOOL_FEDORA_MIRROR}/${HEAT_TEST_FEDORA_IMAGE_PATH}"; then
483 export HEAT_TEST_FEDORA_IMAGE="${NODEPOOL_FEDORA_MIRROR}/${HEAT_TEST_FEDORA_IMAGE_PATH}"
484 else
485 export HEAT_TEST_FEDORA_IMAGE="${HEAT_TEST_FEDORA_IMAGE_UPSTREAM}/${HEAT_TEST_FEDORA_IMAGE_PATH}"
486 fi
478 TOKEN=$(openstack token issue -c id -f value)487 TOKEN=$(openstack token issue -c id -f value)
479 local image_exists=$( openstack image list | grep "Fedora-Cloud-Base-33-1.2.x86_64" )488 local image_exists=$( openstack image list | grep "Fedora-Cloud-Base-33-1.2.x86_64" )
480 if [[ -z $image_exists ]]; then489 if [[ -z $image_exists ]]; then
diff --git a/heat/engine/resources/openstack/heat/resource_group.py b/heat/engine/resources/openstack/heat/resource_group.py
index 48ef05a..1bdc0c3 100644
--- a/heat/engine/resources/openstack/heat/resource_group.py
+++ b/heat/engine/resources/openstack/heat/resource_group.py
@@ -15,6 +15,7 @@ import collections
15import copy15import copy
16import functools16import functools
17import itertools17import itertools
18import math
1819
19from oslo_log import log as logging20from oslo_log import log as logging
2021
@@ -433,18 +434,18 @@ class ResourceGroup(stack_resource.StackResource):
433 return False434 return False
434 return True435 return True
435436
436 def _run_to_completion(self, template, timeout):437 def _run_to_completion(self, template, timeout_mins):
437 updater = self.update_with_template(template, {},438 updater = self.update_with_template(template, {},
438 timeout)439 timeout_mins)
439440
440 while not super(ResourceGroup,441 while not super(ResourceGroup,
441 self).check_update_complete(updater):442 self).check_update_complete(updater):
442 yield443 yield
443444
444 def _run_update(self, total_capacity, max_updates, timeout):445 def _run_update(self, total_capacity, max_updates, timeout_mins):
445 template = self._assemble_for_rolling_update(total_capacity,446 template = self._assemble_for_rolling_update(total_capacity,
446 max_updates)447 max_updates)
447 return self._run_to_completion(template, timeout)448 return self._run_to_completion(template, timeout_mins)
448449
449 def check_update_complete(self, checkers):450 def check_update_complete(self, checkers):
450 for checker in checkers:451 for checker in checkers:
@@ -776,13 +777,18 @@ class ResourceGroup(stack_resource.StackResource):
776777
777 batches = list(self._get_batches(self.get_size(), curr_cap, batch_size,778 batches = list(self._get_batches(self.get_size(), curr_cap, batch_size,
778 min_in_service))779 min_in_service))
779 update_timeout = self._update_timeout(len(batches), pause_sec)780 update_timeout_secs = self._update_timeout(len(batches), pause_sec)
781
782 # NOTE(gibi) update_timeout is in seconds but the _run_update
783 # eventually calls StackResource.update_with_template that takes
784 # timeout in minutes so we need to convert here.
785 update_timeout_mins = math.ceil(update_timeout_secs / 60)
780786
781 def tasks():787 def tasks():
782 for index, (curr_cap, max_upd) in enumerate(batches):788 for index, (curr_cap, max_upd) in enumerate(batches):
783 yield scheduler.TaskRunner(self._run_update,789 yield scheduler.TaskRunner(self._run_update,
784 curr_cap, max_upd,790 curr_cap, max_upd,
785 update_timeout)791 update_timeout_mins)
786792
787 if index < (len(batches) - 1) and pause_sec > 0:793 if index < (len(batches) - 1) and pause_sec > 0:
788 yield scheduler.TaskRunner(pause_between_batch, pause_sec)794 yield scheduler.TaskRunner(pause_between_batch, pause_sec)
diff --git a/heat/engine/resources/openstack/nova/server_group.py b/heat/engine/resources/openstack/nova/server_group.py
index afc417b..b4eb956 100644
--- a/heat/engine/resources/openstack/nova/server_group.py
+++ b/heat/engine/resources/openstack/nova/server_group.py
@@ -35,11 +35,13 @@ class ServerGroup(resource.Resource):
35 entity = 'server_groups'35 entity = 'server_groups'
3636
37 PROPERTIES = (37 PROPERTIES = (
38 NAME, POLICIES, RULE38 NAME, POLICIES, RULES
39 ) = (39 ) = (
40 'name', 'policies', 'rule'40 'name', 'policies', 'rules'
41 )41 )
4242
43 _RULES = (MAX_SERVER_PER_HOST) = ('max_server_per_host')
44
43 properties_schema = {45 properties_schema = {
44 NAME: properties.Schema(46 NAME: properties.Schema(
45 properties.Schema.STRING,47 properties.Schema.STRING,
@@ -47,7 +49,7 @@ class ServerGroup(resource.Resource):
47 ),49 ),
48 POLICIES: properties.Schema(50 POLICIES: properties.Schema(
49 properties.Schema.LIST,51 properties.Schema.LIST,
50 _('A list of string policies to apply. '52 _('A list of exactly one policy to apply. '
51 'Defaults to anti-affinity.'),53 'Defaults to anti-affinity.'),
52 default=['anti-affinity'],54 default=['anti-affinity'],
53 constraints=[55 constraints=[
@@ -59,11 +61,17 @@ class ServerGroup(resource.Resource):
59 properties.Schema.STRING,61 properties.Schema.STRING,
60 ),62 ),
61 ),63 ),
62 RULE: properties.Schema(64 RULES: properties.Schema(
63 properties.Schema.MAP,65 properties.Schema.MAP,
64 _('A rule for the policy. Currently, only the '66 _('Rules for a policy.'),
65 '"max_server_per_host" rule is supported for the '67 schema={
66 '"anti-affinity" policy.'),68 MAX_SERVER_PER_HOST: properties.Schema(
69 properties.Schema.NUMBER,
70 _('Maximum servers in a group on a given host. '
71 'Rule for anti-affinity policy.')
72 )
73 },
74 support_status=support.SupportStatus(version='17.0.0'),
67 ),75 ),
68 }76 }
6977
@@ -77,26 +85,25 @@ class ServerGroup(resource.Resource):
77 msg = _('Required microversion for soft policies not supported.')85 msg = _('Required microversion for soft policies not supported.')
78 raise exception.StackValidationFailed(message=msg)86 raise exception.StackValidationFailed(message=msg)
7987
80 if self.properties[self.RULE]:88 if self.properties[self.RULES]:
81 is_supported = self.client_plugin().is_version_supported(89 is_supported = self.client_plugin().is_version_supported(
82 MICROVERSION_RULE)90 MICROVERSION_RULE)
83 if not is_supported:91 if not is_supported:
84 msg = _('Required microversion for rule not supported.')92 msg = _('Required microversion for rules not supported.')
85 raise exception.StackValidationFailed(message=msg)93 raise exception.StackValidationFailed(message=msg)
8694
87 def handle_create(self):95 def handle_create(self):
88 name = self.physical_resource_name()96 name = self.physical_resource_name()
89 policies = self.properties[self.POLICIES]97 policies = self.properties[self.POLICIES]
90 if self.properties[self.RULE] and 'soft-affinity' in policies:98 rules = self.properties[self.RULES]
91 rule = self.properties[self.RULE]99 rules_supported = self.client_plugin().is_version_supported(
92 client = self.client()100 MICROVERSION_RULE)
93 server_group = client.server_groups.create(name=name,101 if rules_supported:
94 policies=policies,102 server_group = self.client().server_groups.create(
95 rule=rule)103 name=name, policy=policies[0], rules=rules)
96 else:104 else:
97 client = self.client()105 server_group = self.client().server_groups.create(
98 server_group = client.server_groups.create(name=name,106 name=name, policies=policies)
99 policies=policies)
100 self.resource_id_set(server_group.id)107 self.resource_id_set(server_group.id)
101108
102 def physical_resource_name(self):109 def physical_resource_name(self):
diff --git a/heat/tests/openstack/nova/test_server_group.py b/heat/tests/openstack/nova/test_server_group.py
index 0a1e682..c2dfda4 100644
--- a/heat/tests/openstack/nova/test_server_group.py
+++ b/heat/tests/openstack/nova/test_server_group.py
@@ -26,7 +26,9 @@ sg_template = {
26 "type": "OS::Nova::ServerGroup",26 "type": "OS::Nova::ServerGroup",
27 "properties": {27 "properties": {
28 "name": "test",28 "name": "test",
29 "policies": ["anti-affinity"]29 "policies": ["anti-affinity"],
30 "rules": {
31 "max_server_per_host": 8}
30 }32 }
31 }33 }
32 }34 }
@@ -50,6 +52,12 @@ class NovaServerGroupTest(common.HeatTestCase):
50 # create mock clients and objects52 # create mock clients and objects
51 nova = mock.MagicMock()53 nova = mock.MagicMock()
52 self.sg.client = mock.MagicMock(return_value=nova)54 self.sg.client = mock.MagicMock(return_value=nova)
55 mock_plugin = mock.MagicMock()
56 self.patchobject(mock_plugin,
57 'is_version_supported',
58 return_value=True)
59 self.patchobject(self.sg, 'client_plugin',
60 return_value=mock_plugin)
53 self.sg_mgr = nova.server_groups61 self.sg_mgr = nova.server_groups
5462
55 def _create_sg(self, name):63 def _create_sg(self, name):
@@ -68,7 +76,7 @@ class NovaServerGroupTest(common.HeatTestCase):
68 name = 'test'76 name = 'test'
69 n = name77 n = name
7078
71 def fake_create(name, policies):79 def fake_create(name, policy, rules):
72 self.assertGreater(len(name), 1)80 self.assertGreater(len(name), 1)
73 return FakeGroup(n)81 return FakeGroup(n)
74 self.sg_mgr.create = fake_create82 self.sg_mgr.create = fake_create
@@ -81,7 +89,9 @@ class NovaServerGroupTest(common.HeatTestCase):
81 self._create_sg('test')89 self._create_sg('test')
82 expected_args = ()90 expected_args = ()
83 expected_kwargs = {'name': 'test',91 expected_kwargs = {'name': 'test',
84 'policies': ["anti-affinity"],92 'policy': "anti-affinity",
93 'rules': {
94 'max_server_per_host': 8}
85 }95 }
86 self.sg_mgr.create.assert_called_once_with(*expected_args,96 self.sg_mgr.create.assert_called_once_with(*expected_args,
87 **expected_kwargs)97 **expected_kwargs)
diff --git a/heat_integrationtests/functional/test_resource_group.py b/heat_integrationtests/functional/test_resource_group.py
index ebce70d..07be7f2 100644
--- a/heat_integrationtests/functional/test_resource_group.py
+++ b/heat_integrationtests/functional/test_resource_group.py
@@ -129,6 +129,60 @@ resources:
129 outputs.append(validate_output(stack, 'random2', 30))129 outputs.append(validate_output(stack, 'random2', 30))
130 self.assertEqual(outputs, self._stack_output(stack, 'all_values'))130 self.assertEqual(outputs, self._stack_output(stack, 'all_values'))
131131
132 def test_create_nested_groups_with_timeout(self):
133 parent_template = '''
134heat_template_version: rocky
135resources:
136 parent_group:
137 type: OS::Heat::ResourceGroup
138 update_policy:
139 batch_create: { max_batch_size: 1, pause_time: 1 }
140 properties:
141 count: 2
142 resource_def:
143 type: child.yaml
144'''
145 child_template = '''
146heat_template_version: rocky
147resources:
148 child_group:
149 type: OS::Heat::ResourceGroup
150 update_policy:
151 batch_create: { max_batch_size: 1, pause_time: 1 }
152 properties:
153 count: 2
154 resource_def:
155 type: value.yaml
156'''
157 value_template = '''
158heat_template_version: rocky
159resources:
160 value:
161 type: OS::Heat::Value
162 properties:
163 type: string
164 value: 'test'
165'''
166 files = {
167 'child.yaml': child_template,
168 'value.yaml': value_template,
169 }
170 stack_identifier = self.stack_create(
171 template=parent_template,
172 files=files,
173 timeout=10, # in minutes
174 )
175
176 resources = self.client.resources.list(
177 stack_identifier, nested_depth=2, with_detail=True)
178 timeouts = set()
179 for res in resources:
180 if res.resource_type == "OS::Heat::ResourceGroup":
181 nested_stack = self.client.stacks.get(res.physical_resource_id)
182 timeouts.add(nested_stack.timeout_mins)
183
184 self.assertEqual({10}, timeouts)
185
132 def test_update_increase_decrease_count(self):186 def test_update_increase_decrease_count(self):
133 # create stack with resource group count 2187 # create stack with resource group count 2
134 env = {'resource_registry':188 env = {'resource_registry':
diff --git a/openstack_heat.egg-info/PKG-INFO b/openstack_heat.egg-info/PKG-INFO
index 7ef1230..315b8c6 100644
--- a/openstack_heat.egg-info/PKG-INFO
+++ b/openstack_heat.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
1Metadata-Version: 1.21Metadata-Version: 1.2
2Name: openstack-heat2Name: openstack-heat
3Version: 17.0.03Version: 17.0.1
4Summary: OpenStack Orchestration4Summary: OpenStack Orchestration
5Home-page: https://docs.openstack.org/heat/latest/5Home-page: https://docs.openstack.org/heat/latest/
6Author: OpenStack6Author: OpenStack
diff --git a/openstack_heat.egg-info/pbr.json b/openstack_heat.egg-info/pbr.json
index 4773ead..9aeecc8 100644
--- a/openstack_heat.egg-info/pbr.json
+++ b/openstack_heat.egg-info/pbr.json
@@ -1 +1 @@
1{"git_version": "4cf0ff641", "is_release": true}
2\ No newline at end of file1\ No newline at end of file
2{"git_version": "ef36cb304", "is_release": true}
3\ No newline at end of file3\ No newline at end of file
diff --git a/tox.ini b/tox.ini
index 5e76541..eb87eff 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,6 +9,7 @@ basepython = python3
9setenv = VIRTUAL_ENV={envdir}9setenv = VIRTUAL_ENV={envdir}
10 PYTHONWARNINGS=default::DeprecationWarning10 PYTHONWARNINGS=default::DeprecationWarning
11 OS_TEST_PATH=heat/tests11 OS_TEST_PATH=heat/tests
12install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/xena} {opts} {packages}
12usedevelop = True13usedevelop = True
13deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/xena}14deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/xena}
14 -r{toxinidir}/requirements.txt15 -r{toxinidir}/requirements.txt

Subscribers

People subscribed via source and target branches