#!/bin/bash
source /etc/rc.d/init.d/functions
source /usr/libexec/openshift/cartridges/abstract/info/lib/util 
source /etc/openshift/node.conf

lockfile=/var/lock/subsys/openshift-gears
logfile=/var/log/openshift-gears-async-start.log
numparallel=5
timeout=90

# colors, use like: echo "${RED}FAILED!!!${NORM}"
RED=$(echo -e "\033[31m")
GREEN=$(echo -e "\033[32m")
NORM=$(echo -e "\033[0m")

function print_column() {
    sameline="false"
    if [ "$1" == "-n" ]
    then
        shift
        sameline="true"
    fi

    length=$1
    msg=$2
    numspaces=$(( $length - ${#msg} ))

    echo -n "$msg"

    for ix in $(seq $numspaces)
    do
        echo -n ' '
    done
    if [ "$sameline" == "false" ]
    then
        echo
    fi
}

function openshift_gears() {
    grep ":${GEAR_GECOS}:" /etc/passwd | cut -d: -f1
}

RETVAL=0
GROUP_RETVAL=0

# Disable IPV6 - SELinux Friendly
if [ -f /proc/sys/net/ipv6/conf/all/disable_ipv6 ]
then
    echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
fi

if [ -f /proc/sys/net/ipv6/conf/default/disable_ipv6 ]
then
    echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
fi

function _log_message() {
    faclvl=$1
    shift
    [ -z "$@" ]  &&  return 0
    /usr/bin/logger -i -s -t "openshift-gears-service" -p $faclvl "$@"
}

function log_info() {
    _log_message user.info "$@"
}

function log_error() {
    _log_message user.err "$@"
}

function return_output() {
    if [ "$1" ]; 
	then
		echo >> "$1" 2>&1
		cat "$1" | sed -e "s#\[  OK  \]#\[  ${GREEN}OK${NORM}  \]#" -e "s#\[FAILED\]#\[${RED}FAILED${NORM}\]#"
		rm -f "$1"
    fi
}

function return_terminate() {
    log_error "Timeout $1 $2"	
    print_column -n 59 "Timeout $2..."
    echo "[${RED}FAILED${NORM}]"
    exit 1
}

function startgear() {
    # GEARNAME=$1
    local OUTFILE=$(mktemp /var/run/openshift/openshift_init-startgear-$1.XXXXXXXX)
    trap "return_terminate startgear $1 $OUTFILE" USR1
    log_info "Starting $1..."
    echo "Starting $1..." >> $OUTFILE 2>&1
    (
      export APP_HOME="$GEAR_BASE_DIR/$1"
      locks=$(ls $APP_HOME/*/run/stop_lock 2>/dev/null |grep -ve 'app-root|git' |wc -l)
      if [ "$locks" -gt 0 ]
      then
        echo "$1 is locked"
      else
        setuppam $1
        export uuid=$1
        export OPENSHIFT_HOMEDIR=$APP_HOME
        setup_user_vars
        start_app 2>&1 | cat - >>$OUTFILE

        RETVAL=$?
        print_column -n 59 "    $1"
        if [ $RETVAL -eq 0 ]
        then
            echo_success
        else
            GROUP_RETVAL=$(($GROUP_RETVAL+1))
            echo_failure
            echo
            echo $OUTPUT
            echo
        fi
        echo
      fi
    ) &
    wait
    log_info "Started $1"
    return_output $OUTFILE
}

function stopgear() {
    # GEARNAME=$1
    local OUTFILE=$(mktemp /var/run/openshift/openshift_init-stopgear-$1.XXXXXXXX)
    trap "return_terminate stopgear $1 $OUTFILE" USR1
    log_info "Stopping $1..."
    echo "Stopping $1..." >> $OUTFILE 2>&1
    (
      export APP_HOME="$GEAR_BASE_DIR/$1"
      export OPENSHIFT_HOMEDIR=$APP_HOME
      export uuid=$1
      setup_user_vars
      stop_app 2>&1 | cat - >>$OUTFILE

      RETVAL=$?
      print_column -n 59 "    $1"
      if [ $RETVAL -eq 0 ]
      then
          echo_success
      else
          GROUP_RETVAL=$(($GROUP_RETVAL+1))
          echo_failure
          echo
          echo $OUTPUT
          echo
      fi
      echo
    ) &
    wait
    log_info "Stopped $1"
    return_output $OUTFILE
}

function setuppam() {
    uuid=$1
    if [ ! -f "/etc/security/limits.d/84-${uuid}.conf" ]
    then
        echo "found"
        /usr/libexec/openshift/lib/setup_pam_fs_limits.sh $uuid
    fi
}

function start_backgrounded() {
    log_info "Starting OpenShift services in the background ..."
    nohup /usr/sbin/oo-admin-ctl-gears waited-startall > $logfile 2>&1 &
    bgpid=$!
    log_info "Background start initiated - process id = $bgpid"
    log_info "Check $logfile for more details."
    echo
    echo "Note: In the future, if you wish to start the OpenShift services in the"
    echo "      foreground (waited), use:  service openshift-gears waited-start"
    echo
}

function waited_start() {
    log_info "Starting OpenShift Services: "
    echo

	for uuid in $(openshift_gears)
    do
        /bin/egrep -q -v "idle" "$GEAR_BASE_DIR/$uuid/app-root/runtime/.state" && echo $uuid || echo "Skipping $uuid" 1>&2
    done | xargs -I{} -n 1 -P $numparallel /usr/bin/timeout -s USR1 $timeout /usr/sbin/oo-admin-ctl-gears startgear {}

    log_info "All OpenShift services started"
    [ $GROUP_RETVAL -eq 0 ] && touch ${lockfile}
    [ $GROUP_RETVAL -eq 0 ] && success || failure
    echo
    return $GROUP_RETVAL
}

function stop() {
    log_info "Stopping OpenShift Services: "
    echo

	for uuid in $(openshift_gears)
    do
        /bin/egrep -q -v "stopped|idle" "$GEAR_BASE_DIR/$uuid/app-root/runtime/.state" && echo $uuid || echo "Skipping $uuid" 1>&2
    done | xargs -I{} -n 1 -P $numparallel /usr/bin/timeout -s USR1 $timeout /usr/sbin/oo-admin-ctl-gears stopgear {}

    log_info "All OpenShift services stopped"
    [ $GROUP_RETVAL -eq 0 ] && rm -f ${lockfile}
    [ $GROUP_RETVAL -eq 0 ] && success || failure
    echo
    return $GROUP_RETVAL
}

function restart() {
    # This restarts each app individually. DO NOT change it to simply call stop() and start()
    log_info "Restarting OpenShift Services: "
    echo

	for uuid in $(openshift_gears)
    do
        /bin/egrep -q -v "idle|stopped" "$GEAR_BASE_DIR/$uuid/app-root/runtime/.state" && echo $uuid || echo "Skipping $uuid" 1>&2
    done | xargs -I{} -n 1 -P $numparallel /usr/bin/timeout -s USR1 $timeout /usr/sbin/oo-admin-ctl-gears restartgear {}

    echo -n "All OpenShift services restarted"
    [ $GROUP_RETVAL -eq 0 ] && touch ${lockfile}
    [ $GROUP_RETVAL -eq 0 ] && success || failure
    echo
    return $GROUP_RETVAL
}

case "$1" in
  startall)
    start_backgrounded
    ;;
  stopall)
    stop
    ;;
  restartall)
    restart
    ;;
  condrestartall)
    [ -f "$lockfile" ] && restart
    ;;
  waited-startall)
    waited_start
    ;;
  status)
    echo "Checking OpenShift Services: "
    echo

    for gear in $(grep ":${GEAR_GECOS}:" /etc/passwd | cut -d: -f6)
    do
        source $gear/.env/OPENSHIFT_APP_NAME
        echo "Checking application $OPENSHIFT_APP_NAME status:"
        echo "-----------------------------------------------"

        for cartridge in $(ls -d $gear/* |grep -E -v 'app-root|git')
        do
            name=$(basename $cartridge)
            export uuid=$(basename $gear)
            export OPENSHIFT_HOMEDIR=$APP_HOME
            setup_user_vars
            [ -e "${CARTRIDGE_BASE_PATH}/$name" ] || continue
            output=`run_as_user "${CARTRIDGE_BASE_PATH}/$name/info/bin/app_ctl.sh status" 2>&1`
            RETVAL=$?

            if [ -n "$output" ];
            then
              echo "$output"
            else
              echo "$name not provided"
            fi
              
            if [ $RETVAL -ne 0 ];
            then
                GROUP_RETVAL=$(($GROUP_RETVAL+1))
            fi
        done
        echo
    done
    echo
    ;;

  startgear)
    startgear $2
    ;;

  stopgear)
    stopgear $2
    ;;

  restartgear)
    stopgear $2
    startgear $2
    ;;

  list)
    openshift_gears
    ;;

  *)
    echo "Usage: $0 {startall|stopall|status|restartall|condrestartall|startgear|stopgear|restartgear|list}"
    exit 1
esac

exit $RETVAL

