blob: 6afec370e8a10a590e3201bcab75918295abbe7b [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
Dean Troyercc6b4432013-04-08 15:38:03 -050024
25# Functions
26# ---------
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090027
Matthieu Huin7a7a4662013-04-15 17:13:41 +020028
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090029# Make sure we only have one rpc backend enabled.
30# Also check the specified rpc backend is available on your platform.
Ian Wienandaee18c72014-02-21 15:35:08 +110031function check_rpc_backend {
Dean Troyer3ef23bc2014-07-25 14:56:22 -050032 local c svc
33
Matthieu Huin7a7a4662013-04-15 17:13:41 +020034 local rpc_needed=1
35 # We rely on the fact that filenames in lib/* match the service names
36 # that can be passed as arguments to is_service_enabled.
37 # We check for a call to iniset_rpc_backend in these files, meaning
38 # the service needs a backend.
Vishvananda Ishaya78a53d92013-05-09 17:20:31 -070039 rpc_candidates=$(grep -rl iniset_rpc_backend $TOP_DIR/lib/ | awk -F/ '{print $NF}')
Matthieu Huin7a7a4662013-04-15 17:13:41 +020040 for c in ${rpc_candidates}; do
41 if is_service_enabled $c; then
42 rpc_needed=0
43 break
44 fi
45 done
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090046 local rpc_backend_cnt=0
47 for svc in qpid zeromq rabbit; do
48 is_service_enabled $svc &&
Dean Troyerffd17682014-08-02 16:07:03 -050049 (( rpc_backend_cnt++ )) || true
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090050 done
51 if [ "$rpc_backend_cnt" -gt 1 ]; then
52 echo "ERROR: only one rpc backend may be enabled,"
53 echo " set only one of 'rabbit', 'qpid', 'zeromq'"
54 echo " via ENABLED_SERVICES."
Matthieu Huin7a7a4662013-04-15 17:13:41 +020055 elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090056 echo "ERROR: at least one rpc backend must be enabled,"
57 echo " set one of 'rabbit', 'qpid', 'zeromq'"
58 echo " via ENABLED_SERVICES."
59 fi
60
61 if is_service_enabled qpid && ! qpid_is_supported; then
Nachi Ueno07115eb2013-02-26 12:38:18 -080062 die $LINENO "Qpid support is not available for this version of your distribution."
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +090063 fi
64}
65
Dean Troyer995eb922013-03-07 16:11:40 -060066# clean up after rpc backend - eradicate all traces so changing backends
67# produces a clean switch
68function cleanup_rpc_backend {
69 if is_service_enabled rabbit; then
70 # Obliterate rabbitmq-server
Abhishek Chandad5b74c62014-12-12 02:15:55 +053071 if [ -n "$RABBIT_USERID" ]; then
72 sudo rabbitmqctl delete_user "$RABBIT_USERID"
73 fi
Dean Troyer995eb922013-03-07 16:11:40 -060074 uninstall_package rabbitmq-server
DennyZhang557744f2013-10-14 09:50:13 -050075 sudo killall epmd || sudo killall -9 epmd
Dean Troyer995eb922013-03-07 16:11:40 -060076 if is_ubuntu; then
77 # And the Erlang runtime too
Sahid Orentino Ferdjaouie9648272014-02-23 18:55:51 +010078 apt_get purge -y erlang*
Dean Troyer995eb922013-03-07 16:11:40 -060079 fi
80 elif is_service_enabled qpid; then
81 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +080082 uninstall_package qpid-cpp-server
Dean Troyer995eb922013-03-07 16:11:40 -060083 elif is_ubuntu; then
84 uninstall_package qpidd
85 else
86 exit_distro_not_supported "qpid installation"
87 fi
88 elif is_service_enabled zeromq; then
89 if is_fedora; then
Eric Windisch800bf382013-05-24 11:21:11 -040090 uninstall_package zeromq python-zmq redis
Dean Troyer995eb922013-03-07 16:11:40 -060091 elif is_ubuntu; then
Eric Windisch800bf382013-05-24 11:21:11 -040092 uninstall_package libzmq1 python-zmq redis-server
Dean Troyer995eb922013-03-07 16:11:40 -060093 elif is_suse; then
Eric Windisch800bf382013-05-24 11:21:11 -040094 uninstall_package libzmq1 python-pyzmq redis
Dean Troyer995eb922013-03-07 16:11:40 -060095 else
96 exit_distro_not_supported "zeromq installation"
97 fi
98 fi
Kenneth Giusti7e58c062014-07-23 16:44:37 -040099
100 # Remove the AMQP 1.0 messaging libraries
101 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
102 if is_fedora; then
103 uninstall_package qpid-proton-c-devel
104 uninstall_package python-qpid-proton
105 fi
106 # TODO(kgiusti) ubuntu cleanup
107 fi
Dean Troyer995eb922013-03-07 16:11:40 -0600108}
109
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900110# install rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100111function install_rpc_backend {
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400112 # Regardless of the broker used, if AMQP 1.0 is configured load
113 # the necessary messaging client libraries for oslo.messaging
114 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
115 if is_fedora; then
116 install_package qpid-proton-c-devel
117 install_package python-qpid-proton
118 elif is_ubuntu; then
119 # TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
120 # are not yet in the ubuntu repos. Enable these installs
121 # once they are present:
122 #install_package libqpid-proton2-dev
123 #install_package python-qpid-proton
124 # Also add 'uninstall' directives in cleanup_rpc_backend()!
125 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
126 else
127 exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
128 fi
129 # Install pyngus client API
130 # TODO(kgiusti) can remove once python qpid bindings are
131 # available on all supported platforms _and_ pyngus is added
132 # to the requirements.txt file in oslo.messaging
133 pip_install pyngus
134 fi
135
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900136 if is_service_enabled rabbit; then
137 # Install rabbitmq-server
Ian Wienand7ccf4e02014-07-23 14:24:11 +1000138 install_package rabbitmq-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900139 elif is_service_enabled qpid; then
140 if is_fedora; then
zhhuabj5595fdc2013-05-08 18:27:20 +0800141 install_package qpid-cpp-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900142 elif is_ubuntu; then
143 install_package qpidd
144 else
145 exit_distro_not_supported "qpid installation"
146 fi
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400147 _configure_qpid
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900148 elif is_service_enabled zeromq; then
Eric Windisch800bf382013-05-24 11:21:11 -0400149 # NOTE(ewindisch): Redis is not strictly necessary
150 # but there is a matchmaker driver that works
151 # really well & out of the box for multi-node.
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900152 if is_fedora; then
Eric Windisch800bf382013-05-24 11:21:11 -0400153 install_package zeromq python-zmq redis
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900154 elif is_ubuntu; then
Eric Windisch800bf382013-05-24 11:21:11 -0400155 install_package libzmq1 python-zmq redis-server
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900156 elif is_suse; then
Eric Windisch800bf382013-05-24 11:21:11 -0400157 install_package libzmq1 python-pyzmq redis
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900158 else
159 exit_distro_not_supported "zeromq installation"
160 fi
Vincent Hou93a7a502013-09-27 06:16:54 -0400161 # Necessary directory for socket location.
162 sudo mkdir -p /var/run/openstack
163 sudo chown $STACK_USER /var/run/openstack
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900164 fi
Kenneth Giustia1875b72014-09-15 14:21:55 -0400165
166 # If using the QPID broker, install the QPID python client API
167 if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
168 install_package python-qpid
169 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900170}
171
172# restart the rpc backend
Ian Wienandaee18c72014-02-21 15:35:08 +1100173function restart_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900174 if is_service_enabled rabbit; then
175 # Start rabbitmq-server
176 echo_summary "Starting RabbitMQ"
Ben Nemecec5918f2014-01-30 16:07:23 +0000177 # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
178 # the fact that sometimes it fails to start properly.
179 # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1059028
Dean Troyer3ef23bc2014-07-25 14:56:22 -0500180 local i
Ben Nemecec5918f2014-01-30 16:07:23 +0000181 for i in `seq 10`; do
182 if is_fedora || is_suse; then
183 # service is not started by default
184 restart_service rabbitmq-server
185 fi
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530186 rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD"
Ben Nemecec5918f2014-01-30 16:07:23 +0000187 # change the rabbit password since the default is "guest"
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530188 sudo rabbitmqctl change_password $RABBIT_USERID $RABBIT_PASSWORD && break
Ben Nemecec5918f2014-01-30 16:07:23 +0000189 [[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
190 done
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000191 if is_service_enabled n-cell; then
192 # Add partitioned access for the child cell
193 if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
194 sudo rabbitmqctl add_vhost child_cell
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530195 sudo rabbitmqctl set_permissions -p child_cell $RABBIT_USERID ".*" ".*" ".*"
Kieran Spearfb2a3ae2013-03-11 23:55:49 +0000196 fi
197 fi
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900198 elif is_service_enabled qpid; then
199 echo_summary "Starting qpid"
200 restart_service qpidd
201 fi
202}
203
204# iniset cofiguration
Ian Wienandaee18c72014-02-21 15:35:08 +1100205function iniset_rpc_backend {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900206 local package=$1
207 local file=$2
208 local section=$3
209 if is_service_enabled zeromq; then
210 iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_zmq
Eric Windisch800bf382013-05-24 11:21:11 -0400211 iniset $file $section rpc_zmq_matchmaker \
212 ${package}.openstack.common.rpc.matchmaker_redis.MatchMakerRedis
213 # Set MATCHMAKER_REDIS_HOST if running multi-node.
214 MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
215 iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
Jason Dillaman056df822013-07-01 08:52:13 -0400216 elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
Kenneth Giusti7e58c062014-07-23 16:44:37 -0400217 # For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
218 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
219 iniset $file $section rpc_backend "amqp"
220 else
221 iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
222 fi
Attila Fazekasa3dc3992013-07-11 11:26:35 +0200223 iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400224 if [ -n "$QPID_USERNAME" ]; then
225 iniset $file $section qpid_username $QPID_USERNAME
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000226 iniset $file $section qpid_password $QPID_PASSWORD
Eoghan Glynn8c11f562013-03-01 12:09:01 +0000227 fi
jiajun xu4a30b842013-01-22 11:49:03 +0800228 elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900229 iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_kombu
Nicolas Simonds8f084c62014-02-28 17:01:41 -0800230 iniset $file $section rabbit_hosts $RABBIT_HOST
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900231 iniset $file $section rabbit_password $RABBIT_PASSWORD
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530232 iniset $file $section rabbit_userid $RABBIT_USERID
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900233 fi
234}
235
236# Check if qpid can be used on the current distro.
237# qpid_is_supported
Ian Wienandaee18c72014-02-21 15:35:08 +1100238function qpid_is_supported {
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900239 if [[ -z "$DISTRO" ]]; then
240 GetDistro
241 fi
242
Sean Dague2bb483d2014-01-03 09:41:27 -0500243 # Qpid is not in openSUSE
244 ( ! is_suse )
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900245}
246
Abhishek Chandad5b74c62014-12-12 02:15:55 +0530247function rabbit_setuser {
248 local user="$1" pass="$2" found="" out=""
249 out=$(sudo rabbitmqctl list_users) ||
250 { echo "failed to list users" 1>&2; return 1; }
251 found=$(echo "$out" | awk '$1 == user { print $1 }' "user=$user")
252 if [ "$found" = "$user" ]; then
253 sudo rabbitmqctl change_password "$user" "$pass" ||
254 { echo "failed changing pass for '$user'" 1>&2; return 1; }
255 else
256 sudo rabbitmqctl add_user "$user" "$pass" ||
257 { echo "failed changing pass for $user"; return 1; }
258 fi
259 sudo rabbitmqctl set_permissions "$user" ".*" ".*" ".*"
260}
261
Kenneth Giusti062a3c32014-09-30 10:14:08 -0400262# Set up the various configuration files used by the qpidd broker
263function _configure_qpid {
264
265 # the location of the configuration files have changed since qpidd 0.14
266 local qpid_conf_file
267 if [ -e /etc/qpid/qpidd.conf ]; then
268 qpid_conf_file=/etc/qpid/qpidd.conf
269 elif [ -e /etc/qpidd.conf ]; then
270 qpid_conf_file=/etc/qpidd.conf
271 else
272 exit_distro_not_supported "qpidd.conf file not found!"
273 fi
274
275 # force the ACL file to a known location
276 local qpid_acl_file=/etc/qpid/qpidd.acl
277 if [ ! -e $qpid_acl_file ]; then
278 sudo mkdir -p -m 755 `dirname $qpid_acl_file`
279 sudo touch $qpid_acl_file
280 sudo chmod o+r $qpid_acl_file
281 fi
282 sudo sed -i.bak '/^acl-file=/d' $qpid_conf_file
283 echo "acl-file=$qpid_acl_file" | sudo tee --append $qpid_conf_file
284
285 sudo sed -i '/^auth=/d' $qpid_conf_file
286 if [ -z "$QPID_USERNAME" ]; then
287 # no QPID user configured, so disable authentication
288 # and access control
289 echo "auth=no" | sudo tee --append $qpid_conf_file
290 cat <<EOF | sudo tee $qpid_acl_file
291acl allow all all
292EOF
293 else
294 # Configure qpidd to use PLAIN authentication, and add
295 # QPID_USERNAME to the ACL:
296 echo "auth=yes" | sudo tee --append $qpid_conf_file
297 if [ -z "$QPID_PASSWORD" ]; then
298 read_password QPID_PASSWORD "ENTER A PASSWORD FOR QPID USER $QPID_USERNAME"
299 fi
300 # Create ACL to allow $QPID_USERNAME full access
301 cat <<EOF | sudo tee $qpid_acl_file
302group admin ${QPID_USERNAME}@QPID
303acl allow admin all
304acl deny all all
305EOF
306 # Add user to SASL database
307 if is_ubuntu; then
308 install_package sasl2-bin
309 elif is_fedora; then
310 install_package cyrus-sasl-lib
311 fi
312 local sasl_conf_file=/etc/sasl2/qpidd.conf
313 sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
314 local sasl_db=`sudo grep sasldb_path $sasl_conf_file | cut -f 2 -d ":" | tr -d [:blank:]`
315 if [ ! -e $sasl_db ]; then
316 sudo mkdir -p -m 755 `dirname $sasl_db`
317 fi
318 echo $QPID_PASSWORD | sudo saslpasswd2 -c -p -f $sasl_db -u QPID $QPID_USERNAME
319 sudo chmod o+r $sasl_db
320 fi
321
322 # If AMQP 1.0 is specified, ensure that the version of the
323 # broker can support AMQP 1.0 and configure the queue and
324 # topic address patterns used by oslo.messaging.
325 if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
326 QPIDD=$(type -p qpidd)
327 if ! $QPIDD --help | grep -q "queue-patterns"; then
328 exit_distro_not_supported "qpidd with AMQP 1.0 support"
329 fi
330 if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
331 cat <<EOF | sudo tee --append $qpid_conf_file
332queue-patterns=exclusive
333queue-patterns=unicast
334topic-patterns=broadcast
335EOF
336 fi
337 fi
338}
Dean Troyercc6b4432013-04-08 15:38:03 -0500339
Akihiro MOTOKIb0f1c382013-01-13 17:58:12 +0900340# Restore xtrace
341$XTRACE
Sean Dague584d90e2013-03-29 14:34:53 -0400342
Adam Spiers6a5aa7c2013-10-24 11:27:02 +0100343# Tell emacs to use shell-script-mode
344## Local variables:
345## mode: shell-script
346## End: