Merge ~cjwatson/turnip:fix-rabbitmq-hooks into turnip:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: c5ab05edf6dbb775d45bd431b22abc6b303acfae
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/turnip:fix-rabbitmq-hooks
Merge into: turnip:master
Diff against target: 182 lines (+37/-37)
5 files modified
charm/layer/turnip-base/lib/charms/turnip/base.py (+3/-8)
charm/turnip-api/lib/charms/turnip/api.py (+1/-5)
charm/turnip-api/reactive/turnip-api.py (+15/-8)
charm/turnip-celery/lib/charms/turnip/celery.py (+2/-8)
charm/turnip-celery/reactive/turnip-celery.py (+16/-8)
Reviewer Review Type Date Requested Status
Thiago F. Pappacena (community) Approve
Review via email: mp+389630@code.launchpad.net

Commit message

charm: Fix handling of rabbitmq relations

Description of the change

Avoid trying to start turnip-celery when its code and storage prerequisites are potentially unavailable.

Rearrange how we request access to rabbitmq. Using the 'available' state provided by the rabbitmq interface means we can guarantee that the broker URL will always be available at that point, simplifying configuration. To ensure that things work if the rabbitmq relation is removed and re-added, we must explicitly clear any previous access request so that the rabbitmq-server charm notices that the relation data has changed.

To post a comment you must log in.
Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/charm/layer/turnip-base/lib/charms/turnip/base.py b/charm/layer/turnip-base/lib/charms/turnip/base.py
2index dbeada4..35ebf76 100644
3--- a/charm/layer/turnip-base/lib/charms/turnip/base.py
4+++ b/charm/layer/turnip-base/lib/charms/turnip/base.py
5@@ -368,15 +368,10 @@ def publish_website(website, name, port):
6 def get_rabbitmq_url():
7 rabbitmq = endpoint_from_name('amqp')
8
9- vhost = rabbitmq.vhost() if rabbitmq.vhost() else "/"
10- if not rabbitmq.username():
11- try:
12- rabbitmq.request_access(username="turnip", vhost=vhost)
13- except Exception:
14- pass
15-
16 if not rabbitmq.username() or not rabbitmq.password():
17- return None
18+ raise AssertionError(
19+ 'get_rabbitmq_url called when amqp relation data incomplete')
20
21 user = "%s:%s" % (rabbitmq.username(), rabbitmq.password())
22+ vhost = rabbitmq.vhost() if rabbitmq.vhost() else "/"
23 return "pyamqp://%s@%s/%s" % (user, rabbitmq.private_address(), vhost)
24diff --git a/charm/turnip-api/lib/charms/turnip/api.py b/charm/turnip-api/lib/charms/turnip/api.py
25index 77b7976..7635b10 100644
26--- a/charm/turnip-api/lib/charms/turnip/api.py
27+++ b/charm/turnip-api/lib/charms/turnip/api.py
28@@ -24,9 +24,6 @@ from charms.turnip.base import (
29
30
31 def configure_wsgi():
32- celery_broker = get_rabbitmq_url()
33- if celery_broker is None:
34- return host.service_running('turnip-api')
35 config = hookenv.config()
36 context = dict(config)
37 context.update({
38@@ -36,7 +33,7 @@ def configure_wsgi():
39 'data_mount_unit': data_mount_unit(),
40 'logs_dir': logs_dir(),
41 'venv_dir': venv_dir(),
42- 'celery_broker': celery_broker,
43+ 'celery_broker': get_rabbitmq_url(),
44 })
45 if context['wsgi_workers'] == 0:
46 context['wsgi_workers'] = cpu_count() * 2 + 1
47@@ -51,4 +48,3 @@ def configure_wsgi():
48 host.service_stop('turnip-api')
49 if not host.service_resume('turnip-api'):
50 raise RuntimeError('Failed to start turnip-api')
51- return True
52diff --git a/charm/turnip-api/reactive/turnip-api.py b/charm/turnip-api/reactive/turnip-api.py
53index 223112d..dc304cf 100644
54--- a/charm/turnip-api/reactive/turnip-api.py
55+++ b/charm/turnip-api/reactive/turnip-api.py
56@@ -22,8 +22,7 @@ from charms.turnip.base import (
57 )
58
59
60-@when('turnip.installed', 'turnip.storage.available',
61- 'turnip.rabbitmq.available')
62+@when('turnip.installed', 'turnip.storage.available', 'amqp.available')
63 @when_not('turnip.configured')
64 def configure_turnip():
65 configure_wsgi()
66@@ -36,7 +35,7 @@ def configure_turnip():
67
68
69 @when('turnip.configured')
70-@when_not_all('turnip.storage.available', 'turnip.rabbitmq.available')
71+@when_not_all('turnip.storage.available', 'amqp.available')
72 def deconfigure_turnip():
73 deconfigure_service('turnip-api')
74 clear_flag('turnip.configured')
75@@ -44,11 +43,19 @@ def deconfigure_turnip():
76
77
78 @when('amqp.connected')
79-def rabbitmq_available():
80- if configure_wsgi():
81- set_flag('turnip.rabbitmq.available')
82- else:
83- clear_flag('turnip.rabbitmq.available')
84+@when_not('turnip.amqp.requested-access')
85+def request_amqp_access(rabbitmq):
86+ # Clear any previous request so that the rabbitmq-server charm notices
87+ # the change.
88+ rabbitmq.request_access(username='', vhost='')
89+ rabbitmq.request_access(username='turnip', vhost='/')
90+ set_flag('turnip.amqp.requested-access')
91+
92+
93+@when('turnip.amqp.requested-access')
94+@when_not('amqp.connected')
95+def unrequest_amqp_access():
96+ clear_flag('turnip.amqp.requested-access')
97
98
99 @when('nrpe-external-master.available', 'turnip.configured')
100diff --git a/charm/turnip-celery/lib/charms/turnip/celery.py b/charm/turnip-celery/lib/charms/turnip/celery.py
101index 60ed019..8120e77 100644
102--- a/charm/turnip-celery/lib/charms/turnip/celery.py
103+++ b/charm/turnip-celery/lib/charms/turnip/celery.py
104@@ -22,12 +22,7 @@ from charms.turnip.base import (
105
106
107 def configure_celery():
108- """Configure celery service, connecting it to rabbitmq.
109-
110- :return: True if service is running, False otherwise."""
111- celery_broker = get_rabbitmq_url()
112- if celery_broker is None:
113- return host.service_running('turnip-celery')
114+ """Configure celery service, connecting it to rabbitmq."""
115 config = hookenv.config()
116 context = dict(config)
117 context.update({
118@@ -36,7 +31,7 @@ def configure_celery():
119 'data_mount_unit': data_mount_unit(),
120 'logs_dir': logs_dir(),
121 'venv_dir': venv_dir(),
122- 'celery_broker': celery_broker,
123+ 'celery_broker': get_rabbitmq_url(),
124 })
125 templating.render(
126 'turnip-celery.service.j2',
127@@ -47,4 +42,3 @@ def configure_celery():
128 reload_systemd()
129 if not host.service_resume('turnip-celery'):
130 raise RuntimeError('Failed to start turnip-celery')
131- return True
132diff --git a/charm/turnip-celery/reactive/turnip-celery.py b/charm/turnip-celery/reactive/turnip-celery.py
133index 357e96b..84e3513 100644
134--- a/charm/turnip-celery/reactive/turnip-celery.py
135+++ b/charm/turnip-celery/reactive/turnip-celery.py
136@@ -21,10 +21,10 @@ from charms.turnip.base import (
137 )
138
139
140-@when('turnip.installed', 'turnip.storage.available',
141- 'turnip.rabbitmq.available')
142+@when('turnip.installed', 'turnip.storage.available', 'amqp.available')
143 @when_not('turnip.configured')
144 def configure_turnip():
145+ configure_celery()
146 configure_service()
147 set_flag('turnip.configured')
148 clear_flag('turnip.storage.nrpe-external-master.published')
149@@ -34,7 +34,7 @@ def configure_turnip():
150
151
152 @when('turnip.configured')
153-@when_not_all('turnip.storage.available', 'turnip.rabbitmq.available')
154+@when_not_all('turnip.storage.available', 'amqp.available')
155 def deconfigure_turnip():
156 deconfigure_service('turnip-celery')
157 clear_flag('turnip.configured')
158@@ -42,11 +42,19 @@ def deconfigure_turnip():
159
160
161 @when('amqp.connected')
162-def rabbitmq_available():
163- if configure_celery():
164- set_flag('turnip.rabbitmq.available')
165- else:
166- clear_flag('turnip.rabbitmq.available')
167+@when_not('turnip.amqp.requested-access')
168+def request_amqp_access(rabbitmq):
169+ # Clear any previous request so that the rabbitmq-server charm notices
170+ # the change.
171+ rabbitmq.request_access(username='', vhost='')
172+ rabbitmq.request_access(username='turnip', vhost='/')
173+ set_flag('turnip.amqp.requested-access')
174+
175+
176+@when('turnip.amqp.requested-access')
177+@when_not('amqp.connected')
178+def unrequest_amqp_access():
179+ clear_flag('turnip.amqp.requested-access')
180
181
182 @when('nrpe-external-master.available', 'turnip.configured')

Subscribers

People subscribed via source and target branches