Merge lp:~thedac/charms/trusty/nova-cloud-controller/action-managed-upgrade into lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next

Proposed by David Ames
Status: Merged
Merged at revision: 191
Proposed branch: lp:~thedac/charms/trusty/nova-cloud-controller/action-managed-upgrade
Merge into: lp:~openstack-charmers-archive/charms/trusty/nova-cloud-controller/next
Diff against target: 322 lines (+189/-10) (has conflicts)
8 files modified
actions.yaml (+2/-0)
actions/openstack_upgrade.py (+41/-0)
config.yaml (+10/-0)
hooks/charmhelpers/contrib/openstack/utils.py (+50/-0)
hooks/nova_cc_hooks.py (+2/-2)
hooks/nova_cc_utils.py (+1/-1)
unit_tests/test_actions_openstack_upgrade.py (+76/-0)
unit_tests/test_nova_cc_utils.py (+7/-7)
Text conflict in hooks/charmhelpers/contrib/openstack/utils.py
To merge this branch: bzr merge lp:~thedac/charms/trusty/nova-cloud-controller/action-managed-upgrade
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+271893@code.launchpad.net

Description of the change

Action managed upgrade

To post a comment you must log in.
Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #9614 nova-cloud-controller-next for thedac mp271893
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/9614/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #10426 nova-cloud-controller-next for thedac mp271893
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/10426/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #6568 nova-cloud-controller-next for thedac mp271893
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/12519427/
Build: http://10.245.162.77:8080/job/charm_amulet_test/6568/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #10467 nova-cloud-controller-next for thedac mp271893
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/10467/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #9658 nova-cloud-controller-next for thedac mp271893
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/9658/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #6610 nova-cloud-controller-next for thedac mp271893
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/12526974/
Build: http://10.245.162.77:8080/job/charm_amulet_test/6610/

189. By David Ames

Do not use register_configs import CONFIGS directly

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_lint_check #10576 nova-cloud-controller-next for thedac mp271893
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/10576/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_unit_test #9764 nova-cloud-controller-next for thedac mp271893
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/9764/

Revision history for this message
uosci-testing-bot (uosci-testing-bot) wrote :

