# lib/rpc_backend
# Interface for interactig with different rpc backend
# rpc backend settings

# Dependencies:
#
# - ``functions`` file
# - ``RABBIT_{HOST|PASSWORD}`` must be defined when RabbitMQ is used

# ``stack.sh`` calls the entry points in this order:
#
# - check_rpc_backend
# - install_rpc_backend
# - restart_rpc_backend
# - iniset_rpc_backend

# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace


# Functions
# ---------


# Make sure we only have one rpc backend enabled.
# Also check the specified rpc backend is available on your platform.
function check_rpc_backend() {
    local rpc_needed=1
    # We rely on the fact that filenames in lib/* match the service names
    # that can be passed as arguments to is_service_enabled.
    # We check for a call to iniset_rpc_backend in these files, meaning
    # the service needs a backend.
    rpc_candidates=$(grep -rl iniset_rpc_backend $TOP_DIR/lib/ | awk -F/ '{print $NF}')
    for c in ${rpc_candidates}; do
        if is_service_enabled $c; then
            rpc_needed=0
            break
        fi
    done
    local rpc_backend_cnt=0
    for svc in qpid zeromq rabbit; do
        is_service_enabled $svc &&
        ((rpc_backend_cnt++))
    done
    if [ "$rpc_backend_cnt" -gt 1 ]; then
        echo "ERROR: only one rpc backend may be enabled,"
        echo "       set only one of 'rabbit', 'qpid', 'zeromq'"
        echo "       via ENABLED_SERVICES."
    elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
        echo "ERROR: at least one rpc backend must be enabled,"
        echo "       set one of 'rabbit', 'qpid', 'zeromq'"
        echo "       via ENABLED_SERVICES."
    fi

    if is_service_enabled qpid && ! qpid_is_supported; then
        die $LINENO "Qpid support is not available for this version of your distribution."
    fi
}

# 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
        sudo killall epmd || sudo killall -9 epmd
        if is_ubuntu; then
            # And the Erlang runtime too
            apt_get purge -y erlang*
        fi
    elif is_service_enabled qpid; then
        if is_fedora; then
            uninstall_package qpid-cpp-server
        elif is_ubuntu; then
            uninstall_package qpidd
        else
            exit_distro_not_supported "qpid installation"
        fi
    elif is_service_enabled zeromq; then
        if is_fedora; then
            uninstall_package zeromq python-zmq redis
        elif is_ubuntu; then
            uninstall_package libzmq1 python-zmq redis-server
        elif is_suse; then
            uninstall_package libzmq1 python-pyzmq redis
        else
            exit_distro_not_supported "zeromq installation"
        fi
    fi
}

# install rpc backend
function install_rpc_backend() {
    if is_service_enabled rabbit; then
        # Install rabbitmq-server
        # the temp file is necessary due to LP: #878600
        tfile=$(mktemp)
        install_package rabbitmq-server > "$tfile" 2>&1
        cat "$tfile"
        rm -f "$tfile"
    elif is_service_enabled qpid; then
        if is_fedora; then
            install_package qpid-cpp-server
            if [[ $DISTRO =~ (rhel6) ]]; then
                # RHEL6 leaves "auth=yes" in /etc/qpidd.conf, it needs to
                # be no or you get GSS authentication errors as it
                # attempts to default to this.
                sudo sed -i.bak 's/^auth=yes$/auth=no/' /etc/qpidd.conf
            fi
        elif is_ubuntu; then
            install_package qpidd
            sudo sed -i '/PLAIN/!s/mech_list: /mech_list: PLAIN /' /etc/sasl2/qpidd.conf
            sudo chmod o+r /etc/qpid/qpidd.sasldb
        else
            exit_distro_not_supported "qpid installation"
        fi
    elif is_service_enabled zeromq; then
        # NOTE(ewindisch): Redis is not strictly necessary
        # but there is a matchmaker driver that works
        # really well & out of the box for multi-node.
        if is_fedora; then
            install_package zeromq python-zmq redis
        elif is_ubuntu; then
            install_package libzmq1 python-zmq redis-server
        elif is_suse; then
            install_package libzmq1 python-pyzmq redis
        else
            exit_distro_not_supported "zeromq installation"
        fi
        # Necessary directory for socket location.
        sudo mkdir -p /var/run/openstack
        sudo chown $STACK_USER /var/run/openstack
    fi
}

# restart the rpc backend
function restart_rpc_backend() {
    if is_service_enabled rabbit; then
        # Start rabbitmq-server
        echo_summary "Starting RabbitMQ"
        # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
        # the fact that sometimes it fails to start properly.
        # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1059028
        for i in `seq 10`; do
            if is_fedora || is_suse; then
                # service is not started by default
                restart_service rabbitmq-server
            fi
            # change the rabbit password since the default is "guest"
            sudo rabbitmqctl change_password guest $RABBIT_PASSWORD && break
            [[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
        done
        if is_service_enabled n-cell; then
            # Add partitioned access for the child cell
            if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
                sudo rabbitmqctl add_vhost child_cell
                sudo rabbitmqctl set_permissions -p child_cell guest ".*" ".*" ".*"
            fi
        fi
    elif is_service_enabled qpid; then
        echo_summary "Starting qpid"
        restart_service qpidd
    fi
}

# iniset cofiguration
function iniset_rpc_backend() {
    local package=$1
    local file=$2
    local section=$3
    if is_service_enabled zeromq; then
        iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_zmq
        iniset $file $section rpc_zmq_matchmaker \
            ${package}.openstack.common.rpc.matchmaker_redis.MatchMakerRedis
        # Set MATCHMAKER_REDIS_HOST if running multi-node.
        MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
        iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
    elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
        iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_qpid
        iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
        if is_ubuntu; then
            QPID_PASSWORD=`sudo strings /etc/qpid/qpidd.sasldb | grep -B1 admin | head -1`
            iniset $file $section qpid_password $QPID_PASSWORD
            iniset $file $section qpid_username admin
        fi
    elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        iniset $file $section rpc_backend ${package}.openstack.common.rpc.impl_kombu
        iniset $file $section rabbit_host $RABBIT_HOST
        iniset $file $section rabbit_password $RABBIT_PASSWORD
    fi
}

# Check if qpid can be used on the current distro.
# qpid_is_supported
function qpid_is_supported() {
    if [[ -z "$DISTRO" ]]; then
        GetDistro
    fi

    # Qpid is not in openSUSE
    ( ! is_suse )
}


# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
