#!/bin/bash
#
# onapp        Startup script for OnApp background processes
#
# chkconfig: - 86 14
# description: Runs transaction runners, backup takers, hypervisor monitor, and receiver

export HOME=/home/onapp
APPPATH=/onapp/interface
LOGPATH=/onapp/interface/log
PIDPATH=/onapp/interface/tmp/pids
USER=onapp

# The number of retries:
# - to stop receiver process
# - to wait for processes ended (like servers:stop)
MAX_RETRIES=10
# delay (in seconds) between retries
SLEEP=10

export RAILS_ENV=production

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

get_pid_from_file()
{

    PID_FILE=$1

    grep "[[:digit:]]\+" $PID_FILE 2>/dev/null
}

# Returns 2 and prints into STDOUT the PID if process matched with the id from PID_FILE is running, 0 otherwise,
# and 1 if file with the PID exists and no process running.
is_running()
{
    unset PID
    PID_FILE=$1
    PID=`get_pid_from_file "$PID_FILE"`

    if [ "x${PID}" = "x" ]; then
        return 0
    fi

    ps --pid $PID >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        return 2
    else
        rm -f $PID_FILE
        return 1
    fi
}

get_zombie()
{
    TASK=$1
    unset LAST_PID ZOMBIE_PID
    LAST_PID=`get_pid_from_file "$PIDPATH/${TASK}.pid"`

    # HACK for onapp_daemon_ctl
    [ "x${TASK}" = "xonapp_daemon" ] && TASK="${TASK}_ctl"

    if [ "x${LAST_PID}" != "x" ]; then
        ZOMBIE_PID=`ps ax | grep "$TASK run" | grep ruby | grep -v grep | grep -v $LAST_PID | sed 's/[[:space:]]\+.*$//'`
    else
        ZOMBIE_PID=`ps ax | grep "$TASK run" | grep ruby | grep -v grep | sed 's/[[:space:]]\+.*$//'`
    fi
    if [ -n "$ZOMBIE_PID" ] ; then
        echo "Zombie $TASK is running (pid(s) `echo $ZOMBIE_PID`). It is possible some transactions are still running."
    fi
}

start(){
    cd $APPPATH || exit 1
    if [ ! -d $PIDPATH ]; then
        mkdir -p $PIDPATH || exit 1
    fi
    chown ${USER}:${USER} $PIDPATH

    is_running "$PIDPATH/ssh-agent.pid" > /dev/null
    if [ $? -lt 2 ]; then
      echo "Starting SSH Key Server..."
      eval `su $USER -m -c "ssh-agent"`
      echo $SSH_AGENT_PID > $PIDPATH/ssh-agent.pid
      su $USER -m -c "ssh-add /onapp/interface/config/keys/private"
    fi

    echo "Starting All Runners (Schedules, Transactions, Backups and Hypervisor, Cluster Monitor) ..."
    is_running "$PIDPATH/onapp_daemon.pid" > /dev/null
    if [ $? -lt 2 ]; then
      su $USER -m -c "$APPPATH/script/onapp_daemon_ctl run >> $LOGPATH/onapp.err 2>&1 " &
    fi

    # RECEIVER: commented as long as receiver is not working
    # is_running "$PIDPATH/receiver.pid"  > /dev/null
    # if [ $? -eq 0 ]; then
    #   su $USER -m -c "$APPPATH/script/onapp_daemon_ctl run >> $LOGPATH/onapp.err 2>&1 " &
    # fi

    echo "Starting Delayed Jobs ..."
    su $USER -m -c "$APPPATH/script/delayed_job start >> $LOGPATH/onapp.err 2>&1 " &

    is_running "$PIDPATH/vnc_proxy.pid"  > /dev/null
    if [ $? -lt 2 ]; then
       if [ -f "$APPPATH/config/on_app.yml" ]; then
         START_PORT=`cat $APPPATH/config/on_app.yml | grep remote_access_session_start_port | sed s/remote_access_session_start_port://`
         LAST_PORT=`cat $APPPATH/config/on_app.yml | grep remote_access_session_last_port | sed s/remote_access_session_last_port://`
       fi
       if [ -z "$START_PORT" ]; then
         START_PORT=30000
       fi
       if [ -z "$LAST_PORT" ]; then
         LAST_PORT=30099
       fi
       echo Starting VNC Proxy...
       su $USER -m -c "/usr/bin/nohup /onapp/interface/script/servers/vnc_proxy /onapp/interface/config/database.yml $START_PORT $LAST_PORT >/dev/null 2>&1" >/dev/null 2>&1 &
       echo $! > $PIDPATH/vnc_proxy.pid
    fi

    cd - >/dev/null
}

stop(){
    cd $APPPATH || exit 1

    echo "Sending SIGTERM to all Runners (Schedules, Transactions, Backups and Hypervisor, Cluster Monitor)..."
    #su $USER -m -c "$APPPATH/script/onapp_daemon_ctl stop >> $LOGPATH/onapp.err 2>&1 " &
    is_running "$PIDPATH/onapp_daemon.pid"  > /dev/null
    if [ $? -gt 1 ]; then
      su $USER -m -c " kill -15 `get_pid_from_file "$PIDPATH/onapp_daemon.pid"` >/dev/null 2>&1 &"
    fi

    # RECEIVER: commented as long as receiver is not working
    # is_running "$PIDPATH/receiver.pid"  > /dev/null
    # if [ $? -gt 1 ]; then
    #   su $USER -m -c " kill -15 `get_pid_from_file "$PIDPATH/onapp_daemon.pid"` >/dev/null 2>&1 &"
    # fi
    # rm -f $PIDPATH/onapp_daemon.pid

    echo "Sending SIGTERM to Delayed Jobs ..."
    su $USER -m -c "$APPPATH/script/delayed_job stop >> $LOGPATH/onapp.err 2>&1 " &

    echo "Sending KILL signal to VNC Proxy..."
    su $USER -m -c "/usr/bin/nohup killall vnc_proxy >/dev/null 2>&1 &"
    wait
    rm -f $PIDPATH/vnc_proxy.pid

    echo "Killing old ssh-agent processes"
    # deletes all identities from the agent
    su $USER -m -c "ssh-add -D >> $LOGPATH/onapp.err 2>&1"
    # kills the current agent (stored in PIDPATH/ssh-agent.pid)
    is_running "$PIDPATH/ssh-agent.pid"  > /dev/null
    if [ $? -gt 1 ]; then
       su $USER -c "kill -9 `get_pid_from_file "$PIDPATH/ssh-agent.pid"` >/dev/null 2>&1"
       rm -f $PIDPATH/ssh-agent.pid
    fi

    echo -n "Waiting while all Runners will stop "
    RETRY=1
    pgrep -f 'servers:stop' >/dev/null 2>&1
    while [ $? -eq 0 -a $RETRY -lt $MAX_RETRIES ]
    do
        echo -n "."
        RETRY=$((${RETRY}+1))
        sleep $SLEEP
        pgrep -f 'servers:stop' >/dev/null 2>&1
    done
    if [ $RETRY -lt $MAX_RETRIES ]; then
        echo " done"
    else
        echo " give up"
    fi
}

restart(){
    stop && sleep $SLEEP && start
}

status(){
    for task in onapp_daemon delayed_job ssh-agent vnc_proxy ; do
        is_running "$PIDPATH/${task}.pid"
        case $? in
          0)
            if [ -z "$1" ]; then
                echo "$task is stopped"
            else
                echo "$task,stopped"
            fi
            ;;
          1)
            if [ -z "$1" ]; then
                echo "$task is stopped but pid file exists"
            else
                echo "$task,stopped"
            fi
            ;;
          2)
            if [ -z "$1" ]; then
                echo "$task (pid `get_pid_from_file "$PIDPATH/${task}.pid"`) is running..."
            else
                echo "$task,running"
            fi
            ;;
        esac
    done
    if [ -z "$1" ]; then
        get_zombie "onapp_daemon"
    fi
}


case "$1" in
  status)
        status "$2"
        ;;
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  *)
        usage
        ;;
esac
