# lib/zaqar
# Install and start **Zaqar** service

# To enable a minimal set of Zaqar services, add the following to localrc:
#
#     enable_service zaqar-server
#
# Dependencies:
# - functions
# - OS_AUTH_URL for auth in api
# - DEST set to the destination directory
# - SERVICE_PASSWORD, SERVICE_TENANT_NAME for auth in api
# - STACK_USER service user

# stack.sh
# ---------
# install_zaqar
# configure_zaqar
# init_zaqar
# start_zaqar
# stop_zaqar
# cleanup_zaqar
# cleanup_zaqar_mongodb

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


# Defaults
# --------

# Set up default directories
ZAQAR_DIR=$DEST/zaqar
ZAQARCLIENT_DIR=$DEST/python-zaqarclient
ZAQAR_CONF_DIR=/etc/zaqar
ZAQAR_CONF=$ZAQAR_CONF_DIR/zaqar.conf
ZAQAR_API_LOG_DIR=/var/log/zaqar
ZAQAR_API_LOG_FILE=$ZAQAR_API_LOG_DIR/queues.log
ZAQAR_AUTH_CACHE_DIR=${ZAQAR_AUTH_CACHE_DIR:-/var/cache/zaqar}

# Support potential entry-points console scripts
ZAQAR_BIN_DIR=$(get_python_exec_prefix)

# Set up database backend
ZAQAR_BACKEND=${ZAQAR_BACKEND:-mongodb}


# Set Zaqar repository
ZAQAR_REPO=${ZAQAR_REPO:-${GIT_BASE}/openstack/zaqar.git}
ZAQAR_BRANCH=${ZAQAR_BRANCH:-master}

# Set client library repository
ZAQARCLIENT_REPO=${ZAQARCLIENT_REPO:-${GIT_BASE}/openstack/python-zaqarclient.git}
ZAQARCLIENT_BRANCH=${ZAQARCLIENT_BRANCH:-master}

# Set Zaqar Connection Info
ZAQAR_SERVICE_HOST=${ZAQAR_SERVICE_HOST:-$SERVICE_HOST}
ZAQAR_SERVICE_PORT=${ZAQAR_SERVICE_PORT:-8888}
ZAQAR_SERVICE_PROTOCOL=${ZAQAR_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

# Tell Tempest this project is present
TEMPEST_SERVICES+=,zaqar


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

# Test if any Zaqar services are enabled
# is_zaqar_enabled
function is_zaqar_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"zaqar-" ]] && return 0
    return 1
}

# cleanup_zaqar() - Cleans up general things from previous
# runs and storage specific left overs.
function cleanup_zaqar {
    if [ "$ZAQAR_BACKEND" = 'mongodb' ] ; then
        cleanup_zaqar_mongodb
    fi
}

# cleanup_zaqar_mongodb() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_zaqar_mongodb {
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! mongo zaqar --eval 'db.dropDatabase();'; do sleep 1; done"; then
        die $LINENO "Mongo DB did not start"
    else
        full_version=$(mongo zaqar --eval 'db.dropDatabase();')
        mongo_version=`echo $full_version | cut -d' ' -f4`
        required_mongo_version='2.2'
        if [[ $mongo_version < $required_mongo_version ]]; then
            die $LINENO "Zaqar needs Mongo DB version >= 2.2 to run."
        fi
    fi
}

# configure_zaqarclient() - Set config files, create data dirs, etc
function configure_zaqarclient {
    setup_develop $ZAQARCLIENT_DIR
}

