# lib/horizon
# Functions to control the configuration and operation of the horizon service

# Dependencies:
#
# - ``functions`` file
# - ``apache`` file
# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must 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
# --------

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


# 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\    '$option': $value," $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

    # enable firewall dashboard in case service is enabled
    if is_service_enabled q-fwaas; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_firewall True
    fi

    # enable VPN dashboard in case service is enabled
    if is_service_enabled q-vpn; then
        _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_vpn 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

    # Apache 2.4 uses mod_authz_host for access control now (instead of "Allow")
    HORIZON_REQUIRE=''
    if check_apache_version "2.4" ; then
        HORIZON_REQUIRE='Require all granted'
    fi

    local horizon_conf=/etc/$APACHE_NAME/$APACHE_CONF_DIR/horizon.conf
    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 $horizon_conf
        sudo a2ensite horizon.conf
    elif is_fedora; then
        sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
    elif is_suse; then
        : # nothing to do
    else
        exit_distro_not_supported "horizon 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 >$horizon_conf"
}

# install_horizon() - Collect source and prepare
function install_horizon() {
    # Apache installation, because we mark it NOPRIME
    install_apache_wsgi

    # 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_apache_server
    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() {
    stop_apache_server
}


# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
