#!/bin/bash
#
# lib/sahara

# Dependencies:
# ``functions`` file
# ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined

# ``stack.sh`` calls the entry points in this order:
#
# install_sahara
# install_python_saharaclient
# configure_sahara
# start_sahara
# stop_sahara
# cleanup_sahara

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


# Defaults
# --------

# Set up default repos

# Set up default directories
GITDIR["python-saharaclient"]=$DEST/python-saharaclient
SAHARA_DIR=$DEST/sahara

SAHARA_CONF_DIR=${SAHARA_CONF_DIR:-/etc/sahara}
SAHARA_CONF_FILE=${SAHARA_CONF_DIR}/sahara.conf

SAHARA_SERVICE_HOST=${SAHARA_SERVICE_HOST:-$SERVICE_HOST}
SAHARA_SERVICE_PORT=${SAHARA_SERVICE_PORT:-8386}
SAHARA_SERVICE_PROTOCOL=${SAHARA_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

SAHARA_AUTH_CACHE_DIR=${SAHARA_AUTH_CACHE_DIR:-/var/cache/sahara}

SAHARA_ENABLED_PLUGINS=${SAHARA_ENABLED_PLUGINS:-vanilla,hdp,fake}

# Support entry points installation of console scripts
if [[ -d $SAHARA_DIR/bin ]]; then
    SAHARA_BIN_DIR=$SAHARA_DIR/bin
else
    SAHARA_BIN_DIR=$(get_python_exec_prefix)
fi

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

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

# create_sahara_accounts() - Set up common required sahara accounts
#
# Tenant      User       Roles
# ------------------------------
# service     sahara    admin
function create_sahara_accounts {

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

    local sahara_user=$(get_or_create_user "sahara" \
        "$SERVICE_PASSWORD" $service_tenant)
    get_or_add_user_role $admin_role $sahara_user $service_tenant

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

        local sahara_service=$(get_or_create_service "sahara" \
            "data_processing" "Sahara Data Processing")
        get_or_create_endpoint $sahara_service \
            "$REGION_NAME" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s"
    fi
}

# cleanup_sahara() - Remove residual data files, anything left over from
# previous runs that would need to clean up.
function cleanup_sahara {

    # Cleanup auth cache dir
    sudo rm -rf $SAHARA_AUTH_CACHE_DIR
}

# configure_sahara() - Set config files, create data dirs, etc
function configure_sahara {

    if [[ ! -d $SAHARA_CONF_DIR ]]; then
        sudo mkdir -p $SAHARA_CONF_DIR
    fi
    sudo chown $STACK_USER $SAHARA_CONF_DIR

    if [[ -f $SAHARA_DIR/etc/sahara/policy.json ]]; then
        cp -p $SAHARA_DIR/etc/sahara/policy.json $SAHARA_CONF_DIR
    fi

    # Copy over sahara configuration file and configure common parameters.
    cp $SAHARA_DIR/etc/sahara/sahara.conf.sample $SAHARA_CONF_FILE

    # Create auth cache dir
    sudo mkdir -p $SAHARA_AUTH_CACHE_DIR
    sudo chown $STACK_USER $SAHARA_AUTH_CACHE_DIR
    sudo chmod 700 $SAHARA_AUTH_CACHE_DIR
    rm -rf $SAHARA_AUTH_CACHE_DIR/*

    configure_auth_token_middleware $SAHARA_CONF_FILE sahara $SAHARA_AUTH_CACHE_DIR

    # Set configuration to send notifications

    if is_service_enabled ceilometer; then
        iniset $SAHARA_CONF_FILE DEFAULT enable_notifications "true"
        iniset $SAHARA_CONF_FILE DEFAULT notification_driver "messaging"
        iniset_rpc_backend sahara $SAHARA_CONF_FILE DEFAULT
    fi

    iniset $SAHARA_CONF_FILE DEFAULT verbose True
    iniset $SAHARA_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL

    iniset $SAHARA_CONF_FILE DEFAULT plugins $SAHARA_ENABLED_PLUGINS

    iniset $SAHARA_CONF_FILE database connection `database_connection_url sahara`

    if is_service_enabled neutron; then
        iniset $SAHARA_CONF_FILE DEFAULT use_neutron true
        iniset $SAHARA_CONF_FILE DEFAULT use_floating_ips true
    fi

    if is_service_enabled heat; then
        iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine heat
    else
        iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine direct
    fi

    iniset $SAHARA_CONF_FILE DEFAULT use_syslog $SYSLOG

    # Format logging
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
        setup_colorized_logging $SAHARA_CONF_FILE DEFAULT
    fi

    recreate_database sahara utf8
    $SAHARA_BIN_DIR/sahara-db-manage --config-file $SAHARA_CONF_FILE upgrade head
}

# install_sahara() - Collect source and prepare
function install_sahara {
    git_clone $SAHARA_REPO $SAHARA_DIR $SAHARA_BRANCH
    setup_develop $SAHARA_DIR
}

# install_python_saharaclient() - Collect source and prepare
function install_python_saharaclient {
    if use_library_from_git "python-saharaclient"; then
        git_clone_by_name "python-saharaclient"
        setup_dev_lib "python-saharaclient"
    fi
}

# start_sahara() - Start running processes, including screen
function start_sahara {
    run_process sahara "$SAHARA_BIN_DIR/sahara-all --config-file $SAHARA_CONF_FILE"
}

# stop_sahara() - Stop running processes
function stop_sahara {
    # Kill the Sahara screen windows
    screen -S $SCREEN_NAME -p sahara -X kill
}


# Restore xtrace
$XTRACE

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