#!/bin/bash
#
#  Copyright 2006-2013 VMware, Inc.  All rights reserved.
#
# vmware-rhttpproxy     Start/Stop the VMware Reverse Proxy
#
#

# Basic support for IRIX style chkconfig
# chkconfig: 35 100 13
# description: VMware Reverse Proxy.

### BEGIN INIT INFO
# Provides: vmware-rhttpproxy
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: VMware Reverse Proxy
### END INIT INFO

umask 0077

if [ -z "$_VCVA_REPORT_PROGRESS" ]; then
    _VCVA_REPORT_PROGRESS_SILENT=1
fi

RHTTPPROXY_SRV_NAME="VMware HTTP Reverse Proxy"
RHTTPPROXY_TAG=rhttpproxy
RHTTPPROXY_LOGDIR=/var/log/vmware/rhttpproxy
LOG_FILE="${RHTTPPROXY_LOGDIR}"/rhttpproxy.log
RHTTPPROXY_KILL_SIGNAL=15
ISRUNNING="${RHTTPPROXY_SRV_NAME} is running."
ISNOTRUNNING="${RHTTPPROXY_SRV_NAME} is not running."
RHTTPPROXY_PID="$(pidof -s $RHTTPPROXY_TAG)"
WATCHDOG=/usr/bin/vmware-watchdog
RHTTPPROXY_HEALTH_PATH=/usr/lib/vmware-rhttpproxy/rhttpproxy-vmon-apihealth.py
RHTTPPROXY_HEALTH_TIMEOUT=10 # seconds
RHTTPPROXY_HEALTH_CMD="timeout $RHTTPPROXY_HEALTH_TIMEOUT $RHTTPPROXY_HEALTH_PATH"
RHTTPPROXY_START_TIMEOUT=35 # seconds

rhttpproxy_etc_dir=/etc/vmware-rhttpproxy
rhttpproxy_conf_file="${rhttpproxy_etc_dir}"/config.xml
rhttpproxy_endpoints_dir="${rhttpproxy_etc_dir}"/endpoints.conf.d
rhttpproxy_endpoints_file="${rhttpproxy_etc_dir}"/endpoints.conf.d/vpxd.conf

RESULT=0
MTIME=0

mkdir -p $RHTTPPROXY_LOGDIR

# Load environment variables
. /etc/profile

get_monotonic_time() {
    eval uptime=`cat /proc/uptime | cut -f1 -d' '`
    # round the uptime to nearest integer
    printf -v MTIME %.0f "$uptime"
}

check_health() {
    echo "Checking $RHTTPPROXY_SRV_NAME health..."
    $RHTTPPROXY_HEALTH_CMD &> /dev/null
    local ret=$?
    if [ $ret -eq 124 ]; then
        echo "$RHTTPPROXY_SRV_NAME health command timed out."
    else
        echo "$RHTTPPROXY_SRV_NAME health command exited with code $ret."
    fi
    # Return the exit status of api helath command.
    return $ret
}

start() {
    # As a highly-threaded app, rhttpproxy performs better with per-thread arenas
    export MALLOC_PER_THREAD=1
    export MALLOC_ARENA_MAX=4
    # Do everything after changing into the log directory, which is
    # where core dumps, etc., will be deposited
    cd $RHTTPPROXY_LOGDIR
    $WATCHDOG -s $RHTTPPROXY_TAG -u 30 -q 5 "/usr/sbin/rhttpproxy -r $rhttpproxy_conf_file -d $rhttpproxy_endpoints_dir -f $rhttpproxy_endpoints_file" > /dev/null 2>&1 &
    if [ $? -ne 0 ]; then
        echo "failed"
        RESULT=1
        return
    fi

    get_monotonic_time
    local startTime=$MTIME
    until check_health; do
        get_monotonic_time
        if [ $((MTIME-startTime)) -gt $RHTTPPROXY_START_TIMEOUT ]; then
            echo "Timedout trying to start $RHTTPPROXY_SRV_NAME"
            # Attempt to kill the service since it timed out.
            $WATCHDOG -k $RHTTPPROXY_TAG &> /dev/null
            kill "-${RHTTPPROXY_KILL_SIGNAL}" \
                "$(pidof -s $RHTTPPROXY_TAG)" &> /dev/null
            RESULT=1
            return
        fi
    done

    echo "$RHTTPPROXY_SRV_NAME started."
    RESULT=0
}

stop() {
    $WATCHDOG -k $RHTTPPROXY_TAG
    kill "-${RHTTPPROXY_KILL_SIGNAL}" $RHTTPPROXY_PID
    if [ $? -ne 0 ]; then
        echo "failed"
        RESULT=1
        return
    fi

    # Wait for rhttpproxy to stop.
    local waitTime=0
    local maxWaitTime=20 # 20 seconds
    while kill -0 $RHTTPPROXY_PID 2> /dev/null; do
        if [ $waitTime -gt $maxWaitTime ] ; then
            echo "Timedout trying to stop $RHTTPPROXY_SRV_NAME"
            RESULT=1
            return
        fi
        sleep 1
        waitTime=$((waitTime+1))
    done

    echo "$RHTTPPROXY_SRV_NAME stopped."
    RESULT=0
}

ssl_reset() {
   # We cannot use pkill with the daemon TAG as match pattern here as that
   # could produce false matches. Revert to pidof + kill.
   if [ -z "${RHTTPPROXY_PID}" ] ; then
      echo "${ISNOTRUNNING}"
      RESULT=3
   else
      kill -HUP ${RHTTPPROXY_PID}
      if [ 0 -ne ${?} ] ; then
         echo "Unexpected error while trying to signal ${RHTTPPROXY_SRV_NAME}."
         RESULT=1
      else
         echo "${RHTTPPROXY_SRV_NAME} signalled."
      fi
   fi
}

usage() {
   echo "Usage: $0 {start|stop|restart|status|ssl_reset}"
}

if [ $# -ne 1 ]; then
   usage
   exit 1
fi

MYPID=$$
date "+%F %T %z BEGIN $MYPID" >> "${LOG_FILE}"
echo "$0 $@" >> "${LOG_FILE}"

exec > >(tee -a "${LOG_FILE}")
exec 2>&1

case $1 in
   "start")
      if [ -z "${RHTTPPROXY_PID}" ] ; then
         start
      else
         echo "${ISRUNNING}"
      fi
      ;;
   "stop")
      if [ -n "${RHTTPPROXY_PID}" ] ; then
         stop
      else
         echo "${ISNOTRUNNING}"
      fi
     ;;
   "restart")
      stop
      start
      ;;
   "status")
      if [ -n "${RHTTPPROXY_PID}" ] ; then
         echo "${ISRUNNING}"
      else
         echo "${ISNOTRUNNING}"
         RESULT=3
      fi
      ;;
   "ssl_reset")
      ssl_reset
      ;;
   *)
      usage
      RESULT=1
      ;;
esac

date "+%F %T %z END $MYPID" >> "${LOG_FILE}"
exit $RESULT
