# lib/apache
# Functions to control configuration and operation of apache web server

# Dependencies:
#
# - ``functions`` file
# - ``STACK_USER`` must be defined
#
# lib/apache exports the following functions:
#
# - is_apache_enabled_service
# - install_apache_wsgi
# - config_apache_wsgi
# - apache_site_config_for
# - enable_apache_site
# - disable_apache_site
# - start_apache_server
# - stop_apache_server
# - restart_apache_server

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

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


# Set up apache name and configuration directory
if is_ubuntu; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=sites-available
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF_DIR=conf.d
elif is_suse; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=vhosts.d
fi

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

# is_apache_enabled_service() checks if the service(s) specified as arguments are
# apache enabled by the user in ``APACHE_ENABLED_SERVICES`` as web front end.
#
# Multiple services specified as arguments are ``OR``'ed together; the test
# is a short-circuit boolean, i.e it returns on the first match.
#
# Uses global ``APACHE_ENABLED_SERVICES``
# APACHE_ENABLED_SERVICES service [service ...]
function is_apache_enabled_service {
    services=$@
    for service in ${services}; do
        [[ ,${APACHE_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
    done
    return 1
}

# install_apache_wsgi() - Install Apache server and wsgi module
function install_apache_wsgi {
    # Apache installation, because we mark it NOPRIME
    if is_ubuntu; then
        # Install apache2, which is NOPRIME'd
        install_package apache2 libapache2-mod-wsgi
        # WSGI isn't enabled by default, enable it
        sudo a2enmod 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
        # WSGI isn't enabled by default, enable it
        sudo a2enmod wsgi
    else
        exit_distro_not_supported "apache installation"
    fi
}

# apache_site_config_for() - The filename of the site's configuration file.
# This function uses the global variables APACHE_NAME and APACHE_CONF_DIR.
#
# On Ubuntu 14.04, the site configuration file must have a .conf suffix for a2ensite and a2dissite to
# recognise it. a2ensite and a2dissite ignore the .conf suffix used as parameter. The default sites'
# files are 000-default.conf and default-ssl.conf.
#
# On Ubuntu 12.04, the site configuration file may have any format, as long as it is in
# /etc/apache2/sites-available/. a2ensite and a2dissite need the entire file name to work. The default
# sites' files are default and default-ssl.
#
# On Fedora, any file in /etc/httpd/conf.d/ whose name ends with .conf is enabled.
#
# On RHEL and CentOS, things should hopefully work as in Fedora.
#
# The table below summarizes what should happen on each distribution:
# +----------------------+--------------------+--------------------------+--------------------------+
# | Distribution         | File name          | Site enabling command    | Site disabling command   |
# +----------------------+--------------------+--------------------------+--------------------------+
# | Ubuntu 12.04         | site               | a2ensite site            | a2dissite site           |
# | Ubuntu 14.04         | site.conf          | a2ensite site            | a2dissite site           |
# | Fedora, RHEL, CentOS | site.conf.disabled | mv site.conf{.disabled,} | mv site.conf{,.disabled} |
# +----------------------+--------------------+--------------------------+--------------------------+
function apache_site_config_for {
    local site=$@
    if is_ubuntu; then
        local apache_version=$(sudo /usr/sbin/apache2ctl -v | awk '/Server version/ {print $3}' | cut -f2 -d/)
        if [[ "$apache_version" =~ ^2\.2\. ]]; then
            # Ubuntu 12.04 - Apache 2.2
            echo /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}
        else
            # Ubuntu 14.04 - Apache 2.4
            echo /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf
        fi
    elif is_fedora; then
        # fedora conf.d is only imported if it ends with .conf so this is approx the same
        local enabled_site_file="/etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf"
        if [ -f $enabled_site_file ]; then
            echo ${enabled_site_file}
        else
            echo ${enabled_site_file}.disabled
        fi
    fi
}

# enable_apache_site() - Enable a particular apache site
function enable_apache_site {
    local site=$@
    if is_ubuntu; then
        sudo a2ensite ${site}
    elif is_fedora; then
        # fedora conf.d is only imported if it ends with .conf so this is approx the same
        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf.disabled /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf
    fi
}

# disable_apache_site() - Disable a particular apache site
function disable_apache_site {
    local site=$@
    if is_ubuntu; then
        sudo a2dissite ${site}
    elif is_fedora; then
        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf.disabled
    fi
}

# start_apache_server() - Start running apache server
function start_apache_server {
    start_service $APACHE_NAME
}

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

# restart_apache_server
function restart_apache_server {
    restart_service $APACHE_NAME
}

# Restore xtrace
$XTRACE

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