# lib/ceilometer
# Install and start **Ceilometer** service

# To enable a minimal set of Ceilometer services, add the following to localrc:
#
#   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:
#
#   enable_service ceilometer-alarm-notifier ceilometer-alarm-evaluator

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

# 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

    configure_auth_token_middleware $CEILOMETER_CONF ceilometer $CEILOMETER_AUTH_CACHE_DIR

    if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] ; then
        iniset $CEILOMETER_CONF database connection $(database_connection_url ceilometer)
        iniset $CEILOMETER_CONF DEFAULT collector_workers $API_WORKERS
    else
        iniset $CEILOMETER_CONF database 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 utf8
            $CEILOMETER_BIN_DIR/ceilometer-dbsync
        fi
    fi
}

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

    restart_service redis
}

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