blob: 3d4ef762a7a59449b5285657553235893aa46afc [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
57 echo "ERROR: only one rpc backend may be enabled,"
58 echo " set only one of 'rabbit', 'qpid', 'zeromq'"
59 echo " via ENABLED_SERVICES."
Matthieu Huin7a7a4662013-04-15 17:13:41 +020060 elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090061 echo "ERROR: at least one rpc backend must be enabled,"
62 echo " set one of 'rabbit', 'qpid', 'zeromq'"
63 echo " via ENABLED_SERVICES."
64 fi
65
66 if is_service_enabled qpid && ! qpid_is_supported; then
Nachi Ueno07115eb2013-02-26 12:38:18 -080067 die $LINENO "Qpid support is not available for this version of your distribution."
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090068 fi
69}
70
Dean Troyer995eb922013-03-07 16:11:40 -060071# clean up after rpc backend - eradicate all traces so changing backends
72# produces a clean switch
73function cleanup_rpc_backend {
74 if is_service_enabled rabbit; then
75 # Obliterate rabbitmq-server
76 uninstall_package rabbitmq-server
Sean Dague9a413ab2015-02-04 12:44:18 -050077 # in case it's not actually running, /bin/true at the end
78 sudo killall epmd || sudo killall -9 epmd || /bin/true
Dean Troyer995eb922013-03-07 16:11:40 -060079 if is_ubuntu; then
80 # And the Erlang runtime too
Sahid Orentino Ferdjaouie9648272014-02-23 18:55:51 +010081 apt_get purge -y erlang*
Dean Troyer995eb922013-03-07 16:11:40 -060082 fi
83 elif is_service_enabled qpid; then
84 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +080085 uninstall_package qpid-cpp-server
Dean Troyer995eb922013-03-07 16:11:40 -060086 elif is_ubuntu; then
87 uninstall_package qpidd
88 else
89 exit_distro_not_supported "qpid installation"
90 fi
91 elif is_service_enabled zeromq; then
92 if is_fedora; then
Li Mad3ca1412014-12-21 23:36:43 -080093 uninstall_package zeromq python-zmq
94 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
95 uninstall_package redis python-redis
96 fi
Dean Troyer995eb922013-03-07 16:11:40 -060097 elif is_ubuntu; then
Li Mad3ca1412014-12-21 23:36:43 -080098 uninstall_package libzmq1 python-zmq
99 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
100 uninstall_package redis-server python-redis
101 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600102 elif is_suse; then
Li Mad3ca1412014-12-21 23:36:43 -0800103 uninstall_package libzmq1 python-pyzmq
104 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
105 uninstall_package redis python-redis
106 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600107 else
108 exit_distro_not_supported "zeromq installation"
109 fi
110 fi
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400111
112 # Remove the AMQP 1.0 messaging libraries
113 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
114 if is_fedora; then
115 uninstall_package qpid-proton-c-devel
116 uninstall_package python-qpid-proton
117 fi
118 # TODO(kgiusti) ubuntu cleanup
119 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600120}
121
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900122# install rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100123function install_rpc_backend {
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400124 # Regardless of the broker used, if AMQP 1.0 is configured load
125 # the necessary messaging client libraries for oslo.messaging
126 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
127 if is_fedora; then
128 install_package qpid-proton-c-devel
129 install_package python-qpid-proton
130 elif is_ubuntu; then
131 # TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
132 # are not yet in the ubuntu repos. Enable these installs
133 # once they are present:
134 #install_package libqpid-proton2-dev
135 #install_package python-qpid-proton
136 # Also add 'uninstall' directives in cleanup_rpc_backend()!
137 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
138 else
139 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
140 fi
141 # Install pyngus client API
142 # TODO(kgiusti) can remove once python qpid bindings are
143 # available on all supported platforms _and_ pyngus is added
144 # to the requirements.txt file in oslo.messaging
145 pip_install pyngus
146 fi
147
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900148 if is_service_enabled rabbit; then
149 # Install rabbitmq-server
Ian Wienand7ccf4e02014-07-23 14:24:11 +1000150 install_package rabbitmq-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900151 elif is_service_enabled qpid; then
152 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +0800153 install_package qpid-cpp-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900154 elif is_ubuntu; then
155 install_package qpidd
156 else
157 exit_distro_not_supported "qpid installation"
158 fi
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400159 _configure_qpid
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900160 elif is_service_enabled zeromq; then
161 if is_fedora; then
Li Mad3ca1412014-12-21 23:36:43 -0800162 install_package zeromq python-zmq
163 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
164 install_package redis python-redis
165 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900166 elif is_ubuntu; then
Li Mad3ca1412014-12-21 23:36:43 -0800167 install_package libzmq1 python-zmq
168 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
169 install_package redis-server python-redis
170 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900171 elif is_suse; then
Li Mad3ca1412014-12-21 23:36:43 -0800172 install_package libzmq1 python-pyzmq
173 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
174 install_package redis python-redis
175 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900176 else
177 exit_distro_not_supported "zeromq installation"
178 fi
Vincent Hou93a7a502013-09-27 06:16:54 -0400179 # Necessary directory for socket location.
180 sudo mkdir -p /var/run/openstack
181 sudo chown $STACK_USER /var/run/openstack
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900182 fi
Kenneth Giustia1875b72014-09-15 14:21:55 -0400183
184 # If using the QPID broker, install the QPID python client API
185 if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
186 install_package python-qpid
187 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900188}
189
190# restart the rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100191function restart_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900192 if is_service_enabled rabbit; then
193 # Start rabbitmq-server
194 echo_summary "Starting RabbitMQ"
Ben Nemecec5918f2014-01-30 16:07:23 +0000195 # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
196 # the fact that sometimes it fails to start properly.
Ian Wienand64b56a52014-12-16 09:53:36 +1100197 # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1144100
Dean Troyer3ef23bc2014-07-25 14:56:22 -0500198 local i
Ben Nemecec5918f2014-01-30 16:07:23 +0000199 for i in `seq 10`; do
Ian Wienand64b56a52014-12-16 09:53:36 +1100200 local rc=0
201
202 [[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
203
Ben Nemecec5918f2014-01-30 16:07:23 +0000204 if is_fedora || is_suse; then
205 # service is not started by default
206 restart_service rabbitmq-server
207 fi
Ian Wienand64b56a52014-12-16 09:53:36 +1100208
209 rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD" || rc=$?
210 if [ $rc -ne 0 ]; then
211 continue
212 fi
213
Ben Nemecec5918f2014-01-30 16:07:23 +0000214 # change the rabbit password since the default is "guest"
Ian Wienand64b56a52014-12-16 09:53:36 +1100215 sudo rabbitmqctl change_password \
216 $RABBIT_USERID $RABBIT_PASSWORD || rc=$?
217 if [ $rc -ne 0 ]; then
218 continue;
219 fi
220
221 break
Ben Nemecec5918f2014-01-30 16:07:23 +0000222 done
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000223 if is_service_enabled n-cell; then
224 # Add partitioned access for the child cell
225 if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
226 sudo rabbitmqctl add_vhost child_cell
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530227 sudo rabbitmqctl set_permissions -p child_cell $RABBIT_USERID ".*" ".*" ".*"
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000228 fi
229 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900230 elif is_service_enabled qpid; then
231 echo_summary "Starting qpid"
232 restart_service qpidd
233 fi
234}
235
gordon chungb6197e62015-02-12 15:33:35 -0500236# builds transport url string
237function get_transport_url {
238 if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
239 echo "qpid://$QPID_USERNAME:$QPID_PASSWORD@$QPID_HOST:5672/"
240 elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
241 echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/"
242 fi
243}
244
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900245# iniset cofiguration
Ian Wienandaee18c72014-02-21 15:35:08 +1100246function iniset_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900247 local package=$1
248 local file=$2
Brant Knudson2dd110c2015-03-14 12:39:14 -0500249 local section=${3:-DEFAULT}
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900250 if is_service_enabled zeromq; then
Li Mace1524d2014-12-21 00:46:34 -0800251 iniset $file $section rpc_backend "zmq"
Li Mac24b3992014-12-21 23:51:40 -0800252 iniset $file $section rpc_zmq_host `hostname`
253 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
254 iniset $file $section rpc_zmq_matchmaker \
255 oslo.messaging._drivers.matchmaker_redis.MatchMakerRedis
256 MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
257 iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
258 else
259 die $LINENO "Other matchmaker drivers not supported"
260 fi
Jason Dillaman056df822013-07-01 08:52:13 -0400261 elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400262 # For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
263 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
264 iniset $file $section rpc_backend "amqp"
265 else
Li Ma529f8112015-01-23 03:10:49 -0800266 iniset $file $section rpc_backend "qpid"
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400267 fi
Attila Fazekasa3dc3992013-07-11 11:26:35 +0200268 iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400269 if [ -n "$QPID_USERNAME" ]; then
270 iniset $file $section qpid_username $QPID_USERNAME
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000271 iniset $file $section qpid_password $QPID_PASSWORD
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000272 fi
jiajun xu4a30b842013-01-22 11:49:03 +0800273 elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
Li Ma529f8112015-01-23 03:10:49 -0800274 iniset $file $section rpc_backend "rabbit"
Nicolas Simonds8f084c62014-02-28 17:01:41 -0800275 iniset $file $section rabbit_hosts $RABBIT_HOST
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900276 iniset $file $section rabbit_password $RABBIT_PASSWORD
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530277 iniset $file $section rabbit_userid $RABBIT_USERID
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900278 fi
279}
280
281# Check if qpid can be used on the current distro.
282# qpid_is_supported
Ian Wienandaee18c72014-02-21 15:35:08 +1100283function qpid_is_supported {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900284 if [[ -z "$DISTRO" ]]; then
285 GetDistro
286 fi
287
Sean Dague2bb483d2014-01-03 09:41:27 -0500288 # Qpid is not in openSUSE
289 ( ! is_suse )
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900290}
291
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530292function rabbit_setuser {
293 local user="$1" pass="$2" found="" out=""
294 out=$(sudo rabbitmqctl list_users) ||
295 { echo "failed to list users" 1>&2; return 1; }
296 found=$(echo "$out" | awk '$1 == user { print $1 }' "user=$user")
297 if [ "$found" = "$user" ]; then
298 sudo rabbitmqctl change_password "$user" "$pass" ||
299 { echo "failed changing pass for '$user'" 1>&2; return 1; }
300 else
301 sudo rabbitmqctl add_user "$user" "$pass" ||
302 { echo "failed changing pass for $user"; return 1; }
303 fi
304 sudo rabbitmqctl set_permissions "$user" ".*" ".*" ".*"
305}
306
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400307# Set up the various configuration files used by the qpidd broker
308function _configure_qpid {
309
310 # the location of the configuration files have changed since qpidd 0.14
311 local qpid_conf_file
312 if [ -e /etc/qpid/qpidd.conf ]; then
313 qpid_conf_file=/etc/qpid/qpidd.conf
314 elif [ -e /etc/qpidd.conf ]; then
315 qpid_conf_file=/etc/qpidd.conf
316 else
317 exit_distro_not_supported "qpidd.conf file not found!"
318 fi
319
320 # force the ACL file to a known location
321 local qpid_acl_file=/etc/qpid/qpidd.acl
322 if [ ! -e $qpid_acl_file ]; then
323 sudo mkdir -p -m 755 `dirname $qpid_acl_file`
324 sudo touch $qpid_acl_file
325 sudo chmod o+r $qpid_acl_file
326 fi
327 sudo sed -i.bak '/^acl-file=/d' $qpid_conf_file
328 echo "acl-file=$qpid_acl_file" | sudo tee --append $qpid_conf_file
329
330 sudo sed -i '/^auth=/d' $qpid_conf_file
331 if [ -z "$QPID_USERNAME" ]; then
332 # no QPID user configured, so disable authentication
333 # and access control
334 echo "auth=no" | sudo tee --append $qpid_conf_file
335 cat <<EOF | sudo tee $qpid_acl_file
336acl allow all all
337EOF
338 else
339 # Configure qpidd to use PLAIN authentication, and add
340 # QPID_USERNAME to the ACL:
341 echo "auth=yes" | sudo tee --append $qpid_conf_file
342 if [ -z "$QPID_PASSWORD" ]; then
343 read_password QPID_PASSWORD "ENTER A PASSWORD FOR QPID USER $QPID_USERNAME"
344 fi
345 # Create ACL to allow $QPID_USERNAME full access
346 cat <<EOF | sudo tee $qpid_acl_file
347group admin ${QPID_USERNAME}@QPID
348acl allow admin all
349acl deny all all
350EOF
351 # Add user to SASL database
352 if is_ubuntu; then
353 install_package sasl2-bin
354 elif is_fedora; then
355 install_package cyrus-sasl-lib
Mehdi Abaakoukd1e3ff12015-02-10 17:54:53 +0100356 install_package cyrus-sasl-plain
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400357 fi
358 local sasl_conf_file=/etc/sasl2/qpidd.conf
359 sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
360 local sasl_db=`sudo grep sasldb_path $sasl_conf_file | cut -f 2 -d ":" | tr -d [:blank:]`
361 if [ ! -e $sasl_db ]; then
362 sudo mkdir -p -m 755 `dirname $sasl_db`
363 fi
364 echo $QPID_PASSWORD | sudo saslpasswd2 -c -p -f $sasl_db -u QPID $QPID_USERNAME
365 sudo chmod o+r $sasl_db
366 fi
367
368 # If AMQP 1.0 is specified, ensure that the version of the
369 # broker can support AMQP 1.0 and configure the queue and
370 # topic address patterns used by oslo.messaging.
371 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
372 QPIDD=$(type -p qpidd)
373 if ! $QPIDD --help | grep -q "queue-patterns"; then
374 exit_distro_not_supported "qpidd with AMQP 1.0 support"
375 fi
376 if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
377 cat <<EOF | sudo tee --append $qpid_conf_file
378queue-patterns=exclusive
379queue-patterns=unicast
380topic-patterns=broadcast
381EOF
382 fi
383 fi
384}
Dean Troyercc6b4432013-04-08 15:38:03 -0500385
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900386# Restore xtrace
387$XTRACE
Sean Dague584d90e2013-03-29 14:34:53 -0400388
Adam Spiers6a5aa7c2013-10-24 11:27:02 +0100389# Tell emacs to use shell-script-mode
390## Local variables:
391## mode: shell-script
392## End: