# 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_hosts $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:
