# 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
SAHARA_REPO=${SAHARA_REPO:-${GIT_BASE}/openstack/sahara.git}
SAHARA_BRANCH=${SAHARA_BRANCH:-master}

SAHARA_PYTHONCLIENT_REPO=${SAHARA_PYTHONCLIENT_REPO:-${GIT_BASE}/openstack/python-saharaclient.git}
SAHARA_PYTHONCLIENT_BRANCH=${SAHARA_PYTHONCLIENT_BRANCH:-master}

# Set up default directories
SAHARA_DIR=$DEST/sahara
SAHARA_PYTHONCLIENT_DIR=$DEST/python-saharaclient

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 {
    git_clone $SAHARA_PYTHONCLIENT_REPO $SAHARA_PYTHONCLIENT_DIR $SAHARA_PYTHONCLIENT_BRANCH
    setup_develop $SAHARA_PYTHONCLIENT_DIR
}

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