blob: 98be1844b6c80168bb32b848d3b21b9da4813067 [file] [log] [blame]
Sean Daguee263c822014-12-05 14:25:28 -05001#!/bin/bash
2#
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +09003# lib/rpc_backend
4# Interface for interactig with different rpc backend
5# rpc backend settings
6
7# Dependencies:
Adam Spiers6a5aa7c2013-10-24 11:27:02 +01008#
9# - ``functions`` file
Abhishek Chandad5b74c62014-12-12 02:15:55 +053010# - ``RABBIT_{HOST|PASSWORD|USERID}`` must be defined when RabbitMQ is used
Kenneth Giusti7e58c062014-07-23 16:44:37 -040011# - ``RPC_MESSAGING_PROTOCOL`` option for configuring the messaging protocol
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090012
13# ``stack.sh`` calls the entry points in this order:
14#
Adam Spiers6a5aa7c2013-10-24 11:27:02 +010015# - check_rpc_backend
16# - install_rpc_backend
17# - restart_rpc_backend
18# - iniset_rpc_backend
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090019
20# Save trace setting
21XTRACE=$(set +o | grep xtrace)
22set +o xtrace
23
Sean Dague53753292014-12-04 19:38:15 -050024RPC_MESSAGING_PROTOCOL=${RPC_MESSAGING_PROTOCOL:-0.9}
25
26# TODO(sdague): RPC backend selection is super wonky because we treat
27# messaging server as a service, which it really isn't for multi host
28QPID_HOST=${QPID_HOST:-}
Dean Troyercc6b4432013-04-08 15:38:03 -050029
30# Functions
31# ---------
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090032
Matthieu Huin7a7a4662013-04-15 17:13:41 +020033
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090034# Make sure we only have one rpc backend enabled.
35# Also check the specified rpc backend is available on your platform.
Ian Wienandaee18c72014-02-21 15:35:08 +110036function check_rpc_backend {
Dean Troyer3ef23bc2014-07-25 14:56:22 -050037 local c svc
38
Matthieu Huin7a7a4662013-04-15 17:13:41 +020039 local rpc_needed=1
40 # We rely on the fact that filenames in lib/* match the service names
41 # that can be passed as arguments to is_service_enabled.
42 # We check for a call to iniset_rpc_backend in these files, meaning
43 # the service needs a backend.
Vishvananda Ishaya78a53d92013-05-09 17:20:31 -070044 rpc_candidates=$(grep -rl iniset_rpc_backend $TOP_DIR/lib/ | awk -F/ '{print $NF}')
Matthieu Huin7a7a4662013-04-15 17:13:41 +020045 for c in ${rpc_candidates}; do
46 if is_service_enabled $c; then
47 rpc_needed=0
48 break
49 fi
50 done
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090051 local rpc_backend_cnt=0
52 for svc in qpid zeromq rabbit; do
53 is_service_enabled $svc &&
Dean Troyerffd17682014-08-02 16:07:03 -050054 (( rpc_backend_cnt++ )) || true
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090055 done
56 if [ "$rpc_backend_cnt" -gt 1 ]; then
Daniel P. Berrangec1dbf102015-01-22 14:09:00 +000057 die $LINENO \
58 "Only one rpc backend may be enabled, " \
59 "set only one of 'rabbit', 'qpid', 'zeromq' " \
60 "via ENABLED_SERVICES."
Matthieu Huin7a7a4662013-04-15 17:13:41 +020061 elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
Daniel P. Berrangec1dbf102015-01-22 14:09:00 +000062 die $LINENO \
63 "at least one rpc backend must be enabled, " \
64 "set one of 'rabbit', 'qpid', 'zeromq'" \
65 "via ENABLED_SERVICES."
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090066 fi
67
68 if is_service_enabled qpid && ! qpid_is_supported; then
Nachi Ueno07115eb2013-02-26 12:38:18 -080069 die $LINENO "Qpid support is not available for this version of your distribution."
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090070 fi
71}
72
Dean Troyer995eb922013-03-07 16:11:40 -060073# clean up after rpc backend - eradicate all traces so changing backends
74# produces a clean switch
75function cleanup_rpc_backend {
76 if is_service_enabled rabbit; then
77 # Obliterate rabbitmq-server
78 uninstall_package rabbitmq-server
DennyZhang557744f2013-10-14 09:50:13 -050079 sudo killall epmd || sudo killall -9 epmd
Dean Troyer995eb922013-03-07 16:11:40 -060080 if is_ubuntu; then
81 # And the Erlang runtime too
Sahid Orentino Ferdjaouie9648272014-02-23 18:55:51 +010082 apt_get purge -y erlang*
Dean Troyer995eb922013-03-07 16:11:40 -060083 fi
84 elif is_service_enabled qpid; then
85 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +080086 uninstall_package qpid-cpp-server
Dean Troyer995eb922013-03-07 16:11:40 -060087 elif is_ubuntu; then
88 uninstall_package qpidd
89 else
90 exit_distro_not_supported "qpid installation"
91 fi
92 elif is_service_enabled zeromq; then
93 if is_fedora; then
Li Mad3ca1412014-12-21 23:36:43 -080094 uninstall_package zeromq python-zmq
95 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
96 uninstall_package redis python-redis
97 fi
Dean Troyer995eb922013-03-07 16:11:40 -060098 elif is_ubuntu; then
Li Mad3ca1412014-12-21 23:36:43 -080099 uninstall_package libzmq1 python-zmq
100 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
101 uninstall_package redis-server python-redis
102 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600103 elif is_suse; then
Li Mad3ca1412014-12-21 23:36:43 -0800104 uninstall_package libzmq1 python-pyzmq
105 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
106 uninstall_package redis python-redis
107 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600108 else
109 exit_distro_not_supported "zeromq installation"
110 fi
111 fi
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400112
113 # Remove the AMQP 1.0 messaging libraries
114 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
115 if is_fedora; then
116 uninstall_package qpid-proton-c-devel
117 uninstall_package python-qpid-proton
118 fi
119 # TODO(kgiusti) ubuntu cleanup
120 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600121}
122
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900123# install rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100124function install_rpc_backend {
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400125 # Regardless of the broker used, if AMQP 1.0 is configured load
126 # the necessary messaging client libraries for oslo.messaging
127 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
128 if is_fedora; then
129 install_package qpid-proton-c-devel
130 install_package python-qpid-proton
131 elif is_ubuntu; then
132 # TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
133 # are not yet in the ubuntu repos. Enable these installs
134 # once they are present:
135 #install_package libqpid-proton2-dev
136 #install_package python-qpid-proton
137 # Also add 'uninstall' directives in cleanup_rpc_backend()!
138 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
139 else
140 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
141 fi
142 # Install pyngus client API
143 # TODO(kgiusti) can remove once python qpid bindings are
144 # available on all supported platforms _and_ pyngus is added
145 # to the requirements.txt file in oslo.messaging
146 pip_install pyngus
147 fi
148
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900149 if is_service_enabled rabbit; then
150 # Install rabbitmq-server
Ian Wienand7ccf4e02014-07-23 14:24:11 +1000151 install_package rabbitmq-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900152 elif is_service_enabled qpid; then
153 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +0800154 install_package qpid-cpp-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900155 elif is_ubuntu; then
156 install_package qpidd
157 else
158 exit_distro_not_supported "qpid installation"
159 fi
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400160 _configure_qpid
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900161 elif is_service_enabled zeromq; then
Eric Windisch800bf382013-05-24 11:21:11 -0400162 # NOTE(ewindisch): Redis is not strictly necessary
163 # but there is a matchmaker driver that works
164 # really well & out of the box for multi-node.
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900165 if is_fedora; then
Li Mad3ca1412014-12-21 23:36:43 -0800166 install_package zeromq python-zmq
167 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
168 install_package redis python-redis
169 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900170 elif is_ubuntu; then
Li Mad3ca1412014-12-21 23:36:43 -0800171 install_package libzmq1 python-zmq
172 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
173 install_package redis-server python-redis
174 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900175 elif is_suse; then
Li Mad3ca1412014-12-21 23:36:43 -0800176 install_package libzmq1 python-pyzmq
177 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
178 install_package redis python-redis
179 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900180 else
181 exit_distro_not_supported "zeromq installation"
182 fi
Vincent Hou93a7a502013-09-27 06:16:54 -0400183 # Necessary directory for socket location.
184 sudo mkdir -p /var/run/openstack
185 sudo chown $STACK_USER /var/run/openstack
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900186 fi
Kenneth Giustia1875b72014-09-15 14:21:55 -0400187
188 # If using the QPID broker, install the QPID python client API
189 if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
190 install_package python-qpid
191 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900192}
193
194# restart the rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100195function restart_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900196 if is_service_enabled rabbit; then
197 # Start rabbitmq-server
198 echo_summary "Starting RabbitMQ"
Ben Nemecec5918f2014-01-30 16:07:23 +0000199 # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
200 # the fact that sometimes it fails to start properly.
Ian Wienand64b56a52014-12-16 09:53:36 +1100201 # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1144100
Dean Troyer3ef23bc2014-07-25 14:56:22 -0500202 local i
Ben Nemecec5918f2014-01-30 16:07:23 +0000203 for i in `seq 10`; do
Ian Wienand64b56a52014-12-16 09:53:36 +1100204 local rc=0
205
206 [[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
207
Ben Nemecec5918f2014-01-30 16:07:23 +0000208 if is_fedora || is_suse; then
209 # service is not started by default
210 restart_service rabbitmq-server
211 fi
Ian Wienand64b56a52014-12-16 09:53:36 +1100212
213 rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD" || rc=$?
214 if [ $rc -ne 0 ]; then
215 continue
216 fi
217
Ben Nemecec5918f2014-01-30 16:07:23 +0000218 # change the rabbit password since the default is "guest"
Ian Wienand64b56a52014-12-16 09:53:36 +1100219 sudo rabbitmqctl change_password \
220 $RABBIT_USERID $RABBIT_PASSWORD || rc=$?
221 if [ $rc -ne 0 ]; then
222 continue;
223 fi
224
225 break
Ben Nemecec5918f2014-01-30 16:07:23 +0000226 done
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000227 if is_service_enabled n-cell; then
228 # Add partitioned access for the child cell
229 if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
230 sudo rabbitmqctl add_vhost child_cell
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530231 sudo rabbitmqctl set_permissions -p child_cell $RABBIT_USERID ".*" ".*" ".*"
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000232 fi
233 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900234 elif is_service_enabled qpid; then
235 echo_summary "Starting qpid"
236 restart_service qpidd
237 fi
238}
239
240# iniset cofiguration
Ian Wienandaee18c72014-02-21 15:35:08 +1100241function iniset_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900242 local package=$1
243 local file=$2
244 local section=$3
245 if is_service_enabled zeromq; then
Li Mace1524d2014-12-21 00:46:34 -0800246 iniset $file $section rpc_backend "zmq"
Eric Windisch800bf382013-05-24 11:21:11 -0400247 iniset $file $section rpc_zmq_matchmaker \
Li Mace1524d2014-12-21 00:46:34 -0800248 oslo.messaging._drivers.matchmaker_redis.MatchMakerRedis
Eric Windisch800bf382013-05-24 11:21:11 -0400249 # Set MATCHMAKER_REDIS_HOST if running multi-node.
250 MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
251 iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
Jason Dillaman056df822013-07-01 08:52:13 -0400252 elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400253 # For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
254 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
255 iniset $file $section rpc_backend "amqp"
256 else
257 iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
258 fi
Attila Fazekasa3dc3992013-07-11 11:26:35 +0200259 iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400260 if [ -n "$QPID_USERNAME" ]; then
261 iniset $file $section qpid_username $QPID_USERNAME
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000262 iniset $file $section qpid_password $QPID_PASSWORD
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000263 fi
jiajun xu4a30b842013-01-22 11:49:03 +0800264 elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900265 iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_kombu
Nicolas Simonds8f084c62014-02-28 17:01:41 -0800266 iniset $file $section rabbit_hosts $RABBIT_HOST
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900267 iniset $file $section rabbit_password $RABBIT_PASSWORD
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530268 iniset $file $section rabbit_userid $RABBIT_USERID
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900269 fi
270}
271
272# Check if qpid can be used on the current distro.
273# qpid_is_supported
Ian Wienandaee18c72014-02-21 15:35:08 +1100274function qpid_is_supported {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900275 if [[ -z "$DISTRO" ]]; then
276 GetDistro
277 fi
278
Sean Dague2bb483d2014-01-03 09:41:27 -0500279 # Qpid is not in openSUSE
280 ( ! is_suse )
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900281}
282
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530283function rabbit_setuser {
284 local user="$1" pass="$2" found="" out=""
285 out=$(sudo rabbitmqctl list_users) ||
286 { echo "failed to list users" 1>&2; return 1; }
287 found=$(echo "$out" | awk '$1 == user { print $1 }' "user=$user")
288 if [ "$found" = "$user" ]; then
289 sudo rabbitmqctl change_password "$user" "$pass" ||
290 { echo "failed changing pass for '$user'" 1>&2; return 1; }
291 else
292 sudo rabbitmqctl add_user "$user" "$pass" ||
293 { echo "failed changing pass for $user"; return 1; }
294 fi
295 sudo rabbitmqctl set_permissions "$user" ".*" ".*" ".*"
296}
297
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400298# Set up the various configuration files used by the qpidd broker
299function _configure_qpid {
300
301 # the location of the configuration files have changed since qpidd 0.14
302 local qpid_conf_file
303 if [ -e /etc/qpid/qpidd.conf ]; then
304 qpid_conf_file=/etc/qpid/qpidd.conf
305 elif [ -e /etc/qpidd.conf ]; then
306 qpid_conf_file=/etc/qpidd.conf
307 else
308 exit_distro_not_supported "qpidd.conf file not found!"
309 fi
310
311 # force the ACL file to a known location
312 local qpid_acl_file=/etc/qpid/qpidd.acl
313 if [ ! -e $qpid_acl_file ]; then
314 sudo mkdir -p -m 755 `dirname $qpid_acl_file`
315 sudo touch $qpid_acl_file
316 sudo chmod o+r $qpid_acl_file
317 fi
318 sudo sed -i.bak '/^acl-file=/d' $qpid_conf_file
319 echo "acl-file=$qpid_acl_file" | sudo tee --append $qpid_conf_file
320
321 sudo sed -i '/^auth=/d' $qpid_conf_file
322 if [ -z "$QPID_USERNAME" ]; then
323 # no QPID user configured, so disable authentication
324 # and access control
325 echo "auth=no" | sudo tee --append $qpid_conf_file
326 cat <<EOF | sudo tee $qpid_acl_file
327acl allow all all
328EOF
329 else
330 # Configure qpidd to use PLAIN authentication, and add
331 # QPID_USERNAME to the ACL:
332 echo "auth=yes" | sudo tee --append $qpid_conf_file
333 if [ -z "$QPID_PASSWORD" ]; then
334 read_password QPID_PASSWORD "ENTER A PASSWORD FOR QPID USER $QPID_USERNAME"
335 fi
336 # Create ACL to allow $QPID_USERNAME full access
337 cat <<EOF | sudo tee $qpid_acl_file
338group admin ${QPID_USERNAME}@QPID
339acl allow admin all
340acl deny all all
341EOF
342 # Add user to SASL database
343 if is_ubuntu; then
344 install_package sasl2-bin
345 elif is_fedora; then
346 install_package cyrus-sasl-lib
347 fi
348 local sasl_conf_file=/etc/sasl2/qpidd.conf
349 sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
350 local sasl_db=`sudo grep sasldb_path $sasl_conf_file | cut -f 2 -d ":" | tr -d [:blank:]`
351 if [ ! -e $sasl_db ]; then
352 sudo mkdir -p -m 755 `dirname $sasl_db`
353 fi
354 echo $QPID_PASSWORD | sudo saslpasswd2 -c -p -f $sasl_db -u QPID $QPID_USERNAME
355 sudo chmod o+r $sasl_db
356 fi
357
358 # If AMQP 1.0 is specified, ensure that the version of the
359 # broker can support AMQP 1.0 and configure the queue and
360 # topic address patterns used by oslo.messaging.
361 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
362 QPIDD=$(type -p qpidd)
363 if ! $QPIDD --help | grep -q "queue-patterns"; then
364 exit_distro_not_supported "qpidd with AMQP 1.0 support"
365 fi
366 if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
367 cat <<EOF | sudo tee --append $qpid_conf_file
368queue-patterns=exclusive
369queue-patterns=unicast
370topic-patterns=broadcast
371EOF
372 fi
373 fi
374}
Dean Troyercc6b4432013-04-08 15:38:03 -0500375
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900376# Restore xtrace
377$XTRACE
Sean Dague584d90e2013-03-29 14:34:53 -0400378
Adam Spiers6a5aa7c2013-10-24 11:27:02 +0100379# Tell emacs to use shell-script-mode
380## Local variables:
381## mode: shell-script
382## End: