#!/bin/bash
#
# lib/ceilometer
# Install and start **Ceilometer** service

# To enable a minimal set of Ceilometer services, add the following to the
# localrc section of local.conf:
#
#   enable_service ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api
#
# To ensure Ceilometer alarming services are enabled also, further add to the
# localrc section of local.conf:
#
#   enable_service ceilometer-alarm-notifier ceilometer-alarm-evaluator
#
# Several variables set in the localrc section adjust common behaviors
# of Ceilometer (see within for additional settings):
#
#   CEILOMETER_USE_MOD_WSGI:       When True, run the api under mod_wsgi.
#   CEILOMETER_PIPELINE_INTERVAL:  The number of seconds between pipeline processing
#                                  runs. Default 600.
#   CEILOMETER_BACKEND:            The database backend (e.g. 'mysql', 'mongodb', 'es')
#   CEILOMETER_COORDINATION_URL:   The URL for a group membership service provided
#                                  by tooz.
#   CEILOMETER_EVENTS:             Enable event collection


# 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_ceilometer
# - configure_ceilometer
# - init_ceilometer
# - start_ceilometer
# - stop_ceilometer
# - cleanup_ceilometer

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


# Defaults
# --------

# Set up default directories
GITDIR["python-ceilometerclient"]=$DEST/python-ceilometerclient
GITDIR["ceilometermiddleware"]=$DEST/ceilometermiddleware

CEILOMETER_DIR=$DEST/ceilometer
CEILOMETER_CONF_DIR=/etc/ceilometer
CEILOMETER_CONF=$CEILOMETER_CONF_DIR/ceilometer.conf
CEILOMETER_API_LOG_DIR=/var/log/ceilometer-api
CEILOMETER_AUTH_CACHE_DIR=${CEILOMETER_AUTH_CACHE_DIR:-/var/cache/ceilometer}
CEILOMETER_WSGI_DIR=${CEILOMETER_WSGI_DIR:-/var/www/ceilometer}

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

# Set up database backend
CEILOMETER_BACKEND=${CEILOMETER_BACKEND:-mysql}

# Ceilometer connection info.
CEILOMETER_SERVICE_PROTOCOL=http
CEILOMETER_SERVICE_HOST=$SERVICE_HOST
CEILOMETER_SERVICE_PORT=${CEILOMETER_SERVICE_PORT:-8777}
CEILOMETER_USE_MOD_WSGI=$(trueorfalse False CEILOMETER_USE_MOD_WSGI)

# To enable OSprofiler change value of this variable to "notifications,profiler"
CEILOMETER_NOTIFICATION_TOPICS=${CEILOMETER_NOTIFICATION_TOPICS:-notifications}
CEILOMETER_EVENTS=${CEILOMETER_EVENTS:-True}

CEILOMETER_COORDINATION_URL=${CEILOMETER_COORDINATION_URL:-}
CEILOMETER_PIPELINE_INTERVAL=${CEILOMETER_PIPELINE_INTERVAL:-}

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


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

# Test if any Ceilometer services are enabled
# is_ceilometer_enabled
function is_ceilometer_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"ceilometer-" ]] && return 0
    return 1
}

# create_ceilometer_accounts() - Set up common required ceilometer accounts
#
# Project              User         Roles
# ------------------------------------------------------------------
# SERVICE_TENANT_NAME  ceilometer   admin
# SERVICE_TENANT_NAME  ceilometer   ResellerAdmin (if Swift is enabled)
function create_ceilometer_accounts {

    # Ceilometer
    if [[ "$ENABLED_SERVICES" =~ "ceilometer-api" ]]; then

        create_service_user "ceilometer" "admin"

        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
            local ceilometer_service=$(get_or_create_service "ceilometer" \
                "metering" "OpenStack Telemetry Service")
            get_or_create_endpoint $ceilometer_service \
                "$REGION_NAME" \
                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/" \
                "$CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/"
        fi
        if is_service_enabled swift; then
            # Ceilometer needs ResellerAdmin role to access swift account stats.
            get_or_add_user_project_role "ResellerAdmin" "ceilometer" $SERVICE_TENANT_NAME
        fi
    fi
}


# _cleanup_keystone_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_ceilometer_apache_wsgi {
    sudo rm -f $CEILOMETER_WSGI_DIR/*
    sudo rm -f $(apache_site_config_for ceilometer)
}

# cleanup_ceilometer() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_ceilometer {
    if [ "$CEILOMETER_BACKEND" = 'mongodb' ] ; then
        mongo ceilometer --eval "db.dropDatabase();"
    elif [ "$CEILOMETER_BACKEND" = 'es' ] ; then
        curl -XDELETE "localhost:9200/events_*"
    fi
    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
        _cleanup_ceilometer_apache_wsgi
    fi
}

function _config_ceilometer_apache_wsgi {
    sudo mkdir -p $CEILOMETER_WSGI_DIR

    local ceilometer_apache_conf=$(apache_site_config_for ceilometer)
    local apache_version=$(get_apache_version)

    # copy proxy vhost and wsgi file
    sudo cp $CEILOMETER_DIR/ceilometer/api/app.wsgi $CEILOMETER_WSGI_DIR/app

    sudo cp $FILES/apache-ceilometer.template $ceilometer_apache_conf
    sudo sed -e "
        s|%PORT%|$CEILOMETER_SERVICE_PORT|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%WSGIAPP%|$CEILOMETER_WSGI_DIR/app|g;
        s|%USER%|$STACK_USER|g
    " -i $ceilometer_apache_conf
}

# configure_ceilometer() - Set config files, create data dirs, etc
function configure_ceilometer {
    sudo install -d -o $STACK_USER -m 755 $CEILOMETER_CONF_DIR $CEILOMETER_API_LOG_DIR

    iniset_rpc_backend ceilometer $CEILOMETER_CONF

    iniset $CEILOMETER_CONF DEFAULT notification_topics "$CEILOMETER_NOTIFICATION_TOPICS"
    iniset $CEILOMETER_CONF DEFAULT verbose True
    iniset $CEILOMETER_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"

    if [[ -n "$CEILOMETER_COORDINATION_URL" ]]; then
        iniset $CEILOMETER_CONF coordination backend_url $CEILOMETER_COORDINATION_URL
        iniset $CEILOMETER_CONF compute workload_partitioning True
    fi

    # Install the policy file for the API server
    cp $CEILOMETER_DIR/etc/ceilometer/policy.json $CEILOMETER_CONF_DIR
    iniset $CEILOMETER_CONF DEFAULT policy_file $CEILOMETER_CONF_DIR/policy.json

    cp $CEILOMETER_DIR/etc/ceilometer/pipeline.yaml $CEILOMETER_CONF_DIR
    cp $CEILOMETER_DIR/etc/ceilometer/event_pipeline.yaml $CEILOMETER_CONF_DIR
    cp $CEILOMETER_DIR/etc/ceilometer/api_paste.ini $CEILOMETER_CONF_DIR
    cp $CEILOMETER_DIR/etc/ceilometer/event_definitions.yaml $CEILOMETER_CONF_DIR

    if [ "$CEILOMETER_PIPELINE_INTERVAL" ]; then
        sed -i "s/interval:.*/interval: ${CEILOMETER_PIPELINE_INTERVAL}/" $CEILOMETER_CONF_DIR/pipeline.yaml
    fi

    # the compute and central agents need these credentials in order to
    # call out to other services' public APIs
    # the alarm evaluator needs these options to call ceilometer APIs
    iniset $CEILOMETER_CONF service_credentials os_username ceilometer
    iniset $CEILOMETER_CONF service_credentials os_password $SERVICE_PASSWORD
    iniset $CEILOMETER_CONF service_credentials os_tenant_name $SERVICE_TENANT_NAME
    iniset $CEILOMETER_CONF service_credentials os_region_name $REGION_NAME
    iniset $CEILOMETER_CONF service_credentials os_auth_url $KEYSTONE_SERVICE_URI/v2.0

    configure_auth_token_middleware $CEILOMETER_CONF ceilometer $CEILOMETER_AUTH_CACHE_DIR

    iniset $CEILOMETER_CONF notification store_events $CEILOMETER_EVENTS

    if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] ; then
        iniset $CEILOMETER_CONF database alarm_connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF database event_connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF database metering_connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF DEFAULT collector_workers $API_WORKERS
    elif [ "$CEILOMETER_BACKEND" = 'es' ] ; then
        # es is only supported for events. we will use sql for alarming/metering.
        iniset $CEILOMETER_CONF database alarm_connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF database event_connection es://localhost:9200
        iniset $CEILOMETER_CONF database metering_connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF DEFAULT collector_workers $API_WORKERS
        ${TOP_DIR}/pkg/elasticsearch.sh start
        cleanup_ceilometer
    else
        iniset $CEILOMETER_CONF database alarm_connection mongodb://localhost:27017/ceilometer
        iniset $CEILOMETER_CONF database event_connection mongodb://localhost:27017/ceilometer
        iniset $CEILOMETER_CONF database metering_connection mongodb://localhost:27017/ceilometer
        configure_mongodb
        cleanup_ceilometer
    fi

    if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then
        iniset $CEILOMETER_CONF DEFAULT hypervisor_inspector vsphere
        iniset $CEILOMETER_CONF vmware host_ip "$VMWAREAPI_IP"
        iniset $CEILOMETER_CONF vmware host_username "$VMWAREAPI_USER"
        iniset $CEILOMETER_CONF vmware host_password "$VMWAREAPI_PASSWORD"
    fi

    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
        iniset $CEILOMETER_CONF api pecan_debug "False"
        _config_ceilometer_apache_wsgi
    fi
}

function configure_mongodb {
    # server package is the same on all
    local packages=mongodb-server

    if is_fedora; then
        # mongodb client + python bindings
        packages="${packages} mongodb pymongo"
    else
        packages="${packages} python-pymongo"
    fi

    install_package ${packages}

    if is_fedora; then
        # ensure smallfiles selected to minimize freespace requirements
        sudo sed -i '/--smallfiles/!s/OPTIONS=\"/OPTIONS=\"--smallfiles /' /etc/sysconfig/mongod

        restart_service mongod
    fi

    # give mongodb time to start-up
    sleep 5
}

# init_ceilometer() - Initialize etc.
function init_ceilometer {
    # Create cache dir
    sudo install -d -o $STACK_USER $CEILOMETER_AUTH_CACHE_DIR
    rm -f $CEILOMETER_AUTH_CACHE_DIR/*

    if is_service_enabled mysql postgresql; then
        if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] || [ "$CEILOMETER_BACKEND" = 'es' ] ; then
            recreate_database ceilometer
            $CEILOMETER_BIN_DIR/ceilometer-dbsync
        fi
    fi
}

# install_redis() - Install the redis server.
function install_redis {
    if is_ubuntu; then
        install_package redis-server
        restart_service redis-server
    else
        # This will fail (correctly) where a redis package is unavailable
        install_package redis
        restart_service redis
    fi
}

# install_ceilometer() - Collect source and prepare
function install_ceilometer {
    git_clone $CEILOMETER_REPO $CEILOMETER_DIR $CEILOMETER_BRANCH
    setup_develop $CEILOMETER_DIR

    if echo $CEILOMETER_COORDINATION_URL | grep -q '^memcached:'; then
        install_package memcached
    elif echo $CEILOMETER_COORDINATION_URL | grep -q '^redis:'; then
        install_redis
    fi

    if [ "$CEILOMETER_BACKEND" = 'es' ] ; then
        ${TOP_DIR}/pkg/elasticsearch.sh download
        ${TOP_DIR}/pkg/elasticsearch.sh install
    fi
}

# install_ceilometerclient() - Collect source and prepare
function install_ceilometerclient {
    if use_library_from_git "python-ceilometerclient"; then
        git_clone_by_name "python-ceilometerclient"
        setup_dev_lib "python-ceilometerclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-ceilometerclient"]}/tools/,/etc/bash_completion.d/}ceilometer.bash_completion
    fi
}

# install_ceilometermiddleware() - Collect source and prepare
function install_ceilometermiddleware {
    if use_library_from_git "ceilometermiddleware"; then
        git_clone_by_name "ceilometermiddleware"
        setup_dev_lib "ceilometermiddleware"
    else
        pip_install ceilometermiddleware
    fi
}

# start_ceilometer() - Start running processes, including screen
function start_ceilometer {
    run_process ceilometer-acentral "ceilometer-agent-central --config-file $CEILOMETER_CONF"
    run_process ceilometer-anotification "ceilometer-agent-notification --config-file $CEILOMETER_CONF"
    run_process ceilometer-collector "ceilometer-collector --config-file $CEILOMETER_CONF"

    if [[ "$CEILOMETER_USE_MOD_WSGI" == "False" ]]; then
        run_process ceilometer-api "ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
    else
        enable_apache_site ceilometer
        restart_apache_server
        tail_log ceilometer /var/log/$APACHE_NAME/ceilometer.log
        tail_log ceilometer-api /var/log/$APACHE_NAME/ceilometer_access.log
    fi


    # Start the compute agent last to allow time for the collector to
    # fully wake up and connect to the message bus. See bug #1355809
    if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
        run_process ceilometer-acompute "ceilometer-agent-compute --config-file $CEILOMETER_CONF" $LIBVIRT_GROUP
    fi
    if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then
        run_process ceilometer-acompute "ceilometer-agent-compute --config-file $CEILOMETER_CONF"
    fi

    # only die on API if it was actually intended to be turned on
    if is_service_enabled ceilometer-api; then
        echo "Waiting for ceilometer-api to start..."
        if ! wait_for_service $SERVICE_TIMEOUT $CEILOMETER_SERVICE_PROTOCOL://$CEILOMETER_SERVICE_HOST:$CEILOMETER_SERVICE_PORT/v2/; then
            die $LINENO "ceilometer-api did not start"
        fi
    fi

    run_process ceilometer-alarm-notifier "ceilometer-alarm-notifier --config-file $CEILOMETER_CONF"
    run_process ceilometer-alarm-evaluator "ceilometer-alarm-evaluator --config-file $CEILOMETER_CONF"
}

# stop_ceilometer() - Stop running processes
function stop_ceilometer {
    if [ "$CEILOMETER_USE_MOD_WSGI" == "True" ]; then
        disable_apache_site ceilometer
        restart_apache_server
    fi
    # Kill the ceilometer screen windows
    for serv in ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-evaluator; do
        stop_process $serv
    done
}


# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
