#!/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
#
# To enable Ceilometer to collect the IPMI based meters, further add to the
# localrc section of local.conf:
#
#   enable_service ceilometer-aipmi
#
# NOTE: Currently, there are two ways to get the IPMI based meters in
# OpenStack. One way is to configure Ironic conductor to report those meters
# for the nodes managed by Ironic and to have Ceilometer notification
# agent to collect them. Ironic by default does NOT enable that reporting
# functionality. So in order to do so, users need to set the option of
# conductor.send_sensor_data to true in the ironic.conf configuration file
# for the Ironic conductor service, and also enable the
# ceilometer-anotification service.
#
# The other way is to use Ceilometer ipmi agent only to get the IPMI based
# meters. To avoid duplicated meters, users need to make sure to set the
# option of conductor.send_sensor_data to false in the ironic.conf
# configuration file if the node on which Ceilometer ipmi agent is running
# is also managed by Ironic.
#
# 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:  Seconds between pipeline processing runs. Default 600.
#   CEILOMETER_BACKEND:            Database backend (e.g. 'mysql', 'mongodb', 'es')
#   CEILOMETER_COORDINATION_URL:   URL for 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 oslo_policy 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

    if is_service_enabled ceilometer-aipmi; then
        # Configure rootwrap for the ipmi agent
        configure_rootwrap ceilometer $CEILOMETER_BIN_DIR/ceilometer-rootwrap $CEILOMETER_DIR/etc/ceilometer
    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 is 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
        # BUG: this should be a pip_install_gr except it was never
        # included in global-requirements. Needs to be fixed by
        # https://bugs.launchpad.net/ceilometer/+bug/1441655
        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"
    run_process ceilometer-aipmi "ceilometer-agent-ipmi --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-aipmi 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:
