#!/bin/bash
#
# 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:
#
# - 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=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/sites-available}
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/conf.d}
elif is_suse; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/vhosts.d}
fi

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

    # ensure mod_version enabled for <IfVersion ...>.  This is
    # built-in statically on anything recent, but precise (2.2)
    # doesn't have it enabled
    sudo a2enmod version || true
}

# get_apache_version() - return the version of Apache installed
# This function is used to determine the Apache version installed. There are
# various differences between Apache 2.2 and 2.4 that warrant special handling.
function get_apache_version {
    if is_ubuntu; then
        local version_str=$(sudo /usr/sbin/apache2ctl -v | awk '/Server version/ {print $3}' | cut -f2 -d/)
    elif is_fedora; then
        local version_str=$(rpm -qa --queryformat '%{VERSION}' httpd)
    elif is_suse; then
        local version_str=$(rpm -qa --queryformat '%{VERSION}' apache2)
    else
        exit_distro_not_supported "cannot determine apache version"
    fi
    if [[ "$version_str" =~ ^2\.2\. ]]; then
        echo "2.2"
    elif [[ "$version_str" =~ ^2\.4\. ]]; then
        echo "2.4"
    else
        exit_distro_not_supported "apache version not supported"
    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 and openSUSE, 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=$(get_apache_version)
        if [[ "$apache_version" == "2.2" ]]; then
            # Ubuntu 12.04 - Apache 2.2
            echo $APACHE_CONF_DIR/${site}
        else
            # Ubuntu 14.04 - Apache 2.4
            echo $APACHE_CONF_DIR/${site}.conf
        fi
    elif is_fedora || is_suse; then
        # fedora conf.d is only imported if it ends with .conf so this is approx the same
        local enabled_site_file="$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 || is_suse; then
        local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
        # Do nothing if site already enabled or no site config exists
        if [[ -f ${enabled_site_file}.disabled ]] && [[ ! -f ${enabled_site_file} ]]; then
            sudo mv ${enabled_site_file}.disabled ${enabled_site_file}
        fi
    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 || is_suse; then
        local enabled_site_file="$APACHE_CONF_DIR/${site}.conf"
        # Do nothing if no site config exists
        if [[ -f ${enabled_site_file} ]]; then
            sudo mv ${enabled_site_file} ${enabled_site_file}.disabled
        fi
    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 {
    # Apache can be slow to stop, doing an explicit stop, sleep, start helps
    # to mitigate issues where apache will claim a port it's listening on is
    # still in use and fail to start.
    stop_service $APACHE_NAME
    sleep 3
    start_service $APACHE_NAME
}

# Restore xtrace
$XTRACE

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