#!/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 ensure events are stored, add the following section to local.conf:
#
#   [[post-config|$CEILOMETER_CONF]]
#   [notification]
#   store_events=True
#
# 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')
#   CEILOMETER_COORDINATION_URL:   The URL for a group membership service provided
#                                  by tooz.


# 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

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_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 {

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

    # Ceilometer
    if [[ "$ENABLED_SERVICES" =~ "ceilometer-api" ]]; then
        local ceilometer_user=$(get_or_create_user "ceilometer" \
            "$SERVICE_PASSWORD" $service_tenant)
        get_or_add_user_role $admin_role $ceilometer_user $service_tenant

        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_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" != 'mysql' ] && [ "$CEILOMETER_BACKEND" != 'postgresql' ] ; then
        mongo ceilometer --eval "db.dropDatabase();"
    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 {
    [ ! -d $CEILOMETER_CONF_DIR ] && sudo mkdir -m 755 -p $CEILOMETER_CONF_DIR
    sudo chown $STACK_USER $CEILOMETER_CONF_DIR

    [ ! -d $CEILOMETER_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $CEILOMETER_API_LOG_DIR
    sudo chown $STACK_USER $CEILOMETER_API_LOG_DIR

    iniset_rpc_backend ceilometer $CEILOMETER_CONF DEFAULT

    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/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

    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
    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 mkdir -p $CEILOMETER_AUTH_CACHE_DIR
    sudo chown $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' ] ; 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
}

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

# 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 ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s http://localhost:8777/v2/ >/dev/null; do sleep 1; done"; 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:
