lib/rpc_backend
e263c82e
 #!/bin/bash
 #
b0f1c38b
 # lib/rpc_backend
37eca489
 # Interface for installing RabbitMQ on the system
b0f1c38b
 
 # Dependencies:
6a5aa7c6
 #
 # - ``functions`` file
d5b74c68
 # - ``RABBIT_{HOST|PASSWORD|USERID}`` must be defined when RabbitMQ is used
b0f1c38b
 
 # ``stack.sh`` calls the entry points in this order:
 #
6a5aa7c6
 # - check_rpc_backend
 # - install_rpc_backend
 # - restart_rpc_backend
37eca489
 # - iniset_rpc_backend (stable interface)
 #
 # Note: if implementing an out of tree plugin for an RPC backend, you
 # should install all services through normal plugin methods, then
 # redefine ``iniset_rpc_backend`` in your code. That's the one portion
 # of this file which is a standard interface.
b0f1c38b
 
 # Save trace setting
523f4880
 _XTRACE_RPC_BACKEND=$(set +o | grep xtrace)
b0f1c38b
 set +o xtrace
 
0bf25506
 RABBIT_USERID=${RABBIT_USERID:-stackrabbit}
20eb274b
 if is_service_enabled rabbit; then
     RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
 fi
0bf25506
 
cc6b4435
 # Functions
 # ---------
b0f1c38b
 
995eb927
 # 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
9a413abc
         # in case it's not actually running, /bin/true at the end
         sudo killall epmd || sudo killall -9 epmd || /bin/true
995eb927
         if is_ubuntu; then
             # And the Erlang runtime too
e9648276
             apt_get purge -y erlang*
995eb927
         fi
7e58c06a
     fi
995eb927
 }
 
b0f1c38b
 # install rpc backend
aee18c74
 function install_rpc_backend {
b0f1c38b
     if is_service_enabled rabbit; then
         # Install rabbitmq-server
7ccf4e02
         install_package rabbitmq-server
4404f680
         if is_suse; then
             install_package rabbitmq-server-plugins
             # the default systemd socket activation only listens on the loopback interface
             # which causes rabbitmq to try to start its own epmd
             sudo mkdir -p /etc/systemd/system/epmd.socket.d
             cat <<EOF | sudo tee /etc/systemd/system/epmd.socket.d/ports.conf >/dev/null
 [Socket]
 ListenStream=
 ListenStream=[::]:4369
 EOF
             sudo systemctl daemon-reload
             sudo systemctl restart epmd.socket epmd.service
         fi
         if is_fedora || is_suse; then
97096e0a
             # NOTE(jangutter): If rabbitmq is not running (as in a fresh
             # install) then rabbit_setuser triggers epmd@0.0.0.0.socket with
             # socket activation. This fails the first time and does not get
             # cleared. It is benign, but the workaround is to start rabbitmq a
             # bit earlier for RPM based distros.
             sudo systemctl --now enable rabbitmq-server
75633266
         fi
4d8c03a3
     fi
b0f1c38b
 }
 
 # restart the rpc backend
aee18c74
 function restart_rpc_backend {
b0f1c38b
     if is_service_enabled rabbit; then
         # Start rabbitmq-server
         echo_summary "Starting RabbitMQ"
ec5918f2
         # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
         # the fact that sometimes it fails to start properly.
64b56a53
         # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1144100
fe7b56cd
         # NOTE(tonyb): Extend the original retry logic to only restart rabbitmq
6bc905c3
         # every second time around the loop.
         # See: https://bugs.launchpad.net/devstack/+bug/1449056 for details on
         # why this is needed.  This can bee seen on vivid and Debian unstable
         # (May 2015)
         # TODO(tonyb): Remove this when Debian and Ubuntu have a fixed systemd
         # service file.
3ef23bce
         local i
6bc905c3
         for i in `seq 20`; do
64b56a53
             local rc=0
 
6bc905c3
             [[ $i -eq "20" ]] && die $LINENO "Failed to set rabbitmq password"
64b56a53
 
6bc905c3
             if [[ $(( i % 2 )) == "0" ]] ; then
                 restart_service rabbitmq-server
             fi
64b56a53
 
             rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD" || rc=$?
             if [ $rc -ne 0 ]; then
                 continue
             fi
 
ec5918f2
             # change the rabbit password since the default is "guest"
64b56a53
             sudo rabbitmqctl change_password \
                 $RABBIT_USERID $RABBIT_PASSWORD || rc=$?
             if [ $rc -ne 0 ]; then
                 continue;
             fi
 
             break
ec5918f2
         done
81f67fd7
         # NOTE(frickler): Remove the default guest user
         sudo rabbitmqctl delete_user guest || true
6f0205b0
     fi
 }
 
 # adds a vhost to the rpc backend
 function rpc_backend_add_vhost {
     local vhost="$1"
     if is_service_enabled rabbit; then
         if [ -z `sudo rabbitmqctl list_vhosts | grep $vhost` ]; then
             sudo rabbitmqctl add_vhost $vhost
             sudo rabbitmqctl set_permissions -p $vhost $RABBIT_USERID ".*" ".*" ".*"
fb2a3ae3
         fi
6f0205b0
     else
         echo 'RPC backend does not support vhosts'
         return 1
b0f1c38b
     fi
 }
 
b645904d
 # Returns the address of the RPC backend in URL format.
b6197e6a
 function get_transport_url {
6176ae68
     local virtual_host=$1
37eca489
     if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
6176ae68
         echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/$virtual_host"
b6197e6a
     fi
 }
 
b645904d
 # Returns the address of the Notification backend in URL format.  This
 # should be used to set the transport_url option in the
 # oslo_messaging_notifications group.
26e431db
 function get_notification_url {
     local virtual_host=$1
     if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
         echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/$virtual_host"
     fi
 }
 
fe7b56cd
 # iniset configuration
aee18c74
 function iniset_rpc_backend {
b0f1c38b
     local package=$1
     local file=$2
2dd110ce
     local section=${3:-DEFAULT}
6176ae68
     local virtual_host=$4
37eca489
     if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
6176ae68
         iniset $file $section transport_url $(get_transport_url "$virtual_host")
7cf7a8f8
         if [ -n "$RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD" ]; then
             iniset $file oslo_messaging_rabbit heartbeat_timeout_threshold $RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD
         fi
         if [ -n "$RABBIT_HEARTBEAT_RATE" ]; then
             iniset $file oslo_messaging_rabbit heartbeat_rate $RABBIT_HEARTBEAT_RATE
         fi
b0f1c38b
     fi
 }
 
d5b74c68
 function rabbit_setuser {
     local user="$1" pass="$2" found="" out=""
     out=$(sudo rabbitmqctl list_users) ||
         { echo "failed to list users" 1>&2; return 1; }
     found=$(echo "$out" | awk '$1 == user { print $1 }' "user=$user")
     if [ "$found" = "$user" ]; then
         sudo rabbitmqctl change_password "$user" "$pass" ||
             { echo "failed changing pass for '$user'" 1>&2; return 1; }
     else
         sudo rabbitmqctl add_user "$user" "$pass" ||
             { echo "failed changing pass for $user"; return 1; }
     fi
     sudo rabbitmqctl set_permissions "$user" ".*" ".*" ".*"
 }
 
b0f1c38b
 # Restore xtrace
523f4880
 $_XTRACE_RPC_BACKEND
584d90ec
 
6a5aa7c6
 # Tell emacs to use shell-script-mode
 ## Local variables:
 ## mode: shell-script
 ## End: