#!/bin/bash
#
# sccl_start_resource_simulate bearbeitet die Resourcen, die hinter einer Resource
# angegeben sind und simuliert einen Start
#
# Aufruf:
#
# sccl_start_resource_simulate [--force] [--multi|--execute] [-x <extrapar>] <resource> <kurzname> <pidsig>
#
# Die Resource <resource> wird geprueft und ggf. gestartet.
# [--multi]   : Die PRG Resource darf auf mehreren Knoten laufen
# [--execute] : Nur ausführen, keine Locks setzen
# Aufbau des Parameters <resource> siehe Datei resourcen
#
# Returnwerte: 0: alles OK
#              1: Fehler
#              2: SETSTATE
#
########################################################################################
#
. $(dirname $0)/globals.settings
#
unset FORCE MULTI EXECUTE STARTPARS
while getopts p:x:-:? op; do
  case "$op" in
   p) STARTPARS="$STARTPARS $OPTARG";;
   x) for i in $OPTARG; do
        eval $i
      done;;
   -) case "$OPTARG" in
       force)   FORCE="--force";;
       multi)   MULTI=1;;
       execute) EXECUTE=1;;
       *)       echo "usage: $MYPRG [--force] [--multi|--execute] [--kill] [-p <startpar>] [-x <extrapar>] [-i <initignore>] <resource> <kurzname> <pidsig>"
                exit 1;;
      esac;;
   ?) echo "usage: $MYPRG [-p <startpar>] [-x <extrapar>] [-i <initignore>] <resource> <kurzname> <pidsig>"
      exit 1;;
  esac
