10
import rabbit_utils as rabbit
11
import lib.utils as utils
12
import lib.cluster_utils as cluster
13
import lib.ceph_utils as ceph
14
import lib.openstack_common as openstack
17
SERVICE_NAME = os.getenv('JUJU_UNIT_NAME').split('/')[0]
18
POOL_NAME = SERVICE_NAME
19
RABBIT_DIR = '/var/lib/rabbitmq'
24
utils.install(*rabbit.PACKAGES)
28
def amqp_changed(relation_id=None, remote_unit=None):
29
if not cluster.eligible_leader('res_rabbitmq_vip'):
30
msg = 'amqp_changed(): Deferring amqp_changed to eligible_leader.'
31
utils.juju_log('INFO', msg)
34
rabbit_user = utils.relation_get('username', rid=relation_id,
36
vhost = utils.relation_get('vhost', rid=relation_id, unit=remote_unit)
37
if None in [rabbit_user, vhost]:
38
utils.juju_log('INFO', 'amqp_changed(): Relation not ready.')
41
password_file = os.path.join(RABBIT_DIR, '%s.passwd' % rabbit_user)
42
if os.path.exists(password_file):
43
password = open(password_file).read().strip()
45
cmd = ['pwgen', '64', '1']
46
password = subprocess.check_output(cmd).strip()
47
with open(password_file, 'wb') as out:
50
rabbit.create_vhost(vhost)
51
rabbit.create_user(rabbit_user, password)
52
rabbit.grant_permissions(rabbit_user, vhost)
53
rabbit_hostname = utils.unit_get('private-address')
57
'hostname': rabbit_hostname
59
if cluster.is_clustered():
60
relation_settings['clustered'] = 'true'
61
relation_settings['vip'] = utils.config_get('vip')
63
relation_settings['rid'] = relation_id
64
utils.relation_set(**relation_settings)
68
if utils.is_relation_made('ha'):
69
utils.juju_log('INFO',
70
'hacluster relation is present, skipping native '\
71
'rabbitmq cluster config.')
73
l_unit_no = os.getenv('JUJU_UNIT_NAME').split('/')[1]
74
r_unit_no = os.getenv('JUJU_REMOTE_UNIT').split('/')[1]
75
if l_unit_no > r_unit_no:
76
utils.juju_log('INFO', 'cluster_joined: Relation greater.')
78
rabbit.COOKIE_PATH = '/var/lib/rabbitmq/.erlang.cookie'
79
if not os.path.isfile(rabbit.COOKIE_PATH):
80
utils.juju_log('ERROR', 'erlang cookie missing from %s' %\
82
cookie = open(rabbit.COOKIE_PATH, 'r').read().strip()
83
local_hostname = subprocess.check_output(['hostname']).strip()
84
utils.relation_set(cookie=cookie, host=local_hostname)
87
def cluster_changed():
88
if utils.is_relation_made('ha'):
89
utils.juju_log('INFO',
90
'hacluster relation is present, skipping native '\
91
'rabbitmq cluster config.')
93
l_unit_no = os.getenv('JUJU_UNIT_NAME').split('/')[1]
94
r_unit_no = os.getenv('JUJU_REMOTE_UNIT').split('/')[1]
95
if l_unit_no < r_unit_no:
96
utils.juju_log('INFO', 'cluster_joined: Relation lesser.')
99
remote_host = utils.relation_get('host')
100
cookie = utils.relation_get('cookie')
101
if None in [remote_host, cookie]:
102
utils.juju_log('INFO',
103
'cluster_joined: remote_host|cookie not yet set.')
106
if open(rabbit.COOKIE_PATH, 'r').read().strip() == cookie:
107
utils.juju_log('INFO', 'Cookie already synchronized with peer.')
110
utils.juju_log('INFO', 'Synchronizing erlang cookie from peer.')
111
rabbit.service('stop')
112
with open(rabbit.COOKIE_PATH, 'wb') as out:
114
rabbit.service('start')
115
rabbit.cluster_with(remote_host)
119
corosync_bindiface = utils.config_get('ha-bindiface')
120
corosync_mcastport = utils.config_get('ha-mcastport')
121
vip = utils.config_get('vip')
122
vip_iface = utils.config_get('vip_iface')
123
vip_cidr = utils.config_get('vip_cidr')
124
rbd_name = utils.config_get('rbd-name')
126
if None in [corosync_bindiface, corosync_mcastport, vip, vip_iface,
128
utils.juju_log('ERROR', 'Insufficient configuration data to '\
129
'configure hacluster.')
132
if not utils.is_relation_made('ceph', 'auth'):
133
utils.juju_log('INFO',
134
'ha_joined: No ceph relation yet, deferring.')
137
name = '%s@localhost' % SERVICE_NAME
138
if rabbit.get_node_name() != name:
139
utils.juju_log('INFO', 'Stopping rabbitmq-server.')
140
utils.stop('rabbitmq-server')
141
rabbit.set_node_name('%s@localhost' % SERVICE_NAME)
143
utils.juju_log('INFO', 'Node name already set to %s.' % name)
145
relation_settings = {}
146
relation_settings['corosync_bindiface'] = corosync_bindiface
147
relation_settings['corosync_mcastport'] = corosync_mcastport
149
relation_settings['resources'] = {
150
'res_rabbitmq_rbd': 'ocf:ceph:rbd',
151
'res_rabbitmq_fs': 'ocf:heartbeat:Filesystem',
152
'res_rabbitmq_vip': 'ocf:heartbeat:IPaddr2',
153
'res_rabbitmq-server': 'lsb:rabbitmq-server',
156
relation_settings['resource_params'] = {
157
'res_rabbitmq_rbd': 'params name="%s" pool="%s" user="%s" '
159
(rbd_name, POOL_NAME,
160
SERVICE_NAME, ceph.keyfile_path(SERVICE_NAME)),
161
'res_rabbitmq_fs': 'params device="/dev/rbd/%s/%s" directory="%s" '\
162
'fstype="ext4" op start start-delay="10s"' %\
163
(POOL_NAME, rbd_name, RABBIT_DIR),
164
'res_rabbitmq_vip': 'params ip="%s" cidr_netmask="%s" nic="%s"' %\
165
(vip, vip_cidr, vip_iface),
166
'res_rabbitmq-server': 'op start start-delay="5s" op monitor interval="5s"',
169
relation_settings['groups'] = {
170
'grp_rabbitmq': 'res_rabbitmq_rbd res_rabbitmq_fs res_rabbitmq_vip '\
171
'res_rabbitmq-server',
174
for rel_id in utils.relation_ids('ha'):
175
utils.relation_set(rid=rel_id, **relation_settings)
178
'OPENSTACK_PORT_EPMD': 4369,
179
'OPENSTACK_PORT_MCASTPORT': utils.config_get('ha-mcastport'),
181
openstack.save_script_rc(**env_vars)
185
if not cluster.is_clustered():
187
vip = utils.config_get('vip')
188
utils.juju_log('INFO', 'ha_changed(): We are now HA clustered. '
189
'Advertising our VIP (%s) to all AMQP clients.' %\
191
# need to re-authenticate all clients since node-name changed.
192
for rid in utils.relation_ids('amqp'):
193
for unit in utils.relation_list(rid):
194
amqp_changed(relation_id=rid, remote_unit=unit)
198
utils.juju_log('INFO', 'Start Ceph Relation Joined')
200
utils.juju_log('INFO', 'Finish Ceph Relation Joined')
204
utils.juju_log('INFO', 'Start Ceph Relation Changed')
205
auth = utils.relation_get('auth')
206
key = utils.relation_get('key')
207
if None in [auth, key]:
208
utils.juju_log('INFO', 'Missing key or auth in relation')
211
ceph.configure(service=SERVICE_NAME, key=key, auth=auth)
213
if cluster.eligible_leader('res_rabbitmq_vip'):
214
rbd_img = utils.config_get('rbd-name')
215
rbd_size = utils.config_get('rbd-size')
216
sizemb = int(rbd_size.split('G')[0]) * 1024
217
blk_device = '/dev/rbd/%s/%s' % (POOL_NAME, rbd_img)
218
ceph.ensure_ceph_storage(service=SERVICE_NAME, pool=POOL_NAME,
219
rbd_img=rbd_img, sizemb=sizemb,
220
fstype='ext4', mount_point=RABBIT_DIR,
221
blk_device=blk_device,
222
system_services=['rabbitmq-server'])
224
utils.juju_log('INFO',
225
'This is not the peer leader. Not configuring RBD.')
226
utils.juju_log('INFO', 'Stopping rabbitmq-server.')
227
utils.stop('rabbitmq-server')
229
# If 'ha' relation has been made before the 'ceph' relation
230
# it is important to make sure the ha-relation data is being
232
if utils.is_relation_made('ha'):
233
utils.juju_log('INFO', '*ha* relation exists. Triggering ha_joined()')
236
utils.juju_log('INFO', '*ha* relation does not exist.')
237
utils.juju_log('INFO', 'Finish Ceph Relation Changed')
242
# Ensure older passwd files in /var/lib/juju are moved to
243
# /var/lib/rabbitmq which will end up replicated if clustered.
244
for f in [f for f in os.listdir('/var/lib/juju')
245
if os.path.isfile(os.path.join('/var/lib/juju', f))]:
246
if f.endswith('.passwd'):
247
s = os.path.join('/var/lib/juju', f)
248
d = os.path.join('/var/lib/rabbitmq', f)
249
utils.juju_log('INFO',
250
'upgrade_charm: Migrating stored passwd'
251
' from %s to %s.' % (s, d))
254
MAN_PLUGIN = 'rabbitmq_management'
256
def config_changed():
257
if utils.config_get('management_plugin') == True:
258
rabbit.enable_plugin(MAN_PLUGIN)
259
utils.open_port(55672)
261
rabbit.disable_plugin(MAN_PLUGIN)
262
utils.close_port(55672)
264
if utils.config_get('ssl_enabled') == True:
265
ssl_key = utils.config_get('ssl_key')
266
ssl_cert = utils.config_get('ssl_cert')
267
ssl_port = utils.config_get('ssl_port')
268
if None in [ ssl_key, ssl_cert, ssl_port ]:
269
utils.juju_log('ERROR',
270
'Please provide ssl_key, ssl_cert and ssl_port'
271
' config when enabling SSL support')
274
rabbit.enable_ssl(ssl_key, ssl_cert, ssl_port)
275
utils.open_port(ssl_port)
277
if os.path.exists(rabbit.RABBITMQ_CONF):
278
os.remove(rabbit.RABBITMQ_CONF)
279
utils.close_port(utils.config_get('ssl_port'))
281
utils.restart('rabbitmq-server')
284
def pre_install_hooks():
285
for f in glob.glob('exec.d/*/charm-pre-install'):
286
if os.path.isfile(f) and os.access(f, os.X_OK):
287
subprocess.check_call(['sh', '-c', f])
291
'amqp-relation-changed': amqp_changed,
292
'cluster-relation-joined': cluster_joined,
293
'cluster-relation-changed': cluster_changed,
294
'ha-relation-joined': ha_joined,
295
'ha-relation-changed': ha_changed,
296
'ceph-relation-joined': ceph_joined,
297
'ceph-relation-changed': ceph_changed,
298
'upgrade-charm': upgrade_charm,
299
'config-changed': config_changed
302
utils.do_hooks(hooks)