Python rewrite.
This commit is contained in:
commit
e53c196e70
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -1 +0,0 @@
|
|||
rabbitmq-relations
|
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -1,70 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
juju-log "rabbitmq-server: Firing config hook"
|
||||
|
||||
export HOME=/root # (HOME is not set on first run)
|
||||
RABBIT_PLUGINS=/usr/lib/rabbitmq/lib/rabbitmq_server-*/sbin/rabbitmq-plugins
|
||||
if [ "`config-get management_plugin`" == "True" ]; then
|
||||
$RABBIT_PLUGINS enable rabbitmq_management
|
||||
open-port 55672/tcp
|
||||
else
|
||||
$RABBIT_PLUGINS disable rabbitmq_management
|
||||
close-port 55672/tcp
|
||||
fi
|
||||
|
||||
ssl_enabled=`config-get ssl_enabled`
|
||||
|
||||
cd /etc/rabbitmq
|
||||
|
||||
new_config=`mktemp /etc/rabbitmq/.rabbitmq.config.XXXXXX`
|
||||
chgrp rabbitmq "$new_config"
|
||||
chmod g+r "$new_config"
|
||||
exec 3> "$new_config"
|
||||
|
||||
cat >&3 <<EOF
|
||||
[
|
||||
{rabbit, [
|
||||
EOF
|
||||
|
||||
ssl_key_file=/etc/rabbitmq/rabbit-server-privkey.pem
|
||||
ssl_cert_file=/etc/rabbitmq/rabbit-server-cert.pem
|
||||
|
||||
if [ "$ssl_enabled" == "True" ]; then
|
||||
umask 027
|
||||
config-get ssl_key > "$ssl_key_file"
|
||||
config-get ssl_cert > "$ssl_cert_file"
|
||||
chgrp rabbitmq "$ssl_key_file" "$ssl_cert_file"
|
||||
if [ ! -s "$ssl_key_file" ]; then
|
||||
juju-log "ssl_key not set - can't configure SSL"
|
||||
exit 0
|
||||
fi
|
||||
if [ ! -s "$ssl_cert_file" ]; then
|
||||
juju-log "ssl_cert not set - can't configure SSL"
|
||||
exit 0
|
||||
fi
|
||||
cat >&3 <<EOF
|
||||
{ssl_listeners, [`config-get ssl_port`]},
|
||||
{ssl_options, [
|
||||
{certfile,"$ssl_cert_file"},
|
||||
{keyfile,"$ssl_key_file"}
|
||||
]},
|
||||
open-port `config-get ssl_port`/tcp
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >&3 <<EOF
|
||||
{tcp_listeners, [5672]}
|
||||
]}
|
||||
].
|
||||
EOF
|
||||
|
||||
exec 3>&-
|
||||
|
||||
if [ -f rabbitmq.config ]; then
|
||||
mv rabbitmq.config{,.bak}
|
||||
fi
|
||||
|
||||
mv "$new_config" rabbitmq.config
|
||||
|
||||
/etc/init.d/rabbitmq-server restart
|
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -1 +1 @@
|
|||
rabbitmq-relations
|
||||
rabbitmq-server-relations.py
|
|
@ -0,0 +1,97 @@
|
|||
import re
|
||||
import subprocess
|
||||
import utils
|
||||
import apt_pkg as apt
|
||||
|
||||
PACKAGES = ['pwgen', 'rabbitmq-server']
|
||||
|
||||
RABBITMQ_CTL = '/usr/sbin/rabbitmqctl'
|
||||
COOKIE_PATH = '/var/lib/rabbitmq/.erlang.cookie'
|
||||
|
||||
def vhost_exists(vhost):
|
||||
cmd = [RABBITMQ_CTL, 'list_vhosts']
|
||||
out = subprocess.check_output(cmd)
|
||||
for line in out.split('\n')[1:]:
|
||||
if line == vhost:
|
||||
utils.juju_log('INFO', 'vhost (%s) already exists.' % vhost)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def create_vhost(vhost):
|
||||
if vhost_exists(vhost):
|
||||
return
|
||||
cmd = [RABBITMQ_CTL, 'add_vhost', vhost]
|
||||
subprocess.check_call(cmd)
|
||||
utils.juju_log('INFO', 'Created new vhost (%s).' % vhost)
|
||||
|
||||
|
||||
def user_exists(user):
|
||||
cmd = [RABBITMQ_CTL, 'list_users']
|
||||
out = subprocess.check_output(cmd)
|
||||
for line in out.split('\n')[1:]:
|
||||
_user = line.split('\t')[0]
|
||||
if _user == user:
|
||||
admin = line.split('\t')[1]
|
||||
return True, (admin == '[administrator]')
|
||||
return False, False
|
||||
|
||||
|
||||
def create_user(user, password, admin=False):
|
||||
exists, is_admin = user_exists(user)
|
||||
|
||||
if not exists:
|
||||
cmd = [RABBITMQ_CTL, 'add_user', user, password]
|
||||
subprocess.check_call(cmd)
|
||||
utils.juju_log('INFO', 'Created new user (%s).' % user)
|
||||
|
||||
if admin == is_admin:
|
||||
return
|
||||
|
||||
if admin:
|
||||
cmd = [RABBITMQ_CTL, 'set_user_tags', user, 'administrator']
|
||||
utils.juju_log('INFO', 'Granting user (%s) admin access.')
|
||||
else:
|
||||
cmd = [RABBITMQ_CTL, 'set_user_tags', user]
|
||||
utils.juju_log('INFO', 'Revoking user (%s) admin access.')
|
||||
|
||||
|
||||
def grant_permissions(user, vhost):
|
||||
cmd = [RABBITMQ_CTL, 'set_permissions', '-p',
|
||||
vhost, user, '.*', '.*', '.*']
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def service(action):
|
||||
cmd = ['service', 'rabbitmq-server', action]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def rabbit_version():
|
||||
apt.init()
|
||||
cache = apt.Cache()
|
||||
pkg = cache['rabbitmq-server']
|
||||
if pkg.current_ver:
|
||||
return apt.upstream_version(pkg.current_ver.ver_str)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def cluster_with(host):
|
||||
utils.juju_log('INFO', 'Clustering with remote rabbit host (%s).' % host)
|
||||
vers = rabbit_version()
|
||||
if vers >= '3.0.1-1':
|
||||
cluster_cmd = 'join_cluster'
|
||||
else:
|
||||
cluster_cmd = 'cluster'
|
||||
out = subprocess.check_output([RABBITMQ_CTL, 'cluster_status'])
|
||||
for line in out.split('\n'):
|
||||
if re.search(host, line):
|
||||
utils.juju_log('INFO', 'Host already clustered with %s.' % host)
|
||||
return
|
||||
cmd = [RABBITMQ_CTL, 'stop_app']
|
||||
subprocess.check_call(cmd)
|
||||
cmd = [RABBITMQ_CTL, cluster_cmd, 'rabbit@%s' % host]
|
||||
subprocess.check_call(cmd)
|
||||
cmd = [RABBITMQ_CTL, 'start_app']
|
||||
subprocess.check_call(cmd)
|
|
@ -1,82 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# rabbitmq-common - common formula shell functions and config variables
|
||||
#
|
||||
# Copyright (C) 2011 Canonical Ltd.
|
||||
# Author: Adam Gandelman <adam.gandelman@canonical.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
|
||||
RABBIT_CTL='rabbitmqctl'
|
||||
|
||||
ERLANG_COOKIE="/var/lib/rabbitmq/.erlang.cookie"
|
||||
|
||||
function user_exists {
|
||||
$RABBIT_CTL list_users | grep -wq "^$1"
|
||||
}
|
||||
|
||||
function user_is_admin {
|
||||
$RABBIT_CTL list_users | grep -w "^$1" | grep -q "administrator"
|
||||
}
|
||||
|
||||
function vhost_exists {
|
||||
$RABBIT_CTL list_vhosts | grep "^$1\$" >/dev/null
|
||||
}
|
||||
|
||||
function create_vhost {
|
||||
juju-log "Creating vhost: $1"
|
||||
$RABBIT_CTL add_vhost "$1"
|
||||
}
|
||||
|
||||
function user_create {
|
||||
local user="$1"
|
||||
local passwd="$2"
|
||||
local vhost="$3"
|
||||
local admin="$4"
|
||||
juju-log "rabbitmq: Creating user $1 (vhost: $3"
|
||||
$RABBIT_CTL add_user "$user" "$passwd" || return 1
|
||||
|
||||
# grant the user all permissions on the default vhost /
|
||||
# TODO: investigate sane permissions
|
||||
juju-log "rabbitmq: Granting permission to $1 on vhost /"
|
||||
$RABBIT_CTL set_permissions -p "$vhost" "$user" ".*" ".*" ".*"
|
||||
|
||||
if [[ "$admin" == "admin" ]] ; then
|
||||
user_is_admin "$user" && return 0
|
||||
juju-log "rabbitmq: Granting user $user admin access"
|
||||
$RABBIT_CTL set_user_tags "$user" administrator || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function rabbit_version {
|
||||
echo "$(dpkg -l | grep rabbitmq-server | awk '{ print $3 }')"
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Description: Query HA interface to determine is cluster is configured
|
||||
# Returns: 0 if configured, 1 if not configured
|
||||
##########################################################################
|
||||
is_clustered() {
|
||||
for r_id in `relation-ids ha`; do
|
||||
for unit in `relation-list -r $r_id`; do
|
||||
clustered=`relation-get -r $r_id clustered $unit`
|
||||
if [ -n "$clustered" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
return 1
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# rabbitmq-relations - relations to be used by formula, referenced
|
||||
# via symlink
|
||||
#
|
||||
# Copyright (C) 2011 Canonical Ltd.
|
||||
# Author: Adam Gandelman <adam.gandelman@canonical.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set -e
|
||||
|
||||
CHARM_DIR=$(dirname $0)
|
||||
ARG0=${0##*/}
|
||||
|
||||
if [[ -e $CHARM_DIR/rabbitmq-common ]] ; then
|
||||
. $CHARM_DIR/rabbitmq-common
|
||||
else
|
||||
juju-log "rabbitmq-server: ERROR Could not load $CHARM_DIR/rabbitmq-common"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
juju-log "rabbitmq-server: Firing hook $ARG0."
|
||||
|
||||
function install_hook() {
|
||||
[[ ! `which pwgen` ]] && apt-get -y install pwgen
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -qqy \
|
||||
install --no-install-recommends rabbitmq-server
|
||||
rc=$?
|
||||
service rabbitmq-server stop
|
||||
open-port 5672/tcp
|
||||
}
|
||||
|
||||
function amqp_changed() {
|
||||
# Connecting clients should request a username and vhost.
|
||||
# In reponse, we generate a password for new users,
|
||||
# grant the user access on the default vhost "/",
|
||||
# and tell it where to reach us.
|
||||
|
||||
# Skip managing rabbit queue config unless we are the
|
||||
# lowest numbered unit in the service cluster.
|
||||
local local_unit_id=$(echo $JUJU_UNIT_NAME | cut -d/ -f2)
|
||||
local remote_unit_id=""
|
||||
for relid in $(relation-ids cluster) ; do
|
||||
for unit in $(relation-list -r "$relid") ; do
|
||||
remote_unit_id="$(echo $unit | cut -d/ -f2)"
|
||||
if [[ "$local_unit_id" -gt "$remote_unit_id" ]]; then
|
||||
juju-log "amqp_changed(): Deferring amqp_changed to leader."
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
local rabbit_user=`relation-get username`
|
||||
local vhost=`relation-get vhost`
|
||||
if [[ -z "$rabbit_user" ]] || [[ -z "$vhost" ]] ; then
|
||||
juju-log "rabbitmq-server: rabbit_user||vhost not yet received from peer."
|
||||
exit 0
|
||||
fi
|
||||
local passwd_file="/var/lib/juju/$rabbit_user.passwd"
|
||||
local password=""
|
||||
if [[ -e $passwd_file ]] ; then
|
||||
password=$(cat $passwd_file)
|
||||
else
|
||||
password=$(pwgen 10 1)
|
||||
echo $password >$passwd_file
|
||||
chmod 0400 $passwd_file
|
||||
fi
|
||||
if ! vhost_exists "$vhost" ; then
|
||||
juju-log "rabbitmq-server: Creating vhost $vhost"
|
||||
create_vhost "$vhost"
|
||||
fi
|
||||
if ! user_exists "$rabbit_user" ; then
|
||||
juju-log "rabbitmq-server: Creating user $rabbit_user"
|
||||
user_create "$rabbit_user" "$password" "$vhost" admin || exit 1
|
||||
else
|
||||
juju-log "rabbitmq-server: user $rabbit_user already exists."
|
||||
fi
|
||||
local remote_host="$(relation-get private-address)"
|
||||
juju-log "rabbitmq-server: Returning credentials for $rabbit_user@$remote_host"
|
||||
relation-set password="$password"
|
||||
|
||||
if is_clustered ; then
|
||||
relation-set clustered="true" vip="$(config-get vip)"
|
||||
fi
|
||||
}
|
||||
|
||||
function cluster_joined {
|
||||
local remote_unit_id=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f2)
|
||||
local local_unit_id=$(echo $JUJU_UNIT_NAME | cut -d/ -f2)
|
||||
[[ $local_unit_id -gt $remote_unit_id ]] && echo "Relation greater" && exit 0
|
||||
if [[ ! -e $ERLANG_COOKIE ]] ; then
|
||||
juju-log "rabbitmq-server: ERROR Could not find cookie at $ERLANG_COOKIE"
|
||||
exit 1
|
||||
fi
|
||||
relation-set cookie="$(cat $ERLANG_COOKIE)" host="$(hostname)"
|
||||
}
|
||||
|
||||
function cluster_changed {
|
||||
local remote_unit_id=$(echo $JUJU_REMOTE_UNIT | cut -d/ -f2)
|
||||
local local_unit_id=$(echo $JUJU_UNIT_NAME | cut -d/ -f2)
|
||||
|
||||
[[ $local_unit_id -lt $remote_unit_id ]] && echo "Relation lesser" && exit 0
|
||||
|
||||
local remote_host=$(relation-get host)
|
||||
local cookie_value=$(relation-get cookie)
|
||||
|
||||
[[ -z "$remote_host" ]] || [[ -z "$cookie_value" ]] && \
|
||||
juju-log "rabbimtq-server: remote_host||cookie_value not yet set." &&
|
||||
exit 0
|
||||
|
||||
# Sync the erlang cookie to that of remote host.
|
||||
service rabbitmq-server stop
|
||||
echo -n "$cookie_value" > $ERLANG_COOKIE
|
||||
service rabbitmq-server start
|
||||
|
||||
# Configure clustering.
|
||||
# rabbitmq apparently does not like FQDNs.
|
||||
local short_host=$(echo $remote_host | sed -e 's/\./ /g' | awk '{ print $1 }')
|
||||
local cur_vers=$(rabbit_version)
|
||||
local cluster_cmd="cluster"
|
||||
if dpkg --compare-versions "$cur_vers" ge "3.0.1-1" ; then
|
||||
cluster_cmd="join_cluster"
|
||||
fi
|
||||
if ! rabbitmqctl cluster_status | grep -q "rabbit@$short_host" ; then
|
||||
juju-log "Clustering with new rabbitmq peer @ $short_host."
|
||||
rabbitmqctl stop_app
|
||||
rabbitmqctl $cluster_cmd rabbit@$short_host
|
||||
rabbitmqctl start_app
|
||||
else
|
||||
juju-log "Already clustered with rabbitmq peer @ $short_host."
|
||||
fi
|
||||
}
|
||||
|
||||
function ha_joined() {
|
||||
local corosync_bindiface=`config-get ha-bindiface`
|
||||
local corosync_mcastport=`config-get ha-mcastport`
|
||||
local vip=`config-get vip`
|
||||
local vip_iface=`config-get vip_iface`
|
||||
local vip_cidr=`config-get vip_cidr`
|
||||
if [ -n "$vip" ] && [ -n "$vip_iface" ] && \
|
||||
[ -n "$vip_cidr" ] && [ -n "$corosync_bindiface" ] && \
|
||||
[ -n "$corosync_mcastport" ]; then
|
||||
# TODO: This feels horrible but the data required by the hacluster
|
||||
# charm is quite complex and is python ast parsed.
|
||||
resources="{
|
||||
'res_rabbitmq_vip':'ocf:heartbeat:IPaddr2'
|
||||
}"
|
||||
resource_params="{
|
||||
'res_rabbitmq_vip': 'params ip=\"$vip\" cidr_netmask=\"$vip_cidr\" nic=\"$vip_iface\"'
|
||||
}"
|
||||
relation-set corosync_bindiface=$corosync_bindiface \
|
||||
corosync_mcastport=$corosync_mcastport \
|
||||
resources="$resources" resource_params="$resource_params"
|
||||
else
|
||||
juju-log "Insufficient configuration data to configure hacluster"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function ha_changed() {
|
||||
# we may now be clustered, advertise our vip to clients if so.
|
||||
if is_clustered ; then
|
||||
local vip="$(config-get vip)"
|
||||
juju-log "$CHARM - ha_changed(): We are now HA clustered. "\
|
||||
"Advertising our VIP ($vip) to all AMQP clients."
|
||||
for rid in $(relation-ids amqp) ; do
|
||||
relation-set -r $rid clustered="true" vip="$vip"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
case $ARG0 in
|
||||
"install") install_hook ;;
|
||||
"start") service rabbitmq-server status || service rabbitmq-server start ;;
|
||||
"stop") service rabbitmq-server status && service rabbitmq-server stop ;;
|
||||
"amqp-relation-joined") exit 0 ;;
|
||||
"amqp-relation-changed") amqp_changed ;;
|
||||
"cluster-relation-joined") cluster_joined ;;
|
||||
"cluster-relation-changed") cluster_changed ;;
|
||||
"ha-relation-joined") ha_joined ;;
|
||||
"ha-relation-changed") ha_changed ;;
|
||||
esac
|
||||
|
||||
rc=$?
|
||||
juju-log "rabbitmq-server: Hook $ARG0 complete. Exiting $rc"
|
||||
exit $rc
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import rabbit_utils as rabbit
|
||||
import utils
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
def install():
|
||||
utils.install(*rabbit.PACKAGES)
|
||||
utils.expose(5672)
|
||||
|
||||
def amqp_changed():
|
||||
l_unit_no=os.getenv('JUJU_UNIT_NAME').split('/')[1]
|
||||
r_unit_no=None
|
||||
for rid in utils.relation_ids('cluster'):
|
||||
for unit in utils.relation_list(rid):
|
||||
r_unit_no = unit.split('/')[1]
|
||||
if l_unit_no > r_unit_no:
|
||||
msg = 'amqp_changed(): Deferring amqp_changed to leader.'
|
||||
utils.juju_log('INFO', msg)
|
||||
return
|
||||
|
||||
rabbit_user=utils.relation_get('username')
|
||||
vhost=utils.relation_get('vhost')
|
||||
if None in [rabbit_user, vhost]:
|
||||
utils.juju_log('INFO', 'amqp_changed(): Relation not ready.')
|
||||
return
|
||||
|
||||
password_file = '/var/lib/juju/%s.passwd' % rabbit_user
|
||||
if os.path.exists(password_file):
|
||||
password = open(password_file).read().strip()
|
||||
else:
|
||||
cmd = ['pwgen', '64', '1']
|
||||
password = subprocess.check_output(cmd).strip()
|
||||
with open(password_file, 'wb') as out:
|
||||
out.write(password)
|
||||
|
||||
rabbit.create_vhost(vhost)
|
||||
rabbit.create_user(rabbit_user, password)
|
||||
rabbit.grant_permissions(rabbit_user, vhost)
|
||||
|
||||
relation_settings = {
|
||||
'password': password
|
||||
}
|
||||
if utils.is_clustered():
|
||||
relation_settings['clustered'] = 'true'
|
||||
relation_settings['vip'] = utils.config_get('vip')
|
||||
utils.relation_set(**relation_settings)
|
||||
|
||||
|
||||
def cluster_joined():
|
||||
l_unit_no = os.getenv('JUJU_UNIT_NAME').split('/')[1]
|
||||
r_unit_no = os.getenv('JUJU_REMOTE_UNIT').split('/')[1]
|
||||
if l_unit_no > r_unit_no:
|
||||
utils.juju_log('INFO', 'cluster_joined: Relation greater.')
|
||||
return
|
||||
rabbit.COOKIE_PATH = '/var/lib/rabbitmq/.erlang.cookie'
|
||||
if not os.path.isfile(rabbit.COOKIE_PATH):
|
||||
utils.juju_log('ERROR', 'erlang cookie missing from %s' %\
|
||||
rabbit.COOKIE_PATH)
|
||||
cookie = open(rabbit.COOKIE_PATH, 'r').read().strip()
|
||||
local_hostname = subprocess.check_output(['hostname']).strip()
|
||||
utils.relation_set(cookie=cookie, host=local_hostname)
|
||||
|
||||
|
||||
def cluster_changed():
|
||||
l_unit_no = os.getenv('JUJU_UNIT_NAME').split('/')[1]
|
||||
r_unit_no = os.getenv('JUJU_REMOTE_UNIT').split('/')[1]
|
||||
if l_unit_no < r_unit_no:
|
||||
utils.juju_log('INFO', 'cluster_joined: Relation lesser.')
|
||||
return
|
||||
|
||||
remote_host = utils.relation_get('host')
|
||||
cookie = utils.relation_get('cookie')
|
||||
if None in [remote_host, cookie]:
|
||||
utils.juju_log('INFO',
|
||||
'cluster_joined: remote_host|cookie not yet set.')
|
||||
return
|
||||
|
||||
if open(rabbit.COOKIE_PATH, 'r').read().strip() == cookie:
|
||||
utils.juju_log('INFO', 'Cookie already synchronized with peer.')
|
||||
return
|
||||
|
||||
utils.juju_log('INFO', 'Synchronizing erlang cookie from peer.')
|
||||
rabbit.service('stop')
|
||||
with open(rabbit.COOKIE_PATH, 'wb') as out:
|
||||
out.write(cookie)
|
||||
rabbit.service('start')
|
||||
rabbit.cluster_with(remote_host)
|
||||
|
||||
|
||||
def ha_joined():
|
||||
config = {}
|
||||
corosync_bindiface = utils.config_get('ha-bindiface')
|
||||
corosync_mcastport = utils.config_get('ha-mcastport')
|
||||
vip = utils.config_get('vip')
|
||||
vip_iface = utils.config_get('vip_iface')
|
||||
vip_cidr = utils.config_get('vip_cidr')
|
||||
if None in [corosync_bindiface, corosync_mcastport, vip, vip_iface,
|
||||
vip_cidr]:
|
||||
utils.juju_log('ERROR', 'Insufficient configuration data to '\
|
||||
'configure hacluster.')
|
||||
sys.exit(1)
|
||||
|
||||
relation_settings = {}
|
||||
relation_settings['corosync_bindiface'] = corosync_bindiface
|
||||
relation_settings['corosync_mcastport'] = corosync_mcastport
|
||||
relation_settings['resources'] = {
|
||||
'res_rabbitmq_vip': 'ocf:heartbeat:IPaddr2'
|
||||
}
|
||||
relation_settings['resource_params'] = {
|
||||
'res_rabbitmq_vip': ('params ip="%s" cider_netmask="%s" nic="%s"' %\
|
||||
(vip, vip_cidr, vip_iface))
|
||||
}
|
||||
utils.relation_set(**relation_settings)
|
||||
|
||||
|
||||
def ha_changed():
|
||||
if not utils.is_clustered:
|
||||
return
|
||||
vip = utils.config_get('vip')
|
||||
utils.juju_log('INFO', 'ha_changed(): We are now HA clustered. '\
|
||||
'Advertising our VIP (%s) to all AMQP clients.' %\
|
||||
vip)
|
||||
relation_settings = {'vip': vip, 'clustered': 'true'}
|
||||
for rid in utils.relation_ids('amqp'):
|
||||
relation_settings['rid'] = rid
|
||||
utils.relation_set(**relation_settings)
|
||||
|
||||
|
||||
hooks = {
|
||||
'install': install,
|
||||
'amqp-relation-changed': amqp_changed,
|
||||
'cluster-relation-joined': cluster_joined,
|
||||
'cluster-relation-changed': cluster_changed,
|
||||
'ha-relation-joined': ha_joined,
|
||||
'ha-relation-changed': ha_changed,
|
||||
}
|
||||
|
||||
utils.do_hooks(hooks)
|
|
@ -1 +0,0 @@
|
|||
rabbitmq-relations
|
|
@ -1 +0,0 @@
|
|||
rabbitmq-relations
|
|
@ -0,0 +1,147 @@
|
|||
|
||||
#
|
||||
# Copyright 2012 Canonical Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# James Page <james.page@ubuntu.com>
|
||||
# Paul Collins <paul.collins@canonical.com>
|
||||
#
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import socket
|
||||
import sys
|
||||
|
||||
|
||||
def do_hooks(hooks):
|
||||
hook = os.path.basename(sys.argv[0])
|
||||
|
||||
try:
|
||||
hook_func = hooks[hook]
|
||||
except KeyError:
|
||||
juju_log('INFO',
|
||||
"This charm doesn't know how to handle '{}'.".format(hook))
|
||||
else:
|
||||
hook_func()
|
||||
|
||||
|
||||
def install(*pkgs):
|
||||
cmd = [
|
||||
'apt-get',
|
||||
'-y',
|
||||
'install'
|
||||
]
|
||||
for pkg in pkgs:
|
||||
cmd.append(pkg)
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
TEMPLATES_DIR = 'templates'
|
||||
|
||||
|
||||
def expose(port, protocol='TCP'):
|
||||
cmd = [
|
||||
'open-port',
|
||||
'{}/{}'.format(port, protocol)
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def juju_log(severity, message):
|
||||
cmd = [
|
||||
'juju-log',
|
||||
'--log-level', severity,
|
||||
message
|
||||
]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def relation_ids(relation):
|
||||
cmd = [
|
||||
'relation-ids',
|
||||
relation
|
||||
]
|
||||
return subprocess.check_output(cmd).split() # IGNORE:E1103
|
||||
|
||||
|
||||
def relation_list(rid):
|
||||
cmd = [
|
||||
'relation-list',
|
||||
'-r', rid,
|
||||
]
|
||||
return subprocess.check_output(cmd).split() # IGNORE:E1103
|
||||
|
||||
|
||||
def relation_get(attribute, unit=None, rid=None):
|
||||
cmd = [
|
||||
'relation-get',
|
||||
]
|
||||
if rid:
|
||||
cmd.append('-r')
|
||||
cmd.append(rid)
|
||||
cmd.append(attribute)
|
||||
if unit:
|
||||
cmd.append(unit)
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def relation_set(**kwargs):
|
||||
cmd = [
|
||||
'relation-set'
|
||||
]
|
||||
args = []
|
||||
for k, v in kwargs.items():
|
||||
if k == 'rid':
|
||||
cmd.append('-r')
|
||||
cmd.append(v)
|
||||
else:
|
||||
args.append('{}={}'.format(k, v))
|
||||
cmd += args
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def unit_get(attribute):
|
||||
cmd = [
|
||||
'unit-get',
|
||||
attribute
|
||||
]
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def config_get(attribute):
|
||||
cmd = [
|
||||
'config-get',
|
||||
attribute
|
||||
]
|
||||
value = subprocess.check_output(cmd).strip() # IGNORE:E1103
|
||||
if value == "":
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def is_clustered():
|
||||
for r_id in (relation_ids('ha') or []):
|
||||
for unit in (relation_list(r_id) or []):
|
||||
relation_data = \
|
||||
relation_get_dict(relation_id=r_id,
|
||||
remote_unit=unit)
|
||||
if 'clustered' in relation_data:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_leader():
|
||||
status = execute('crm resource show res_ks_vip', echo=True)[0].strip()
|
||||
hostname = execute('hostname', echo=True)[0].strip()
|
||||
if hostname in status:
|
||||
return True
|
||||
else:
|
||||
return False
|
Loading…
Reference in New Issue