Merge lp:~adam-collard/charms/trusty/swift-proxy/guard-paused-unit-service-restarts into lp:~openstack-charmers-archive/charms/trusty/swift-proxy/next

Proposed by Adam Collard
Status: Merged
Merged at revision: 110
Proposed branch: lp:~adam-collard/charms/trusty/swift-proxy/guard-paused-unit-service-restarts
Merge into: lp:~openstack-charmers-archive/charms/trusty/swift-proxy/next
Prerequisite: lp:~adam-collard/charms/trusty/swift-proxy/add-pause-resume-actions
Diff against target: 214 lines (+83/-15)
4 files modified
hooks/swift_hooks.py (+19/-14)
lib/swift_utils.py (+19/-1)
tests/basic_deployment.py (+33/-0)
unit_tests/test_swift_utils.py (+12/-0)
To merge this branch: bzr merge lp:~adam-collard/charms/trusty/swift-proxy/guard-paused-unit-service-restarts
Reviewer Review Type Date Requested Status
Chris Glass (community) Approve
Geoff Teale (community) Approve
Review via email: mp+270641@code.launchpad.net

Description of the change

This is a follow up branch to https://code.launchpad.net/~adam-collard/charms/trusty/swift-proxy/add-pause-resume-actions/+merge/270407 to prevent config-changed and other hooks from blindly (re)starting services when the unit is paused.

Normal flow is pause(), (optionally) change config -> changes should be persisted on disk, but nothing started. resume() -> services started.

It's a mirror of https://code.launchpad.net/~adam-collard/charms/trusty/swift-storage/guard-paused-unit-service-restarts/+merge/269860

To post a comment you must log in.
114. By Adam Collard

Back out accidental commit of pointer to tealeg's charm-helpers branch

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

charm_lint_check #9702 swift-proxy-next for adam-collard mp270641
    LINT FAIL: lint-test failed
    LINT FAIL: charm-proof failed

LINT Results (max last 2 lines):
make: *** [lint] Error 100
ERROR:root:Make target returned non-zero.

Full lint test output: http://paste.ubuntu.com/12328231/
Build: http://10.245.162.77:8080/job/charm_lint_check/9702/

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

charm_unit_test #8938 swift-proxy-next for adam-collard mp270641
    UNIT OK: passed

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

115. By Adam Collard

Merge from ../add-pause-resume-actions/

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

charm_lint_check #9716 swift-proxy-next for adam-collard mp270641
    LINT OK: passed

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

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

charm_unit_test #8947 swift-proxy-next for adam-collard mp270641
    UNIT OK: passed

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

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

charm_amulet_test #6342 swift-proxy-next for adam-collard mp270641
    AMULET OK: passed

Build: http://10.245.162.77:8080/job/charm_amulet_test/6342/

Revision history for this message
Geoff Teale (tealeg) wrote :

+1

review: Approve
Revision history for this message
Chris Glass (tribaal) wrote :

+1, Merged.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'hooks/swift_hooks.py'
--- hooks/swift_hooks.py 2015-09-07 13:44:04 +0000
+++ hooks/swift_hooks.py 2015-09-10 14:15:17 +0000
@@ -32,6 +32,8 @@
32 get_first_available_value,32 get_first_available_value,
33 all_responses_equal,33 all_responses_equal,
34 ensure_www_dir_permissions,34 ensure_www_dir_permissions,
35 is_paused,
36 pause_aware_restart_on_change
35)37)
3638
37import charmhelpers.contrib.openstack.utils as openstack39import charmhelpers.contrib.openstack.utils as openstack
@@ -60,7 +62,6 @@
60 service_restart,62 service_restart,
61 service_stop,63 service_stop,
62 service_start,64 service_start,
63 restart_on_change,
64)65)
65from charmhelpers.fetch import (66from charmhelpers.fetch import (
66 apt_install,67 apt_install,
@@ -121,7 +122,7 @@
121122
122123
123@hooks.hook('config-changed')124@hooks.hook('config-changed')
124@restart_on_change(restart_map())125@pause_aware_restart_on_change(restart_map())
125def config_changed():126def config_changed():
126 if config('prefer-ipv6'):127 if config('prefer-ipv6'):
127 setup_ipv6()128 setup_ipv6()
@@ -161,7 +162,7 @@
161162
162163
163@hooks.hook('identity-service-relation-changed')164@hooks.hook('identity-service-relation-changed')
164@restart_on_change(restart_map())165@pause_aware_restart_on_change(restart_map())
165def keystone_changed():166def keystone_changed():
166 configure_https()167 configure_https()
167168
@@ -181,7 +182,7 @@
181182
182183
183@hooks.hook('swift-storage-relation-changed')184@hooks.hook('swift-storage-relation-changed')
184@restart_on_change(restart_map())185@pause_aware_restart_on_change(restart_map())
185def storage_changed():186def storage_changed():
186 """Storage relation.187 """Storage relation.
187188
@@ -231,13 +232,14 @@
231 node_settings['devices'] = devs.split(':')232 node_settings['devices'] = devs.split(':')
232233
233 update_rings(node_settings)234 update_rings(node_settings)
234 # Restart proxy here in case no config changes made (so235 if not is_paused():
235 # restart_on_change() ineffective).236 # Restart proxy here in case no config changes made (so
236 service_restart('swift-proxy')237 # pause_aware_restart_on_change() ineffective).
238 service_restart('swift-proxy')
237239
238240
239@hooks.hook('swift-storage-relation-broken')241@hooks.hook('swift-storage-relation-broken')
240@restart_on_change(restart_map())242@pause_aware_restart_on_change(restart_map())
241def storage_broken():243def storage_broken():
242 CONFIGS.write_all()244 CONFIGS.write_all()
243245
@@ -358,7 +360,8 @@
358 broker = settings.get('builder-broker', None)360 broker = settings.get('builder-broker', None)
359 if not broker:361 if not broker:
360 log("No update available", level=DEBUG)362 log("No update available", level=DEBUG)
361 service_start('swift-proxy')363 if not is_paused():
364 service_start('swift-proxy')
362 return365 return
363366
364 builders_only = int(settings.get('sync-only-builders', 0))367 builders_only = int(settings.get('sync-only-builders', 0))
@@ -375,14 +378,15 @@
375 if fully_synced():378 if fully_synced():
376 log("Ring builders synced - starting proxy", level=INFO)379 log("Ring builders synced - starting proxy", level=INFO)
377 CONFIGS.write_all()380 CONFIGS.write_all()
378 service_start('swift-proxy')381 if not is_paused():
382 service_start('swift-proxy')
379 else:383 else:
380 log("Not all builders and rings synced yet - waiting for peer sync "384 log("Not all builders and rings synced yet - waiting for peer sync "
381 "before starting proxy", level=INFO)385 "before starting proxy", level=INFO)
382386
383387
384@hooks.hook('cluster-relation-changed')388@hooks.hook('cluster-relation-changed')
385@restart_on_change(restart_map())389@pause_aware_restart_on_change(restart_map())
386def cluster_changed():390def cluster_changed():
387 key = SwiftProxyClusterRPC.KEY_NOTIFY_LEADER_CHANGED391 key = SwiftProxyClusterRPC.KEY_NOTIFY_LEADER_CHANGED
388 leader_changed = relation_get(attribute=key)392 leader_changed = relation_get(attribute=key)
@@ -481,9 +485,10 @@
481 if os.path.exists('/usr/sbin/a2enconf'):485 if os.path.exists('/usr/sbin/a2enconf'):
482 check_call(['a2enconf', 'swift-rings'])486 check_call(['a2enconf', 'swift-rings'])
483487
484 # TODO: improve this by checking if local CN certs are available488 if not is_paused():
485 # first then checking reload status (see LP #1433114).489 # TODO: improve this by checking if local CN certs are available
486 service_reload('apache2', restart_on_failure=True)490 # first then checking reload status (see LP #1433114).
491 service_reload('apache2', restart_on_failure=True)
487492
488 for rid in relation_ids('identity-service'):493 for rid in relation_ids('identity-service'):
489 keystone_joined(relid=rid)494 keystone_joined(relid=rid)
490495
=== modified file 'lib/swift_utils.py'
--- lib/swift_utils.py 2015-09-07 13:44:04 +0000
+++ lib/swift_utils.py 2015-09-10 14:15:17 +0000
@@ -42,6 +42,7 @@
42 relation_set,42 relation_set,
43 relation_ids,43 relation_ids,
44 related_units,44 related_units,
45 status_get
45)46)
46from charmhelpers.fetch import (47from charmhelpers.fetch import (
47 apt_update,48 apt_update,
@@ -50,7 +51,8 @@
50 add_source51 add_source
51)52)
52from charmhelpers.core.host import (53from charmhelpers.core.host import (
53 lsb_release54 lsb_release,
55 restart_on_change,
54)56)
55from charmhelpers.contrib.network.ip import (57from charmhelpers.contrib.network.ip import (
56 format_ipv6_addr,58 format_ipv6_addr,
@@ -994,3 +996,19 @@
994 return get_ipv6_addr(exc_list=[config('vip')])[0]996 return get_ipv6_addr(exc_list=[config('vip')])[0]
995997
996 return unit_get('private-address')998 return unit_get('private-address')
999
1000
1001def is_paused(status_get=status_get):
1002 """Is the unit paused?"""
1003 status, message = status_get()
1004 return status == "maintenance" and message.startswith("Paused")
1005
1006
1007def pause_aware_restart_on_change(restart_map):
1008 """Avoids restarting services if config changes when unit is paused."""
1009 def wrapper(f):
1010 if is_paused():
1011 return f
1012 else:
1013 return restart_on_change(restart_map)(f)
1014 return wrapper
9971015
=== modified file 'tests/basic_deployment.py'
--- tests/basic_deployment.py 2015-09-10 14:15:17 +0000
+++ tests/basic_deployment.py 2015-09-10 14:15:17 +0000
@@ -333,6 +333,39 @@
333333
334 self.d.configure('swift-proxy', {'node-timeout': '60'})334 self.d.configure('swift-proxy', {'node-timeout': '60'})
335335
336 def test_z_no_restart_on_config_change_when_paused(self):
337 """Verify that the specified services are not restarted when the config
338 is changed and the unit is paused."""
339 u.log.info('Checking that system services do not get restarted '
340 'when charm config changes but unit is paused...')
341 sentry = self.swift_proxy_sentry
342 juju_service = 'swift-proxy'
343
344 # Expected default and alternate values
345 set_default = {'node-timeout': '60'}
346 set_alternate = {'node-timeout': '90'}
347
348 services = ['swift-proxy', 'haproxy', 'apache2', 'memcached']
349
350 # Pause the unit
351 u.log.debug('Pausing the unit...')
352 pause_action_id = u.run_action(sentry, "pause")
353 assert u.wait_on_action(pause_action_id), "Resume action failed."
354 # Make config change, check for service restarts
355 u.log.debug('Making config change on {}...'.format(juju_service))
356 self.d.configure(juju_service, set_alternate)
357
358 for service in services:
359 u.log.debug("Checking that service didn't start while "
360 "paused: {}".format(service))
361 # No explicit assert because get_process_id_list will do it for us
362 u.get_process_id_list(
363 sentry, service, expect_success=False)
364
365 self.d.configure(juju_service, set_default)
366 resume_action_id = u.run_action(sentry, "resume")
367 assert u.wait_on_action(resume_action_id), "Resume action failed."
368
336 def _assert_services(self, should_run):369 def _assert_services(self, should_run):
337 swift_proxy_services = ['swift-proxy-server',370 swift_proxy_services = ['swift-proxy-server',
338 'haproxy',371 'haproxy',
339372
=== modified file 'unit_tests/test_swift_utils.py'
--- unit_tests/test_swift_utils.py 2015-09-07 13:44:04 +0000
+++ unit_tests/test_swift_utils.py 2015-09-10 14:15:17 +0000
@@ -222,3 +222,15 @@
222222
223 rsps = []223 rsps = []
224 self.assertIsNone(swift_utils.get_first_available_value(rsps, 'key3'))224 self.assertIsNone(swift_utils.get_first_available_value(rsps, 'key3'))
225
226 def test_is_paused_unknown(self):
227 fake_status_get = lambda: ("unknown", "")
228 self.assertFalse(swift_utils.is_paused(status_get=fake_status_get))
229
230 def test_is_paused_paused(self):
231 fake_status_get = lambda: ("maintenance", "Paused")
232 self.assertTrue(swift_utils.is_paused(status_get=fake_status_get))
233
234 def test_is_paused_other_maintenance(self):
235 fake_status_get = lambda: ("maintenance", "Hook")
236 self.assertFalse(swift_utils.is_paused(status_get=fake_status_get))

Subscribers

People subscribed via source and target branches