# configure_zaqar() - Set config files, create data dirs, etc
function configure_zaqar {
    setup_develop $ZAQAR_DIR

    [ ! -d $ZAQAR_CONF_DIR ] && sudo mkdir -m 755 -p $ZAQAR_CONF_DIR
    sudo chown $USER $ZAQAR_CONF_DIR

    [ ! -d $ZAQAR_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $ZAQAR_API_LOG_DIR
    sudo chown $USER $ZAQAR_API_LOG_DIR

    iniset $ZAQAR_CONF DEFAULT verbose True
    iniset $ZAQAR_CONF DEFAULT admin_mode True
    iniset $ZAQAR_CONF DEFAULT use_syslog $SYSLOG
    iniset $ZAQAR_CONF DEFAULT log_file $ZAQAR_API_LOG_FILE
    iniset $ZAQAR_CONF 'drivers:transport:wsgi' bind $ZAQAR_SERVICE_HOST

    configure_auth_token_middleware $ZAQAR_CONF zaqar $ZAQAR_AUTH_CACHE_DIR

    if [ "$ZAQAR_BACKEND" = 'mysql' ] || [ "$ZAQAR_BACKEND" = 'postgresql' ] ; then
        iniset $ZAQAR_CONF drivers storage sqlalchemy
        iniset $ZAQAR_CONF 'drivers:storage:sqlalchemy' uri `database_connection_url zaqar`
    elif [ "$ZAQAR_BACKEND" = 'mongodb' ] ; then
        iniset $ZAQAR_CONF  drivers storage mongodb
        iniset $ZAQAR_CONF 'drivers:storage:mongodb' uri mongodb://localhost:27017/zaqar
        configure_mongodb
    elif [ "$ZAQAR_BACKEND" = 'redis' ] ; then
        iniset $ZAQAR_CONF  drivers storage redis
        iniset $ZAQAR_CONF 'drivers:storage:redis' uri redis://localhost:6379
        configure_redis
    fi

    cleanup_zaqar
}

function configure_redis {
    if is_ubuntu; then
        install_package redis-server
    elif is_fedora; then
        install_package redis
    else
        exit_distro_not_supported "redis installation"
    fi

    install_package python-redis
}

function configure_mongodb {
    # Set nssize to 2GB. This increases the number of namespaces supported
    # # per database.
    if is_ubuntu; then
        sudo sed -i -e "
            s|[^ \t]*#[ \t]*\(nssize[ \t]*=.*\$\)|\1|
            s|^\(nssize[ \t]*=[ \t]*\).*\$|\1 2047|
        " /etc/mongodb.conf
        restart_service mongodb
    elif is_fedora; then
        sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
        restart_service mongod
    fi
}

# init_zaqar() - Initialize etc.
function init_zaqar {
    # Create cache dir
    sudo mkdir -p $ZAQAR_AUTH_CACHE_DIR
    sudo chown $STACK_USER $ZAQAR_AUTH_CACHE_DIR
    rm -f $ZAQAR_AUTH_CACHE_DIR/*
}

# install_zaqar() - Collect source and prepare
function install_zaqar {
    git_clone $ZAQAR_REPO $ZAQAR_DIR $ZAQAR_BRANCH
    setup_develop $ZAQAR_DIR
}

# install_zaqarclient() - Collect source and prepare
function install_zaqarclient {
    git_clone $ZAQARCLIENT_REPO $ZAQARCLIENT_DIR $ZAQARCLIENT_BRANCH
    setup_develop $ZAQARCLIENT_DIR
}

# start_zaqar() - Start running processes, including screen
function start_zaqar {
    if [[ "$USE_SCREEN" = "False" ]]; then
        run_process zaqar-server "zaqar-server --config-file $ZAQAR_CONF --daemon"
    else
        run_process zaqar-server "zaqar-server --config-file $ZAQAR_CONF"
    fi

    echo "Waiting for Zaqar to start..."
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT/v1/health; do sleep 1; done"; then
        die $LINENO "Zaqar did not start"
    fi
}

# stop_zaqar() - Stop running processes
function stop_zaqar {
    local serv
    # Kill the zaqar screen windows
    for serv in zaqar-server; do
        screen -S $SCREEN_NAME -p $serv -X kill
    done
}

function create_zaqar_accounts {
    local service_tenant=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")

    local zaqar_user=$(get_or_create_user "zaqar" \
        "$SERVICE_PASSWORD" $service_tenant)
    get_or_add_user_role $ADMIN_ROLE $zaqar_user $service_tenant

    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then

        local zaqar_service=$(get_or_create_service "zaqar" \
            "messaging" "Zaqar Service")
        get_or_create_endpoint $zaqar_service \
            "$REGION_NAME" \
            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT" \
            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT" \
            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT"
    fi

}


# Restore xtrace
$XTRACE

# Local variables:
# mode: shell-script
# End:
