#!/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
# - apache_site_config_for
# - enable_apache_site
# - disable_apache_site
# - start_apache_server
# - stop_apache_server
# - restart_apache_server

# Save trace setting
_XTRACE_LIB_APACHE=$(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)}

APACHE_LOCAL_HOST=$SERVICE_LOCAL_HOST
if [[ "$SERVICE_IP_VERSION" == 6 ]]; then
    APACHE_LOCAL_HOST=[$APACHE_LOCAL_HOST]
fi


# Set up apache name and configuration directory
# Note that APACHE_CONF_DIR is really more accurately apache's vhost
# configuration dir but we can't just change this because public interfaces.
if is_ubuntu; then
    APACHE_NAME=apache2
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/sites-available}
    APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf-enabled}
elif is_fedora; then
    APACHE_NAME=httpd
    APACHE_CONF_DIR=${APACHE_CONF_DIR:-/etc/$APACHE_NAME/conf.d}
    APACHE_SETTINGS_DIR=${APACHE_SETTINGS_DIR:-/etc/$APACHE_NAME/conf.d}
fi
APACHE_LOG_DIR="/var/log/${APACHE_NAME}"

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

# Enable apache mod and restart apache if it isn't already enabled.
function enable_apache_mod {
    local mod=$1
    local should_restart=$2
    # Apache installation, because we mark it NOPRIME
    if is_ubuntu; then
        # Skip mod_version as it is not a valid mod to enable
        # on debuntu, instead it is built in.
        if [[ "$mod" != "version" ]] && ! a2query -m $mod ; then
            sudo a2enmod $mod
            if [[ "$should_restart" != "norestart" ]] ; then
                restart_apache_server
            fi
        fi
    elif is_fedora; then
        # pass
        true
    else
        exit_distro_not_supported "apache enable mod"
    fi
}

# NOTE(sdague): Install uwsgi including apache module, we need to get
# to 2.0.6+ to get a working mod_proxy_uwsgi. We can probably build a
# check for that and do it differently for different platforms.
function install_apache_uwsgi {
    local apxs="apxs2"
    if is_fedora; then
        apxs="apxs"
    fi

    if is_ubuntu; then
        local pkg_list="uwsgi uwsgi-plugin-python3 libapache2-mod-proxy-uwsgi"
        install_package ${pkg_list}
    # NOTE(ianw) 2022-02-03 : Fedora 35 needs to skip this and fall
    # into the install-from-source because the upstream packages
    # didn't fix Python 3.10 compatibility before release.  Should be
    # fixed in uwsgi 4.9.0; can remove this when packages available
    # or we drop this release
    elif is_fedora && ! is_openeuler && ! [[ $DISTRO =~ f36 ]]; then
        # Note httpd comes with mod_proxy_uwsgi and it is loaded by
        # default; the mod_proxy_uwsgi package actually conflicts now.
        # See:
        #  https://bugzilla.redhat.com/show_bug.cgi?id=1574335
        #
        # Thus there is nothing else to do after this install
        install_package uwsgi \
                        uwsgi-plugin-python3
    else
        # Compile uwsgi from source.
        local dir
        dir=$(mktemp -d)
        pushd $dir
        pip_install uwsgi
        pip download uwsgi -c $REQUIREMENTS_DIR/upper-constraints.txt
        local uwsgi
        uwsgi=$(ls uwsgi*)
        tar xvf $uwsgi
        cd uwsgi*/apache2
        sudo $apxs -i -c mod_proxy_uwsgi.c
        popd
        # delete the temp directory
        sudo rm -rf $dir
    fi

    if is_ubuntu; then
        if ! a2query -m proxy || ! a2query -m proxy_uwsgi ; then
            # we've got to enable proxy and proxy_uwsgi for this to work
            sudo a2enmod proxy
            sudo a2enmod proxy_uwsgi
            restart_apache_server
        fi
    fi
}

# 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
        if is_package_installed libapache2-mod-wsgi; then
            uninstall_package libapache2-mod-wsgi
        fi
        install_package libapache2-mod-wsgi-py3
    elif is_fedora; then
        sudo rm -f /etc/httpd/conf.d/000-*
        install_package httpd python3-mod_wsgi
        # rpm distros dont enable httpd by default so enable it to support reboots.
        sudo systemctl enable httpd
        # For consistency with Ubuntu, switch to the worker mpm, as
        # the default is event
        sudo sed -i '/mod_mpm_prefork.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
        sudo sed -i '/mod_mpm_event.so/s/^/#/g' /etc/httpd/conf.modules.d/00-mpm.conf
        sudo sed -i '/mod_mpm_worker.so/s/^#//g' /etc/httpd/conf.modules.d/00-mpm.conf
    else
        exit_distro_not_supported "apache wsgi installation"
    fi
    # WSGI isn't enabled by default, enable it
    enable_apache_mod wsgi
}

# 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 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 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
        # Ubuntu 14.04 - Apache 2.4
        echo $APACHE_CONF_DIR/${site}.conf
    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="$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=$@
    # Many of our sites use mod version. Just enable it.
    enable_apache_mod version
    if is_ubuntu; then
        sudo a2ensite ${site}
    elif is_fedora; 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} || true
    elif is_fedora; 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.
    restart_service $APACHE_NAME
}

# write_uwsgi_config() - Create a new uWSGI config file
function write_uwsgi_config {
    local conf=$1
    local wsgi=$2
    local url=$3
    local http=$4
    local name=$5

    if [ -z "$name" ]; then
        name=$(basename $wsgi)
    fi

    # create a home for the sockets; note don't use /tmp -- apache has
    # a private view of it on some platforms.
    local socket_dir='/var/run/uwsgi'

    # /var/run will be empty on ubuntu after reboot, so we can use systemd-temptiles
    # to automatically create $socket_dir.
    sudo mkdir -p /etc/tmpfiles.d/
    echo "d $socket_dir 0755 $STACK_USER root" | sudo tee /etc/tmpfiles.d/uwsgi.conf
    sudo systemd-tmpfiles --create /etc/tmpfiles.d/uwsgi.conf

    local socket="$socket_dir/${name}.socket"

    # always cleanup given that we are using iniset here
    rm -rf $conf
    # Set either the module path or wsgi script path depending on what we've
    # been given. Note that the regex isn't exhaustive - neither Python modules
    # nor Python variables can start with a number - but it's "good enough"
    if [[ "$wsgi" =~ ^[a-zA-Z0-9_.]+:[a-zA-Z0-9_]+$ ]]; then
        iniset "$conf" uwsgi module "$wsgi"
    else
        deprecated 'Configuring uWSGI with a WSGI file is deprecated, use module paths instead'
        iniset "$conf" uwsgi wsgi-file "$wsgi"
    fi
    iniset "$conf" uwsgi processes $API_WORKERS
    # This is running standalone
    iniset "$conf" uwsgi master true
    # Set die-on-term & exit-on-reload so that uwsgi shuts down
    iniset "$conf" uwsgi die-on-term true
    iniset "$conf" uwsgi exit-on-reload false
    # Set worker-reload-mercy so that worker will not exit till the time
    # configured after graceful shutdown
    iniset "$conf" uwsgi worker-reload-mercy $WORKER_TIMEOUT
    iniset "$conf" uwsgi enable-threads true
    iniset "$conf" uwsgi plugins http,python3
    # uwsgi recommends this to prevent thundering herd on accept.
    iniset "$conf" uwsgi thunder-lock true
    # Set hook to trigger graceful shutdown on SIGTERM
    iniset "$conf" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
    # Override the default size for headers from the 4k default.
    iniset "$conf" uwsgi buffer-size 65535
    # Make sure the client doesn't try to re-use the connection.
    iniset "$conf" uwsgi add-header "Connection: close"
    # This ensures that file descriptors aren't shared between processes.
    iniset "$conf" uwsgi lazy-apps true
    # Starting time of the WSGi server
    iniset "$conf" uwsgi start-time %t

    # If we said bind directly to http, then do that and don't start the apache proxy
    if [[ -n "$http" ]]; then
        iniset "$conf" uwsgi http $http
    else
        local apache_conf=""
        apache_conf=$(apache_site_config_for $name)
        iniset "$conf" uwsgi socket "$socket"
        iniset "$conf" uwsgi chmod-socket 666
        echo "ProxyPass \"${url}\" \"unix:${socket}|uwsgi://uwsgi-uds-${name}\" retry=0 acquire=1 " | sudo tee -a $apache_conf
        enable_apache_site $name
        restart_apache_server
    fi
}

