# lib/marconi
# Install and start **Marconi** service

# To enable a minimal set of Marconi services, add the following to localrc:
#
#     enable_service marconi-server
#
# 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_marconi
# configure_marconi
# init_marconi
# start_marconi
# stop_marconi
# cleanup_marconi

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


# Defaults
# --------

# Set up default directories
MARCONI_DIR=$DEST/marconi
MARCONICLIENT_DIR=$DEST/python-marconiclient
MARCONI_CONF_DIR=/etc/marconi
MARCONI_CONF=$MARCONI_CONF_DIR/marconi.conf
MARCONI_API_LOG_DIR=/var/log/marconi
MARCONI_API_LOG_FILE=$MARCONI_API_LOG_DIR/queues.log
MARCONI_AUTH_CACHE_DIR=${MARCONI_AUTH_CACHE_DIR:-/var/cache/marconi}

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

# Set up database backend
MARCONI_BACKEND=${MARCONI_BACKEND:-sqlite}


# Set Marconi repository
MARCONI_REPO=${MARCONI_REPO:-${GIT_BASE}/openstack/marconi.git}
MARCONI_BRANCH=${MARCONI_BRANCH:-master}

# Set client library repository
MARCONICLIENT_REPO=${MARCONICLIENT_REPO:-${GIT_BASE}/openstack/python-marconiclient.git}
MARCONICLIENT_BRANCH=${MARCONICLIENT_BRANCH:-master}

# Set Marconi Connection Info
MARCONI_SERVICE_HOST=${MARCONI_SERVICE_HOST:-$SERVICE_HOST}
MARCONI_SERVICE_PORT=${MARCONI_SERVICE_PORT:-8888}
MARCONI_SERVICE_PROTOCOL=${MARCONI_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

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


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

# Test if any Marconi services are enabled
# is_marconi_enabled
function is_marconi_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"marconi-" ]] && return 0
    return 1
}

# cleanup_marconi() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_marconi {
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! mongo marconi --eval 'db.dropDatabase();'; do sleep 1; done"; then
        die $LINENO "Mongo DB did not start"
    fi
}

# configure_marconiclient() - Set config files, create data dirs, etc
function configure_marconiclient {
    setup_develop $MARCONICLIENT_DIR
}

# configure_marconi() - Set config files, create data dirs, etc
function configure_marconi {
    setup_develop $MARCONI_DIR

    [ ! -d $MARCONI_CONF_DIR ] && sudo mkdir -m 755 -p $MARCONI_CONF_DIR
    sudo chown $USER $MARCONI_CONF_DIR

    [ ! -d $MARCONI_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $MARCONI_API_LOG_DIR
    sudo chown $USER $MARCONI_API_LOG_DIR

    iniset $MARCONI_CONF DEFAULT verbose True
    iniset $MARCONI_CONF DEFAULT use_syslog $SYSLOG
    iniset $MARCONI_CONF DEFAULT log_file $MARCONI_API_LOG_FILE
    iniset $MARCONI_CONF 'drivers:transport:wsgi' bind $MARCONI_SERVICE_HOST

    iniset $MARCONI_CONF keystone_authtoken auth_protocol http
    iniset $MARCONI_CONF keystone_authtoken admin_user marconi
    iniset $MARCONI_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
    iniset $MARCONI_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
    iniset $MARCONI_CONF keystone_authtoken signing_dir $MARCONI_AUTH_CACHE_DIR

    if [ "$MARCONI_BACKEND" = 'mysql' ] || [ "$MARCONI_BACKEND" = 'postgresql' ] ; then
        iniset $MARCONI_CONF drivers storage sqlalchemy
        iniset $MARCONI_CONF 'drivers:storage:sqlalchemy' uri `database_connection_url marconi`
    elif [ "$MARCONI_BACKEND" = 'mongodb' ] ; then
        iniset $MARCONI_CONF  drivers storage mongodb
        iniset $MARCONI_CONF 'drivers:storage:mongodb' uri mongodb://localhost:27017/marconi
        configure_mongodb
        cleanup_marconi
    fi
}

function configure_mongodb {
    # Set nssize to 2GB. This increases the number of namespaces supported
    # # per database.
    if is_ubuntu; then
        sudo sed -i -e "
            s|[^ \t]*#[ \t]*\(nssize[ \t]*=.*\$\)|\1|
            s|^\(nssize[ \t]*=[ \t]*\).*\$|\1 2047|
        " /etc/mongodb.conf
        restart_service mongodb
    elif is_fedora; then
        sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
        restart_service mongod
    fi
}

# init_marconi() - Initialize etc.
function init_marconi {
    # Create cache dir
    sudo mkdir -p $MARCONI_AUTH_CACHE_DIR
    sudo chown $STACK_USER $MARCONI_AUTH_CACHE_DIR
    rm -f $MARCONI_AUTH_CACHE_DIR/*
}

# install_marconi() - Collect source and prepare
function install_marconi {
    git_clone $MARCONI_REPO $MARCONI_DIR $MARCONI_BRANCH
    setup_develop $MARCONI_DIR
}

# install_marconiclient() - Collect source and prepare
function install_marconiclient {
    git_clone $MARCONICLIENT_REPO $MARCONICLIENT_DIR $MARCONICLIENT_BRANCH
    setup_develop $MARCONICLIENT_DIR
}

# start_marconi() - Start running processes, including screen
function start_marconi {
    screen_it marconi-server "marconi-server --config-file $MARCONI_CONF --daemon"
    echo "Waiting for Marconi to start..."
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT/v1/health; do sleep 1; done"; then
        die $LINENO "Marconi did not start"
    fi
}

# stop_marconi() - Stop running processes
function stop_marconi {
    # Kill the marconi screen windows
    for serv in marconi-server; do
        screen -S $SCREEN_NAME -p $serv -X kill
    done
}

function create_marconi_accounts {
    SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")

    MARCONI_USER=$(openstack user create \
        marconi \
        --password "$SERVICE_PASSWORD" \
        --project $SERVICE_TENANT \
        --email marconi@example.com \
        | grep " id " | get_field 2)
    openstack role add \
        $ADMIN_ROLE \
        --project $SERVICE_TENANT \
        --user $MARCONI_USER

    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
        MARCONI_SERVICE=$(openstack service create \
            marconi \
            --type=queuing \
            --description="Marconi Service" \
            | grep " id " | get_field 2)
        openstack endpoint create \
            $MARCONI_SERVICE \
            --region RegionOne \
            --publicurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
            --adminurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
            --internalurl "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT"
    fi

}


# Restore xtrace
$XTRACE

# Local variables:
# mode: shell-script
# End:
