blob: ff22bbf8fafeb65bb0f2a6dca07f0b74b20e5e96 [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
236# iniset cofiguration
Ian Wienandaee18c72014-02-21 15:35:08 +1100237function iniset_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900238 local package=$1
239 local file=$2
240 local section=$3
241 if is_service_enabled zeromq; then
Li Mace1524d2014-12-21 00:46:34 -0800242 iniset $file $section rpc_backend "zmq"
Li Mac24b3992014-12-21 23:51:40 -0800243 iniset $file $section rpc_zmq_host `hostname`
244 if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
245 iniset $file $section rpc_zmq_matchmaker \
246 oslo.messaging._drivers.matchmaker_redis.MatchMakerRedis
247 MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
248 iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
249 else
250 die $LINENO "Other matchmaker drivers not supported"
251 fi
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
Li Ma529f8112015-01-23 03:10:49 -0800257 iniset $file $section rpc_backend "qpid"
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400258 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
Li Ma529f8112015-01-23 03:10:49 -0800265 iniset $file $section rpc_backend "rabbit"
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
Mehdi Abaakoukd1e3ff12015-02-10 17:54:53 +0100347 install_package cyrus-sasl-plain
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400348 fi
349 local sasl_conf_file=/etc/sasl2/qpidd.conf
350 sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
351 local sasl_db=`sudo grep sasldb_path $sasl_conf_file | cut -f 2 -d ":" | tr -d [:blank:]`
352 if [ ! -e $sasl_db ]; then
353 sudo mkdir -p -m 755 `dirname $sasl_db`
354 fi
355 echo $QPID_PASSWORD | sudo saslpasswd2 -c -p -f $sasl_db -u QPID $QPID_USERNAME
356 sudo chmod o+r $sasl_db
357 fi
358
359 # If AMQP 1.0 is specified, ensure that the version of the
360 # broker can support AMQP 1.0 and configure the queue and
361 # topic address patterns used by oslo.messaging.
362 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
363 QPIDD=$(type -p qpidd)
364 if ! $QPIDD --help | grep -q "queue-patterns"; then
365 exit_distro_not_supported "qpidd with AMQP 1.0 support"
366 fi
367 if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
368 cat <<EOF | sudo tee --append $qpid_conf_file
369queue-patterns=exclusive
370queue-patterns=unicast
371topic-patterns=broadcast
372EOF
373 fi
374 fi
375}
Dean Troyercc6b4432013-04-08 15:38:03 -0500376
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900377# Restore xtrace
378$XTRACE
Sean Dague584d90e2013-03-29 14:34:53 -0400379
Adam Spiers6a5aa7c2013-10-24 11:27:02 +0100380# Tell emacs to use shell-script-mode
381## Local variables:
382## mode: shell-script
383## End: