# 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

# 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() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_zaqar {
    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 use_syslog $SYSLOG
    iniset $ZAQAR_CONF DEFAULT log_file $ZAQAR_API_LOG_FILE
    iniset $ZAQAR_CONF 'drivers:transport:wsgi' bind $ZAQAR_SERVICE_HOST

    iniset $ZAQAR_CONF keystone_authtoken auth_protocol http
    iniset $ZAQAR_CONF keystone_authtoken admin_user zaqar
    iniset $ZAQAR_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
    iniset $ZAQAR_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
    iniset $ZAQAR_CONF keystone_authtoken signing_dir $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
        cleanup_zaqar
    fi
}

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
        screen_it zaqar-server "zaqar-server --config-file $ZAQAR_CONF --daemon"
    else
        screen_it 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 {
    # Kill the zaqar screen windows
    for serv in zaqar-server; do
        screen -S $SCREEN_NAME -p $serv -X kill
    done
}

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

    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

        ZAQAR_SERVICE=$(get_or_create_service "zaqar" \
            "queuing" "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:
