# lib/horizon
# Functions to control the configuration and operation of the horizon service
# <do not include this template file in ``stack.sh``!>

# Dependencies:
# ``functions`` file
# ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
# <list other global vars that are assumed to be defined>

# ``stack.sh`` calls the entry points in this order:
#
# install_horizon
# configure_horizon
# init_horizon
# start_horizon
# stop_horizon
# cleanup_horizon

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


# Defaults
# --------

# <define global variables here that belong to this project>

# Set up default directories
HORIZON_DIR=$DEST/horizon

# local_settings.py is used to customize Dashboard settings.
# The example file in Horizon repo is used by default.
HORIZON_SETTINGS=${HORIZON_SETTINGS:-$HORIZON_DIR/openstack_dashboard/local/local_settings.py.example}

# Allow overriding the default Apache user and group, default to
# current user and his default group.
APACHE_USER=${APACHE_USER:-$USER}
APACHE_GROUP=${APACHE_GROUP:-$(id -gn $APACHE_USER)}

# Set up service name and configuration path
if is_ubuntu; then
    APACHE_NAME=apache2
    APACHE_CONF=sites-available/horizon
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF=conf.d/horizon.conf
elif is_suse; then
    APACHE_NAME=apache2
    APACHE_CONF=vhosts.d/horizon.conf
fi


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

# utility method of setting python option
function _horizon_config_set() {
    local file=$1
    local section=$2
    local option=$3
    local value=$4

    if grep -q "^$section" $file; then
        line=$(sed -ne "/^$section/,/^}/ { /^ *'$option':/ p; }" $file)
        if [ -n "$line" ]; then
            sed -i -e "/^$section/,/^}/ s/^\( *'$option'\) *:.*$/\1: $value,/" $file
        else
            sed -i -e "/^$section/ a\n    '$option': $value,\n" $file
        fi
    else
        echo -e "\n\n$section = {\n    '$option': $value,\n}" >> $file
    fi
}



# Entry Points
# ------------

# cleanup_horizon() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_horizon() {
    if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
        # If ``/usr/bin/node`` points into ``$DEST``
        # we installed it via ``install_nodejs``
        if [[ $(readlink -f /usr/bin/node) =~ ($DEST) ]]; then
            sudo rm /usr/bin/node
        fi
    fi
}

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

# init_horizon() - Initialize databases, etc.
function init_horizon() {
    # Remove stale session database.
    rm -f $HORIZON_DIR/openstack_dashboard/local/dashboard_openstack.sqlite3

    # ``local_settings.py`` is used to override horizon default settings.
    local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
    cp $HORIZON_SETTINGS $local_settings

    if is_service_enabled neutron; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_security_group $Q_USE_SECGROUP
    fi
    # enable loadbalancer dashboard in case service is enabled
    if is_service_enabled q-lbaas; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_lb True
    fi

    # Initialize the horizon database (it stores sessions and notices shown to
    # users).  The user system is external (keystone).
    cd $HORIZON_DIR
    python manage.py syncdb --noinput
    cd $TOP_DIR

    # Create an empty directory that apache uses as docroot
    sudo mkdir -p $HORIZON_DIR/.blackhole

    HORIZON_REQUIRE=''
    if is_ubuntu; then
        # Clean up the old config name
        sudo rm -f /etc/apache2/sites-enabled/000-default
        # Be a good citizen and use the distro tools here
        sudo touch /etc/$APACHE_NAME/$APACHE_CONF
        sudo a2ensite horizon
        # WSGI isn't enabled by default, enable it
        sudo a2enmod wsgi
    elif is_fedora; then
        if [[ "$os_RELEASE" -ge "18" ]]; then
            # fedora 18 has Require all denied  in its httpd.conf
            # and requires explicit Require all granted
            HORIZON_REQUIRE='Require all granted'
        fi
        sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
    elif is_suse; then
        # WSGI isn't enabled by default, enable it
        sudo a2enmod wsgi
    else
        exit_distro_not_supported "apache configuration"
    fi

    # Remove old log files that could mess with how devstack detects whether Horizon
    # has been successfully started (see start_horizon() and functions::screen_it())
    sudo rm -f /var/log/$APACHE_NAME/horizon_*

    # Configure apache to run horizon
    sudo sh -c "sed -e \"
        s,%USER%,$APACHE_USER,g;
        s,%GROUP%,$APACHE_GROUP,g;
        s,%HORIZON_DIR%,$HORIZON_DIR,g;
        s,%APACHE_NAME%,$APACHE_NAME,g;
        s,%DEST%,$DEST,g;
        s,%HORIZON_REQUIRE%,$HORIZON_REQUIRE,g;
    \" $FILES/apache-horizon.template >/etc/$APACHE_NAME/$APACHE_CONF"
}

# install_horizon() - Collect source and prepare
function install_horizon() {
    # Apache installation, because we mark it NOPRIME
    if is_ubuntu; then
        # Install apache2, which is NOPRIME'd
        install_package apache2 libapache2-mod-wsgi
    elif is_fedora; then
        sudo rm -f /etc/httpd/conf.d/000-*
        install_package httpd mod_wsgi
    elif is_suse; then
        install_package apache2 apache2-mod_wsgi
    else
        exit_distro_not_supported "apache installation"
    fi

    # NOTE(sdague) quantal changed the name of the node binary
    if is_ubuntu; then
        if [[ ! -e "/usr/bin/node" ]]; then
            install_package nodejs-legacy
        fi
    elif is_fedora && [[ $DISTRO =~ (rhel6) || "$os_RELEASE" -ge "18" ]]; then
        install_package nodejs
    fi

    git_clone $HORIZON_REPO $HORIZON_DIR $HORIZON_BRANCH $HORIZON_TAG
}

# start_horizon() - Start running processes, including screen
function start_horizon() {
    restart_service $APACHE_NAME
    screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
}

# stop_horizon() - Stop running processes (non-screen)
function stop_horizon() {
    if [ -n "$APACHE_NAME" ]; then
        stop_service $APACHE_NAME
    else
        exit_distro_not_supported "apache configuration"
    fi
}


# Restore xtrace
$XTRACE

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