done
#
shift $(( $OPTIND - 1))
#
if [[ $# -ne 3 ]]; then
  echo "usage: $MYPRG [--force] [--multi] [-p <startpar>] [-x <extrapar>] [-i <initignore>] <resource> <kurzname> <pidsig>"
  exit 1
fi
#
RES="$1"
PKGNAME="$2"
PIDSIG="$3"
#
A=${1// /\\ }
eval set ${A//:/ }
#
RESTYP=$1
shift
#
case $RESTYP in
########################################################################################
# IP-Adresse setzen
#
  IP)
    if [[ $# -lt 3 ]]; then
      echo "Falsches Format: $RES"
      exit 1
    fi
    LOCK=IP_$2
    if ./sccl_test_resource $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    if $IP_TEST $2; then
      echo "Die IP-Adresse $2 ist schon vorhanden."
      exit 1
    fi
    if [[ "$4" = "ROUTE" ]]; then
      ROUTE=-r
    fi
    echo "ip_startstop $ROUTE $1 $2 $3 start"
    exit 0
  ;;
########################################################################################
# Prozess darf nicht laufen
#
  !PROC)
    if [[ "$2" = "WAIT" ]]; then
      if [[ $3 =~ ^[0-9]+$ ]]; then
        MAXWAIT=$3
      else
        MAXWAIT=5
      fi
      SLEEP='sleep 60'
    else
      MAXWAIT=1
      SLEEP=:
    fi
    WAIT=0
    while [[ $WAIT -lt $MAXWAIT ]]; do
      if ! ps -e | grep -Ev 'grep|sccl_start_resource' | grep -q $1; then
        exit 0
      fi
      WAIT=$(( $WAIT + 1 ))
      $SLEEP
    done
    echo "Der Prozess $1 laeuft."
    exit 1
  ;;
########################################################################################
# Prozess muss laufen
#
  PROC)
    if [[ "$2" = "WAIT" ]]; then
      if [[ $3 =~ ^[0-9]+$ ]]; then
        MAXWAIT=$3
      else
        MAXWAIT=5
      fi
      SLEEP='sleep 60'
    else
      MAXWAIT=1
      SLEEP=:
    fi
    WAIT=0
    while [[ $WAIT -lt $MAXWAIT ]]; do
      if ps -ef | grep -Ev 'grep|sccl_start_resource' | grep -q $1; then
        exit 0
      fi
      WAIT=$(( $WAIT + 1 ))
      $SLEEP
    done
    echo "Der Prozess $1 laeuft nicht."
    exit 1
  ;;
########################################################################################
# LOCK: beliebiges Locking von z. B. Rawdevices
#
  LOCK)
    LOCK=LOCK_${1//\//.}
    if ./sccl_test_resource $LOCK; then
      echo "Die Resource $RES:$1 zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    exit 0
  ;;
########################################################################################
# Filesystem
#
  FS)
    LOCK=FS_${1//\//.}
    if ./sccl_test_resource $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    if [[ "$2" = "FSCK" ]]; then
      FSCK='--fsck'
    else
      FSCK=''
    fi
    echo "fs_startstop $FORCE $FSCK $1 start"
    exit 0
  ;;
########################################################################################
# Filesystem-Gruppe aus /etc/fstab
#
  FSG)
    LOCK=FSG_${1//\//.}
    if ./sccl_test_resource $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    if [[ "$2" = "FSCK" ]]; then
      FSCK='--fsck'
    else
      FSCK=''
    fi
    echo "fsg_startstop $FSCK $1 start"
    exit 0
  ;;
########################################################################################
# NFS Filesystem - Unterschied zu FS: darf auf mehreren Knoten gemounted werden
#
  NFS)
    LOCK=NFS_${1//\//.}
    if ./sccl_test_res_on_node $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    echo "fs_startstop --nfs $1 start"
    exit 0
  ;;
########################################################################################
# NFSG Filesystemgruppe - Unterschied zu FSG: darf auf mehreren Knoten gemounted werden
#
  NFSG)
    LOCK=NFSG_${1//\//.}
    if ./sccl_test_res_on_node $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    echo "fsg_startstop --nfs $1 start"
    exit 0
  ;;
########################################################################################
# SubResource
#
  RS)
    if ! ./sccl_start_package -u $1 $PIDSIG; then
      echo "Das Unterpaket $1 konnte nicht gestartet werden."
      exit 1
    fi
  ;;
########################################################################################
# Programm starten
#
  PRG)
    LOCK=PRG_$PKGNAME${1//\//_}
    if [[ -z "$1" ]]; then
      STARTSTOPPRG=$STARTSTOPDIR/${PKGNAME}_startstop
    elif [[ "$1" == */* ]]; then
      STARTSTOPPRG=$1
    else
      STARTSTOPPRG=$STARTSTOPDIR/$1
    fi
    if [[ -n "$MULTI" ]]; then
      if ./sccl_test_res_on_node $LOCK; then
        echo "Die Resource $RES zu $PKGNAME laeuft schon auf diesem Knoten."
        exit 1
      fi
    else
      if ./sccl_test_resource $LOCK; then
        echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
        exit 1
      fi
    fi
    echo "$STARTSTOPPRG start $STARTPARS"
    exit 0
  ;;
########################################################################################
# Programm mit Parametern starten
#
  PRGP)
    LOCK=PRGP_${PKGNAME}_`echo "$RES" | md5sum | cut -d ' ' -f 1`
    if [[ -z "$1" ]]; then
      STARTSTOPPRG=$STARTSTOPDIR/${PKGNAME}_startstop
    elif [[ "$1" == */* ]]; then
      STARTSTOPPRG=$1
    else
      STARTSTOPPRG=$STARTSTOPDIR/$1
    fi
    shift
    if [[ -n "$MULTI" ]]; then
      if ./sccl_test_res_on_node $LOCK; then
        echo "Die Resource $RES zu $PKGNAME laeuft schon auf diesem Knoten."
        exit 1
      fi
    else
      if ./sccl_test_resource $LOCK; then
        echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
        exit 1
      fi
    fi
    echo "$STARTSTOPPRG start $STARTPARS $@"
    exit 0 
  ;;
########################################################################################
# Pakete pruefen
#
  TST)
    LOCK=TST_$PKGNAME
    LOCKD=TSTD_${PKGNAME}_$THISHOSTNAME
    TSTPRG=${2:-$STARTSTOPDIR/${PKGNAME}_test}
    if [[ -n "$MULTI" ]]; then
      echo "Die Resource $RES ist als MULTI gekennzeichnet!"
      exit 1
    elif ./sccl_test_resource $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    elif ./sccl_test_resource $LOCKD; then
      echo "Die Test-Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    NEXTNODE=`./sccl_get_nextnode $PKGNAME`
    if [[ -n "$NEXTNODE" ]]; then
      echo "sccl_start_tst $LOCKD $PKGNAME ${1:-60} '$TSTPRG' $NEXTNODE"
      exit 0
    fi
    echo "WARNUNG: Der Test-Knoten konnte nicht bestimmt werden."
    exit 0
  ;;
########################################################################################
# Pakete lokal pruefen und ggf. restarten
#
  STST)
    LOCK=STST_$PKGNAME
    LOCKD=STSTD_${PKGNAME}_$THISHOSTNAME
    TSTPRG=${3:-$STARTSTOPDIR/${PKGNAME}_test}
    if [[ $TSTPRG != /* ]]; then
      TSTPRG="$STARTSTOPDIR/$TSTPRG"
    fi
    if ./sccl_test_res_on_node $LOCK; then
      echo "Die Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    elif ./sccl_test_res_on_node $LOCKD; then
      echo "Die Restart-Resource $RES zu $PKGNAME ist schon aktiv."
      exit 1
    fi
    echo "sccl_start_tst -n ${STSTMAX:-${2:-999}} $LOCKD $PKGNAME ${1:-60} '$TSTPRG'"
    exit 0
  ;;
########################################################################################
# Paket testen
#
  CPKG)
    if [[ -n "$SCCLINITIGNORE" ]]; then
      if [[ "$SCCLINITIGNORE" == $1:* ]]; then
        exit 0
      fi
    fi
    if ./sccl_test_resource $1; then
      exit 0
    fi
    if [[ $3 =~ ^[0-9]+$ ]]; then
      MAXWAIT=$3
    else
      MAXWAIT=5
    fi
    if [[ "$2" == WAIT* ]]; then
      echo -n "wating for starting $1 "
      WAITEND=`date -d "+$MAXWAIT minute" '+%s'`
      while [[ `date '+%s'` -lt $WAITEND ]]; do
        if ./sccl_test_resource $1; then
          exit 0
        fi
        echo -n "."
        sleep 5
      done
      echo
    fi
    if [[ "$2" == *START ]]; then
      if ./sccl_test_resource $1; then
        exit 0
      fi
      echo "sccl_start -i '$SCCLINITIGNORE' $1 `get_first_node $1`"
      if ./sccl_test_resource $1; then
        exit 0
      fi
      echo -n "wating for starting $1 "
      WAITEND=`date -d "+$MAXWAIT minute" '+%s'`
      while [[ `date '+%s'` -lt $WAITEND ]]; do
        if ./sccl_test_resource $1; then
          exit 0
        fi
        echo -n "."
        sleep 5
      done
      echo
    fi
    echo "Das Paket $1 muss im Cluster laufen."
    exit 1
  ;;
########################################################################################
# Pakete testen
#
  CPKGO)
    if [[ -n "$SCCLINITIGNORE" ]]; then
      if [[ "$SCCLINITIGNORE" == $1:* ]]; then
        exit 0
      fi
    fi
    for i in ${1//,/ }; do
      if ./sccl_test_resource $i; then
        exit 0
      fi
    done
    if [[ $3 =~ ^[0-9]+$ ]]; then
      MAXWAIT=$3
    else
      MAXWAIT=5
    fi
    if [[ "$2" == WAIT* ]]; then
      echo -n "wating for starting on one of $1 "
      WAITEND=`date -d "+$MAXWAIT minute" '+%s'`
      while [[ `date '+%s'` -lt $WAITEND ]]; do
        for i in ${1//,/ }; do
          if ./sccl_test_resource $i; then
            exit 0
          fi
        done
        echo -n "."
        sleep 5
      done
      echo
    fi
    echo "Eines der Pakete $1 muss im Cluster laufen."
    exit 1
  ;;
########################################################################################
# Paketestart testen
#
  CPKGW)
    if [[ -n "$SCCLINITIGNORE" ]]; then
      if [[ "$SCCLINITIGNORE" == $1:* ]]; then
        exit 0
      fi
    fi
    if [[ $2 =~ ^[0-9]+$ ]]; then
      WAIT=$2
    else
      echo "Wartezeit nicht angegeben"
      exit 1
    fi
    START=$(./sccl_get_start $1)
    if [[ -z "$START" ]]; then
      if [[ $3 =~ ^[0-9]+$ ]]; then
        MAXWAIT=$3
      else
        MAXWAIT=5
      fi
      echo -n "wating for starting $1 "
      WAITEND=$(date -d "+$MAXWAIT minute" '+%s')
      while [[ -z "$START" && $(date '+%s') -lt $WAITEND ]]; do
        START=$(./sccl_get_start $1)
        sleep 5
        echo -n "."
      done
      echo
      if [[ -z "$START" ]]; then
        echo "Das Paket $1 muss im Cluster laufen."
        exit 1
      fi
    fi
    if [[ $(date '+%s') -lt $(( $START + $WAIT )) ]]; then
      echo "wating $(( $START + $WAIT - $(date '+%s') )) seconds"
      sleep $(( $START + $WAIT - $(date '+%s') ))
    fi
    exit 0
  ;;
########################################################################################
# Paket testen
#
  PKG)
    if [[ "$2" = "WAIT" ]]; then
      if [[ $3 =~ ^[0-9]+$ ]]; then
        MAXWAIT=$3
      else
        MAXWAIT=5
      fi
      SLEEP='sleep 60'
    else
      MAXWAIT=1
      SLEEP=:
    fi
    WAIT=0
    while [[ $WAIT -lt $MAXWAIT ]]; do
      if ./sccl_test_res $1; then
        exit 0
      fi
      WAIT=$(( $WAIT + 1 ))
      $SLEEP
    done
    echo "Das Paket $1 muss auf diesem Knoten laufen."
    exit 1
  ;;
########################################################################################
# Ausschlusspaket auf gleichem Knoten testen
#
  !PKG)
    if ./sccl_test_res $1; then
      if [[ "$2" = "STOP" || "$2" = "SWITCH" ]]; then
        if ! ./sccl_stop_package --simulate $1; then
          echo "Das Paket $1 kann nicht gestoppt werden!"
          exit 1
        fi
        exit 0
      else
        echo "Das Paket $1 darf nicht gleichzeitig laufen!"
        exit 1
      fi
    fi
  ;;
########################################################################################
# Ausschlusspaket im Cluster testen
#
  !CPKG)
    if ./sccl_test_resource $1; then
      if [[ "$2" = "STOP" || "$2" = "SWITCH" ]]; then
        if ! ./sccl_stop --simulate $1; then
          echo "Das Paket $1 kann nicht gestoppt werden!"
          exit 1
        fi
        exit 0
      else
        echo "Das Paket $1 darf nicht gleichzeitig laufen!"
        exit 1
      fi
    fi
  ;;
########################################################################################
# Restart von aktiven Paketen
#
  RST)
    if [[ "$2" = "CLUSTER" ]]; then
      for i in $NODES; do
        if [[ "$SCCLINITIGNORE" != "$j:$i" ]]; then
          sccl_restart --simulate -i '$THISINITIGNORE' $1 $i
        fi
      done
    elif [[ "$SCCLINITIGNORE" != "$j:$i" ]]; then
      sccl_restart --simulate -i '$THISINITIGNORE' $1
    fi
    if [[ -s "$LOCKDIR/$PKGNAME.RST" ]]; then
      tac "$LOCKDIR/$PKGNAME.RST" | while read j n; do
        for i in $n; do
          if [[ "$SCCLINITIGNORE" != "$j:$i" ]]; then
            sccl_start --simulate -i '$THISINITIGNORE' $j $i
          fi
        done
      done
    fi
    exit 0
  ;;
########################################################################################
# wird nur beim Stoppen geprüft
#
  MINPKGS)
    exit 0
  ;;
########################################################################################
# wird nur beim Stoppen geprüft
#
  CSRV)
    exit 0
  ;;
########################################################################################
# Paket als laufend markieren
#
  SETSTATE)
    echo "Der Start des Paketes '$PACKAGE' wurde auf $THISHOSTNAME simuliert."
    exit 2
  ;;
########################################################################################
# Paket wieder stoppen aber "OK" liefern
#
  TEARDOWN)
    echo "Das Paket '$PACKAGE' wird wieder heruntergefahren."
    exit 3
  ;;
########################################################################################
# wird nur beim Stoppen geprüft
#
  MINPKGS)
    exit 0
  ;;
########################################################################################
  *)
    echo "Ungueltiger Resourcetyp $RESTYP in $RES"
    exit 1
  ;;
esac
