
This change adds the RPC_MESSAGING_PROTOCOL configuration option that selects the messaging protocol that is used by the RPC backend and client. Some brokers can support different kinds of 'on the wire' messaging protocols. Qpid, for example, supports both AMQP 0-10 (the default), and AMQP 1.0. Use the RPC_MESSAGING_PROTOCOL configuration variable to override the default protocol for those brokers that support multiple protocol options. This new option is necessary in order to enable the new AMQP 1.0 oslo.messaging transport as described in the blueprint. Note well: currently this AMQP 1.0 functionality is only available on fedora 19+ platforms. Support is WIP on ubuntu/debian and rhel/centos 7. Enabling the RPC_MESSAGING_PROTOCOL option on an unsupported platform will cause devstack to exit with an approriate error message. Change-Id: Ib8dea59922844e87d6c947b5dca557f5b5fc1160 Implements: blueprint amqp10-driver-implementation
269 lines
9.7 KiB
Plaintext
269 lines
9.7 KiB
Plaintext
# lib/rpc_backend
|
|
# Interface for interactig with different rpc backend
|
|
# rpc backend settings
|
|
|
|
# Dependencies:
|
|
#
|
|
# - ``functions`` file
|
|
# - ``RABBIT_{HOST|PASSWORD}`` must be defined when RabbitMQ is used
|
|
# - ``RPC_MESSAGING_PROTOCOL`` option for configuring the messaging protocol
|
|
|
|
# ``stack.sh`` calls the entry points in this order:
|
|
#
|
|
# - check_rpc_backend
|
|
# - install_rpc_backend
|
|
# - restart_rpc_backend
|
|
# - iniset_rpc_backend
|
|
|
|
# Save trace setting
|
|
XTRACE=$(set +o | grep xtrace)
|
|
set +o xtrace
|
|
|
|
|
|
# Functions
|
|
# ---------
|
|
|
|
|
|
# Make sure we only have one rpc backend enabled.
|
|
# Also check the specified rpc backend is available on your platform.
|
|
function check_rpc_backend {
|
|
local c svc
|
|
|
|
local rpc_needed=1
|
|
# We rely on the fact that filenames in lib/* match the service names
|
|
# that can be passed as arguments to is_service_enabled.
|
|
# We check for a call to iniset_rpc_backend in these files, meaning
|
|
# the service needs a backend.
|
|
rpc_candidates=$(grep -rl iniset_rpc_backend $TOP_DIR/lib/ | awk -F/ '{print $NF}')
|
|
for c in ${rpc_candidates}; do
|
|
if is_service_enabled $c; then
|
|
rpc_needed=0
|
|
break
|
|
fi
|
|
done
|
|
local rpc_backend_cnt=0
|
|
for svc in qpid zeromq rabbit; do
|
|
is_service_enabled $svc &&
|
|
((rpc_backend_cnt++))
|
|
done
|
|
if [ "$rpc_backend_cnt" -gt 1 ]; then
|
|
echo "ERROR: only one rpc backend may be enabled,"
|
|
echo " set only one of 'rabbit', 'qpid', 'zeromq'"
|
|
echo " via ENABLED_SERVICES."
|
|
elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
|
|
echo "ERROR: at least one rpc backend must be enabled,"
|
|
echo " set one of 'rabbit', 'qpid', 'zeromq'"
|
|
echo " via ENABLED_SERVICES."
|
|
fi
|
|
|
|
if is_service_enabled qpid && ! qpid_is_supported; then
|
|
die $LINENO "Qpid support is not available for this version of your distribution."
|
|
fi
|
|
}
|
|
|
|
# clean up after rpc backend - eradicate all traces so changing backends
|
|
# produces a clean switch
|
|
function cleanup_rpc_backend {
|
|
if is_service_enabled rabbit; then
|
|
# Obliterate rabbitmq-server
|
|
uninstall_package rabbitmq-server
|
|
sudo killall epmd || sudo killall -9 epmd
|
|
if is_ubuntu; then
|
|
# And the Erlang runtime too
|
|
apt_get purge -y erlang*
|
|
fi
|
|
elif is_service_enabled qpid; then
|
|
if is_fedora; then
|
|
uninstall_package qpid-cpp-server
|
|
elif is_ubuntu; then
|
|
uninstall_package qpidd
|
|
else
|
|
exit_distro_not_supported "qpid installation"
|
|
fi
|
|
elif is_service_enabled zeromq; then
|
|
if is_fedora; then
|
|
uninstall_package zeromq python-zmq redis
|
|
elif is_ubuntu; then
|
|
uninstall_package libzmq1 python-zmq redis-server
|
|
elif is_suse; then
|
|
uninstall_package libzmq1 python-pyzmq redis
|
|
else
|
|
exit_distro_not_supported "zeromq installation"
|
|
fi
|
|
fi
|
|
|
|
# Remove the AMQP 1.0 messaging libraries
|
|
if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
|
|
if is_fedora; then
|
|
uninstall_package qpid-proton-c-devel
|
|
uninstall_package python-qpid-proton
|
|
fi
|
|
# TODO(kgiusti) ubuntu cleanup
|
|
fi
|
|
}
|
|
|
|
# install rpc backend
|
|
function install_rpc_backend {
|
|
# Regardless of the broker used, if AMQP 1.0 is configured load
|
|
# the necessary messaging client libraries for oslo.messaging
|
|
if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
|
|
if is_fedora; then
|
|
install_package qpid-proton-c-devel
|
|
install_package python-qpid-proton
|
|
elif is_ubuntu; then
|
|
# TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
|
|
# are not yet in the ubuntu repos. Enable these installs
|
|
# once they are present:
|
|
#install_package libqpid-proton2-dev
|
|
#install_package python-qpid-proton
|
|
# Also add 'uninstall' directives in cleanup_rpc_backend()!
|
|
exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
|
|
else
|
|
exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
|
|
fi
|
|
# Install pyngus client API
|
|
# TODO(kgiusti) can remove once python qpid bindings are
|
|
# available on all supported platforms _and_ pyngus is added
|
|
# to the requirements.txt file in oslo.messaging
|
|
pip_install pyngus
|
|
fi
|
|
|
|
if is_service_enabled rabbit; then
|
|
# Install rabbitmq-server
|
|
install_package rabbitmq-server
|
|
elif is_service_enabled qpid; then
|
|
local qpid_conf_file=/etc/qpid/qpidd.conf
|
|
if is_fedora; then
|
|
install_package qpid-cpp-server
|
|
if [[ $DISTRO =~ (rhel6) ]]; then
|
|
qpid_conf_file=/etc/qpidd.conf
|
|
# RHEL6 leaves "auth=yes" in /etc/qpidd.conf, it needs to
|
|
# be no or you get GSS authentication errors as it
|
|
# attempts to default to this.
|
|
sudo sed -i.bak 's/^auth=yes$/auth=no/' $qpid_conf_file
|
|
fi
|
|
elif is_ubuntu; then
|
|
install_package qpidd
|
|
sudo sed -i '/PLAIN/!s/mech_list: /mech_list: PLAIN /' /etc/sasl2/qpidd.conf
|
|
sudo chmod o+r /etc/qpid/qpidd.sasldb
|
|
else
|
|
exit_distro_not_supported "qpid installation"
|
|
fi
|
|
# If AMQP 1.0 is specified, ensure that the version of the
|
|
# broker can support AMQP 1.0 and configure the queue and
|
|
# topic address patterns used by oslo.messaging.
|
|
if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
|
|
QPIDD=$(type -p qpidd)
|
|
if ! $QPIDD --help | grep -q "queue-patterns"; then
|
|
exit_distro_not_supported "qpidd with AMQP 1.0 support"
|
|
fi
|
|
if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
|
|
cat <<EOF | sudo tee --append $qpid_conf_file
|
|
queue-patterns=exclusive
|
|
queue-patterns=unicast
|
|
topic-patterns=broadcast
|
|
EOF
|
|
fi
|
|
fi
|
|
elif is_service_enabled zeromq; then
|
|
# NOTE(ewindisch): Redis is not strictly necessary
|
|
# but there is a matchmaker driver that works
|
|
# really well & out of the box for multi-node.
|
|
if is_fedora; then
|
|
install_package zeromq python-zmq redis
|
|
elif is_ubuntu; then
|
|
install_package libzmq1 python-zmq redis-server
|
|
elif is_suse; then
|
|
install_package libzmq1 python-pyzmq redis
|
|
else
|
|
exit_distro_not_supported "zeromq installation"
|
|
fi
|
|
# Necessary directory for socket location.
|
|
sudo mkdir -p /var/run/openstack
|
|
sudo chown $STACK_USER /var/run/openstack
|
|
fi
|
|
}
|
|
|
|
# restart the rpc backend
|
|
function restart_rpc_backend {
|
|
if is_service_enabled rabbit; then
|
|
# Start rabbitmq-server
|
|
echo_summary "Starting RabbitMQ"
|
|
# NOTE(bnemec): Retry initial rabbitmq configuration to deal with
|
|
# the fact that sometimes it fails to start properly.
|
|
# Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1059028
|
|
local i
|
|
for i in `seq 10`; do
|
|
if is_fedora || is_suse; then
|
|
# service is not started by default
|
|
restart_service rabbitmq-server
|
|
fi
|
|
# change the rabbit password since the default is "guest"
|
|
sudo rabbitmqctl change_password guest $RABBIT_PASSWORD && break
|
|
[[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
|
|
done
|
|
if is_service_enabled n-cell; then
|
|
# Add partitioned access for the child cell
|
|
if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
|
|
sudo rabbitmqctl add_vhost child_cell
|
|
sudo rabbitmqctl set_permissions -p child_cell guest ".*" ".*" ".*"
|
|
fi
|
|
fi
|
|
elif is_service_enabled qpid; then
|
|
echo_summary "Starting qpid"
|
|
restart_service qpidd
|
|
fi
|
|
}
|
|
|
|
# iniset cofiguration
|
|
function iniset_rpc_backend {
|
|
local package=$1
|
|
local file=$2
|
|
local section=$3
|
|
if is_service_enabled zeromq; then
|
|
iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_zmq
|
|
iniset $file $section rpc_zmq_matchmaker \
|
|
${package}.openstack.common.rpc.matchmaker_redis.MatchMakerRedis
|
|
# Set MATCHMAKER_REDIS_HOST if running multi-node.
|
|
MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
|
|
iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
|
|
elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
|
|
# For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
|
|
if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
|
|
iniset $file $section rpc_backend "amqp"
|
|
else
|
|
iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
|
|
fi
|
|
iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
|
|
if is_ubuntu; then
|
|
QPID_PASSWORD=`sudo strings /etc/qpid/qpidd.sasldb | grep -B1 admin | head -1`
|
|
iniset $file $section qpid_password $QPID_PASSWORD
|
|
iniset $file $section qpid_username admin
|
|
fi
|
|
elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
|
|
iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_kombu
|
|
iniset $file $section rabbit_hosts $RABBIT_HOST
|
|
iniset $file $section rabbit_password $RABBIT_PASSWORD
|
|
fi
|
|
}
|
|
|
|
# Check if qpid can be used on the current distro.
|
|
# qpid_is_supported
|
|
function qpid_is_supported {
|
|
if [[ -z "$DISTRO" ]]; then
|
|
GetDistro
|
|
fi
|
|
|
|
# Qpid is not in openSUSE
|
|
( ! is_suse )
|
|
}
|
|
|
|
|
|
# Restore xtrace
|
|
$XTRACE
|
|
|
|
# Tell emacs to use shell-script-mode
|
|
## Local variables:
|
|
## mode: shell-script
|
|
## End:
|