charm_amulet_test #6710 nova-cloud-controller-next for thedac mp271893
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/12537992/
Build: http://10.245.162.77:8080/job/charm_amulet_test/6710/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'actions.yaml'
2--- actions.yaml 2015-04-15 14:17:56 +0000
3+++ actions.yaml 2015-09-23 16:09:47 +0000
4@@ -1,2 +1,4 @@
5 git-reinstall:
6 description: Reinstall nova-cloud-controller from the openstack-origin-git repositories.
7+openstack-upgrade:
8+ description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.
9
10=== added symlink 'actions/openstack-upgrade'
11=== target is u'openstack_upgrade.py'
12=== added file 'actions/openstack_upgrade.py'
13--- actions/openstack_upgrade.py 1970-01-01 00:00:00 +0000
14+++ actions/openstack_upgrade.py 2015-09-23 16:09:47 +0000
15@@ -0,0 +1,41 @@
16+#!/usr/bin/python
17+import sys
18+
19+sys.path.append('hooks/')
20+
21+from charmhelpers.contrib.openstack.utils import (
22+ do_action_openstack_upgrade,
23+)
24+
25+from charmhelpers.core.hookenv import (
26+ relation_ids,
27+)
28+
29+from nova_cc_utils import (
30+ do_openstack_upgrade,
31+)
32+
33+from nova_cc_hooks import (
34+ config_changed,
35+ CONFIGS,
36+ neutron_api_relation_joined,
37+)
38+
39+
40+def openstack_upgrade():
41+ """Upgrade packages to config-set Openstack version.
42+
43+ If the charm was installed from source we cannot upgrade it.
44+ For backwards compatibility a config flag must be set for this
45+ code to run, otherwise a full service level upgrade will fire
46+ on config-changed."""
47+
48+ if (do_action_openstack_upgrade('nova-common',
49+ do_openstack_upgrade,
50+ CONFIGS)):
51+ [neutron_api_relation_joined(rid=rid, remote_restart=True)
52+ for rid in relation_ids('neutron-api')]
53+ config_changed()
54+
55+if __name__ == '__main__':
56+ openstack_upgrade()
57
58=== modified file 'config.yaml'
59--- config.yaml 2015-09-21 18:06:09 +0000
60+++ config.yaml 2015-09-23 16:09:47 +0000
61@@ -395,3 +395,13 @@
62
63 If memcached is being used to store the tokens, then it's recommended to
64 change this configuration to False.
65+ action-managed-upgrade:
66+ type: boolean
67+ default: False
68+ description: |
69+ If True enables openstack upgrades for this charm via juju actions.
70+ You will still need to set openstack-origin to the new repository but
71+ instead of an upgrade running automatically across all units, it will
72+ wait for you to execute the openstack-upgrade action for this charm on
73+ each unit. If False it will revert to existing behavior of upgrading
74+ all units on config change.
75
76=== modified file 'hooks/charmhelpers/contrib/openstack/utils.py'
77--- hooks/charmhelpers/contrib/openstack/utils.py 2015-09-22 02:45:17 +0000
78+++ hooks/charmhelpers/contrib/openstack/utils.py 2015-09-23 16:09:47 +0000
79@@ -148,6 +148,9 @@
80 'glance-common': OrderedDict([
81 ('11.0.0', 'liberty'),
82 ]),
83+ 'openstack-dashboard': OrderedDict([
84+ ('8.0.0', 'liberty'),
85+ ]),
86 }
87
88 DEFAULT_LOOPBACK_SIZE = '5G'
89@@ -751,6 +754,7 @@
90 return projects[key]
91
92 return None
93+<<<<<<< TREE
94
95
96 def os_workload_status(configs, required_interfaces, charm_func=None):
97@@ -965,3 +969,49 @@
98 action_set({'outcome': 'no upgrade available.'})
99
100 return ret
101+=======
102+
103+
104+def do_action_openstack_upgrade(package, upgrade_callback, configs):
105+ """Perform action-managed OpenStack upgrade.
106+
107+ Upgrades packages to the configured openstack-origin version and sets
108+ the corresponding action status as a result.
109+
110+ If the charm was installed from source we cannot upgrade it.
111+ For backwards compatibility a config flag (action-managed-upgrade) must
112+ be set for this code to run, otherwise a full service level upgrade will
113+ fire on config-changed.
114+
115+ @param package: package name for determining if upgrade available
116+ @param upgrade_callback: function callback to charm's upgrade function
117+ @param configs: templating object derived from OSConfigRenderer class
118+
119+ @return: True if upgrade successful; False if upgrade failed or skipped
120+ """
121+ ret = False
122+
123+ if git_install_requested():
124+ action_set({'outcome': 'installed from source, skipped upgrade.'})
125+ else:
126+ if openstack_upgrade_available(package):
127+ if config('action-managed-upgrade'):
128+ juju_log('Upgrading OpenStack release')
129+
130+ try:
131+ upgrade_callback(configs=configs)
132+ action_set({'outcome': 'success, upgrade completed.'})
133+ ret = True
134+ except:
135+ action_set({'outcome': 'upgrade failed, see traceback.'})
136+ action_set({'traceback': traceback.format_exc()})
137+ action_fail('do_openstack_upgrade resulted in an '
138+ 'unexpected error')
139+ else:
140+ action_set({'outcome': 'action-managed-upgrade config is '
141+ 'False, skipped upgrade.'})
142+ else:
143+ action_set({'outcome': 'no upgrade available.'})
144+
145+ return ret
146+>>>>>>> MERGE-SOURCE
147
148=== modified file 'hooks/nova_cc_hooks.py'
149--- hooks/nova_cc_hooks.py 2015-09-22 13:52:12 +0000
150+++ hooks/nova_cc_hooks.py 2015-09-23 16:09:47 +0000
151@@ -182,9 +182,9 @@
152 if git_install_requested():
153 if config_value_changed('openstack-origin-git'):
154 git_install(config('openstack-origin-git'))
155- else:
156+ elif not config('action-managed-upgrade'):
157 if openstack_upgrade_available('nova-common'):
158- CONFIGS = do_openstack_upgrade()
159+ CONFIGS = do_openstack_upgrade(CONFIGS)
160 [neutron_api_relation_joined(rid=rid, remote_restart=True)
161 for rid in relation_ids('neutron-api')]
162 save_script_rc()
163
164=== modified file 'hooks/nova_cc_utils.py'
165--- hooks/nova_cc_utils.py 2015-08-06 06:04:08 +0000
166+++ hooks/nova_cc_utils.py 2015-09-23 16:09:47 +0000
167@@ -624,7 +624,7 @@
168 return configs
169
170
171-def do_openstack_upgrade():
172+def do_openstack_upgrade(configs):
173 new_src = config('openstack-origin')
174 if new_src[:6] != 'cloud:':
175 raise ValueError("Unable to perform upgrade to %s" % new_src)
176
177=== added file 'unit_tests/test_actions_openstack_upgrade.py'
178--- unit_tests/test_actions_openstack_upgrade.py 1970-01-01 00:00:00 +0000
179+++ unit_tests/test_actions_openstack_upgrade.py 2015-09-23 16:09:47 +0000
180@@ -0,0 +1,76 @@
181+from mock import patch, MagicMock
182+import os
183+
184+os.environ['JUJU_UNIT_NAME'] = 'nova-cloud-controller'
185+
186+
187+with patch('charmhelpers.core.hookenv.config') as config:
188+ config.return_value = 'nova'
189+ import nova_cc_utils as utils # noqa
190+
191+_reg = utils.register_configs
192+_map = utils.restart_map
193+
194+utils.register_configs = MagicMock()
195+utils.restart_map = MagicMock()
196+
197+with patch('nova_cc_utils.guard_map') as gmap:
198+ with patch('charmhelpers.core.hookenv.config') as config:
199+ config.return_value = False
200+ gmap.return_value = {}
201+ import openstack_upgrade
202+
203+utils.register_configs = _reg
204+utils.restart_map = _map
205+
206+from test_utils import (
207+ CharmTestCase
208+)
209+
210+TO_PATCH = [
211+ 'do_openstack_upgrade',
212+ 'relation_ids',
213+ 'neutron_api_relation_joined',
214+ 'config_changed',
215+]
216+
217+
218+class TestNovaCCUpgradeActions(CharmTestCase):
219+
220+ def setUp(self):
221+ super(TestNovaCCUpgradeActions, self).setUp(openstack_upgrade,
222+ TO_PATCH)
223+
224+ @patch('charmhelpers.contrib.openstack.utils.config')
225+ @patch('charmhelpers.contrib.openstack.utils.action_set')
226+ @patch('charmhelpers.contrib.openstack.utils.git_install_requested')
227+ @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
228+ def test_openstack_upgrade_true(self, upgrade_avail, git_requested,
229+ action_set, config):
230+ git_requested.return_value = False
231+ upgrade_avail.return_value = True
232+ config.return_value = True
233+ self.relation_ids.return_value = ['relid1']
234+
235+ openstack_upgrade.openstack_upgrade()
236+
237+ self.assertTrue(self.do_openstack_upgrade.called)
238+ self.assertTrue(
239+ self.neutron_api_relation_joined.called_with(rid='relid1',
240+ remote_restart=True))
241+ self.assertTrue(self.config_changed.called)
242+
243+ @patch('charmhelpers.contrib.openstack.utils.config')
244+ @patch('charmhelpers.contrib.openstack.utils.action_set')
245+ @patch('charmhelpers.contrib.openstack.utils.git_install_requested')
246+ @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
247+ def test_openstack_upgrade_false(self, upgrade_avail, git_requested,
248+ action_set, config):
249+ git_requested.return_value = False
250+ upgrade_avail.return_value = True
251+ config.return_value = False
252+
253+ openstack_upgrade.openstack_upgrade()
254+
255+ self.assertFalse(self.do_openstack_upgrade.called)
256+ self.assertFalse(self.config_changed.called)
257
258=== modified file 'unit_tests/test_nova_cc_utils.py'
259--- unit_tests/test_nova_cc_utils.py 2015-07-29 11:23:06 +0000
260+++ unit_tests/test_nova_cc_utils.py 2015-09-23 16:09:47 +0000
261@@ -647,7 +647,7 @@
262 'icehouse']
263 self.is_elected_leader.return_value = True
264 self.relation_ids.return_value = []
265- utils.do_openstack_upgrade()
266+ utils.do_openstack_upgrade(self.register_configs())
267 expected = [call(['stamp', 'grizzly']), call(['upgrade', 'head']),
268 call(['stamp', 'havana']), call(['upgrade', 'head'])]
269 self.assertEquals(self.neutron_db_manage.call_args_list, expected)
270@@ -655,7 +655,7 @@
271 self.apt_upgrade.assert_called_with(options=DPKG_OPTS, fatal=True,
272 dist=True)
273 self.apt_install.assert_called_with(determine_packages(), fatal=True)
274- expected = [call(release='havana'), call(release='icehouse')]
275+ expected = [call(), call(release='havana'), call(release='icehouse')]
276 self.assertEquals(self.register_configs.call_args_list, expected)
277 self.assertEquals(self.ml2_migration.call_count, 1)
278 self.assertTrue(migrate_nova_database.call_count, 2)
279@@ -673,7 +673,7 @@
280 self.get_os_codename_install_source.return_value = 'icehouse'
281 self.is_elected_leader.return_value = True
282 self.relation_ids.return_value = []
283- utils.do_openstack_upgrade()
284+ utils.do_openstack_upgrade(self.register_configs())
285 self.neutron_db_manage.assert_called_with(['upgrade', 'head'])
286 self.apt_update.assert_called_with(fatal=True)
287 self.apt_upgrade.assert_called_with(options=DPKG_OPTS, fatal=True,
288@@ -696,7 +696,7 @@
289 self.get_os_codename_install_source.return_value = 'juno'
290 self.is_elected_leader.return_value = True
291 self.relation_ids.return_value = []
292- utils.do_openstack_upgrade()
293+ utils.do_openstack_upgrade(self.register_configs())
294 neutron_db_calls = [call(['stamp', 'icehouse']),
295 call(['upgrade', 'head'])]
296 self.neutron_db_manage.assert_has_calls(neutron_db_calls,
297@@ -722,7 +722,7 @@
298 self.get_os_codename_install_source.return_value = 'kilo'
299 self.is_elected_leader.return_value = True
300 self.relation_ids.return_value = []
301- utils.do_openstack_upgrade()
302+ utils.do_openstack_upgrade(self.register_configs())
303 self.assertEquals(self.neutron_db_manage.call_count, 0)
304 self.apt_update.assert_called_with(fatal=True)
305 self.apt_upgrade.assert_called_with(options=DPKG_OPTS, fatal=True,
306@@ -741,7 +741,7 @@
307 _file.read = MagicMock()
308 _file.readline.return_value = ("deb url"
309 " precise-updates/grizzly main")
310- utils.do_openstack_upgrade()
311+ utils.do_openstack_upgrade(self.register_configs())
312 expected = [call('cloud:precise-havana'),
313 call('cloud:precise-icehouse')]
314 self.assertEquals(_do_openstack_upgrade.call_args_list, expected)
315@@ -754,7 +754,7 @@
316 with patch_open() as (_open, _file):
317 _file.read = MagicMock()
318 _file.readline.return_value = "deb url precise-updates/havana main"
319- utils.do_openstack_upgrade()
320+ utils.do_openstack_upgrade(self.register_configs())
321 expected = [call('cloud:precise-icehouse')]
322 self.assertEquals(_do_openstack_upgrade.call_args_list, expected)
323

Subscribers

People subscribed via source and target branches