# For services using chunked encoding, the only services known to use this
# currently are Glance and Swift, we need to use an http proxy instead of
# mod_proxy_uwsgi because the chunked encoding gets dropped. See:
# https://github.com/unbit/uwsgi/issues/1540.
function write_local_uwsgi_http_config {
    local conf=$1
    local wsgi=$2
    local url=$3
    local name=$4

    if [ -z "$name" ]; then
        name=$(basename $wsgi)
    fi

    # create a home for the sockets; note don't use /tmp -- apache has
    # a private view of it on some platforms.

    # always cleanup given that we are using iniset here
    rm -rf $conf
    # Set either the module path or wsgi script path depending on what we've
    # been given
    if [[ "$wsgi" =~ ^[a-zA-Z0-9_.]+:[a-zA-Z0-9_]+$ ]]; then
        iniset "$conf" uwsgi module "$wsgi"
    else
        deprecated 'Configuring uWSGI with a WSGI file is deprecated, use module paths instead'
        iniset "$conf" uwsgi wsgi-file "$wsgi"
    fi
    port=$(get_random_port)
    iniset "$conf" uwsgi http-socket "$APACHE_LOCAL_HOST:$port"
    iniset "$conf" uwsgi processes $API_WORKERS
    # This is running standalone
    iniset "$conf" uwsgi master true
    # Set die-on-term & exit-on-reload so that uwsgi shuts down
    iniset "$conf" uwsgi die-on-term true
    iniset "$conf" uwsgi exit-on-reload false
    # Set worker-reload-mercy so that worker will not exit till the time
    # configured after graceful shutdown
    iniset "$conf" uwsgi worker-reload-mercy $WORKER_TIMEOUT
    iniset "$conf" uwsgi enable-threads true
    iniset "$conf" uwsgi plugins http,python3
    # uwsgi recommends this to prevent thundering herd on accept.
    iniset "$conf" uwsgi thunder-lock true
    # Set hook to trigger graceful shutdown on SIGTERM
    iniset "$conf" uwsgi hook-master-start "unix_signal:15 gracefully_kill_them_all"
    # Override the default size for headers from the 4k default.
    iniset "$conf" uwsgi buffer-size 65535
    # Make sure the client doesn't try to re-use the connection.
    iniset "$conf" uwsgi add-header "Connection: close"
    # This ensures that file descriptors aren't shared between processes.
    iniset "$conf" uwsgi lazy-apps true
    iniset "$conf" uwsgi chmod-socket 666
    iniset "$conf" uwsgi http-raw-body true
    iniset "$conf" uwsgi http-chunked-input true
    iniset "$conf" uwsgi http-auto-chunked true
    iniset "$conf" uwsgi http-keepalive false
    # Increase socket timeout for slow chunked uploads
    iniset "$conf" uwsgi socket-timeout 30
    # Starting time of the WSGi server
    iniset "$conf" uwsgi start-time %t

    enable_apache_mod proxy
    enable_apache_mod proxy_http
    local apache_conf=""
    apache_conf=$(apache_site_config_for $name)
    echo "KeepAlive Off" | sudo tee $apache_conf
    echo "SetEnv proxy-sendchunked 1" | sudo tee -a $apache_conf
    echo "ProxyPass \"${url}\" \"http://$APACHE_LOCAL_HOST:$port\" retry=0 acquire=1 " | sudo tee -a $apache_conf
    enable_apache_site $name
    restart_apache_server
}

# Write a straight-through proxy for a service that runs locally and just needs
# to be reachable via the main http proxy at $loc
function write_local_proxy_http_config {
    local name=$1
    local url=$2
    local loc=$3
    local apache_conf
    apache_conf=$(apache_site_config_for $name)

    enable_apache_mod proxy
    enable_apache_mod proxy_http

    echo "KeepAlive Off" | sudo tee $apache_conf
    echo "SetEnv proxy-sendchunked 1" | sudo tee -a $apache_conf
    echo "ProxyPass \"${loc}\" \"$url\" retry=0 acquire=1 " | sudo tee -a $apache_conf
    enable_apache_site $name
    restart_apache_server
}

function remove_uwsgi_config {
    local conf=$1
    local wsgi=$2
    local name=""
    # TODO(stephenfin): Remove this call when everyone is using module path
    # configuration instead of file path configuration
    name=$(basename $wsgi)

    if [[ "$wsgi" = /* ]]; then
        deprecated "Passing a wsgi script to remove_uwsgi_config is deprecated, pass an application name instead"
    fi

    rm -rf $conf
    disable_apache_site $name
}

# Restore xtrace
$_XTRACE_LIB_APACHE

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