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


# 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" = 'mongodb' ]]; then
        iniset $MARCONI_CONF database connection 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 2>&1"
    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:
