#!/bin/bash
#
# sccl_start_resource bearbeitet die Resourcen, die hinter einer Resource
# angegeben sind
#
# Aufruf:
#
# sccl_start_resource [--force] [--multi] [-x <extrapars>] <resource> <kurzname> <pidsig>
#
# Die Resource <resource> wird geprueft und ggf. gestartet.
# [--multi] : Die PRG Resource darf auf mehreren Knoten laufen
# Aufbau des Parameters <resource> siehe Datei resourcen
#
########################################################################################
#
#echo $0 $*
#
if [[ "$1" = "--force" ]]
 then
  FORCE="--force"
  shift
else
  FORCE=""
fi
#
. `dirname $0`/globals.functions
#
if [[ "$1" = "--multi" ]]
 then
  MULTI=1
  shift
else
  MULTI=0
fi
#
if [[ "$1" = "-x" ]]
 then
  X="-x $2"
  for i in $2
   do
    eval $i
  done
  shift 2
else
  X=""
fi
#
if [[ $# -ne 3 ]]
 then
  echo "usage: $0 [--force] [--multi] <resource> <kurzname> <pidsig>"
  exit 1
fi
#
RES=$1
KURZNAME=$2
PIDSIG=$3
#
set `echo $1 | sed 's/:/ /g'`
#
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 $KURZNAME 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
    if ./ip_startstop $ROUTE $1 $2 $3 start
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Die IP-Adresse $2 konnte nicht gesetzt werden."
    exit 1 
  ;;
########################################################################################
# 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 | egrep -v 'grep|sccl_start_resource' | grep -q $1
       then
        exit 0
      fi
      WAIT=$(( $WAIT + 1 ))
      $SLEEP
    done
    echo "Der Prozess $1 laeuft nicht."
    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 -efa | egrep -v '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_`echo $1 | sed 's/\//./g'`
    if ./sccl_test_resource $LOCK
     then
      echo "Die Resource $RES:$1 zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    set_lockdat $LOCK $KURZNAME $PIDSIG
    exit 0
  ;;
########################################################################################
# Filesystem
#
  FS)
    LOCK=FS_`echo $1 | sed 's/\//./g'`
    if ./sccl_test_resource $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    if ./fs_startstop $FORCE $1 start $2
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Das Filesystem $1 konnte nicht gemounted werden."
    exit 1 
  ;;
########################################################################################
# Filesystem-Gruppe aus /etc/fstab
#
  FSG)
    LOCK=FSG_`echo $1 | sed 's/\//./g'`
    if ./sccl_test_resource $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    if ./fsg_startstop $1 start $2
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Die Filesystemgruppe $1 konnte nicht gemounted werden."
    exit 1 
  ;;
########################################################################################
# NFS Filesystem - Unterschied zu FS: darf auf mehreren Knoten gemounted werden
#
  NFS)
    LOCK=NFS_`echo $1 | sed 's/\//./g'`
    if ./sccl_test_res_on_node $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    if ./fs_startstop --nfs $1 start
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Das Filesystem $1 konnte nicht gemounted werden."
    exit 1 
  ;;
########################################################################################
# NFSG Filesystemgruppe - Unterschied zu FSG: darf auf mehreren Knoten gemounted werden
#
  NFSG)
    LOCK=NFSG_`echo $1 | sed 's/\//./g'`
    if ./sccl_test_res_on_node $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    if ./fsg_startstop --nfs $1 start
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Die Filesystemgruppe $1 konnte nicht gemounted werden."
    exit 1 
  ;;
########################################################################################
# SubResource
#
  RS)
    if ! ./sccl_start_package $1 $PIDSIG
     then
      echo "Das Unterpaket $1 konnte nicht gestartet werden."
      exit 1
    fi
  ;;
########################################################################################
# Programm starten
#
  PRG)
    LOCK=PRG_$KURZNAME`echo $1 | sed 's|/|_|g'`
    if [[ -z "$1" ]]
     then
      STARTSTOPPRG=$STARTSTOPDIR/${KURZNAME}_startstop
    elif echo "$1" | grep -q '/'
     then
      STARTSTOPPRG=$1
    else
      STARTSTOPPRG=$STARTSTOPDIR/$1
    fi
    if [[ $MULTI = 1 ]]
     then
      if ./sccl_test_res_on_node $LOCK
       then
        echo "Die Resource $RES zu $KURZNAME laeuft schon auf diesem Knoten."
        exit 1
      fi
    else
      if ./sccl_test_resource $LOCK
       then
        echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
        exit 1
      fi
    fi
    if $STARTSTOPPRG start
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Das Programm $1 konnte nicht gestartet werden."
    exit 1 
  ;;
########################################################################################
# Programm mit Parametern starten
#
  PRGP)
    LOCK=PRGP_$KURZNAME_`echo "$*" | md5sum | cut -d ' ' -f 1`
    if [[ -z "$1" ]]
     then
      STARTSTOPPRG=$STARTSTOPDIR/${KURZNAME}_startstop
    elif echo "$1" | grep -q '/'
     then
      STARTSTOPPRG=$1
    else
      STARTSTOPPRG=$STARTSTOPDIR/$1
    fi
    if [[ $MULTI = 1 ]]
     then
      if ./sccl_test_res_on_node $LOCK
       then
        echo "Die Resource $RES zu $KURZNAME laeuft schon auf diesem Knoten."
        exit 1
      fi
    else
      if ./sccl_test_resource $LOCK
       then
        echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
        exit 1
      fi
    fi
    if [[ -n "$2" ]]
     then
      shift
      if $STARTSTOPPRG start "$@"
       then
        set_lockdat $LOCK $KURZNAME $PIDSIG
        exit 0
      fi
    else
      if $STARTSTOPPRG start $KURZNAME
       then
        set_lockdat $LOCK $KURZNAME $PIDSIG
        exit 0
      fi
    fi
    echo "Das Programm $STARTSTOPPRG konnte nicht gestartet werden."
    exit 1 
  ;;
########################################################################################
# Pakte pruefen
#
  TST)
    LOCK=TST_$KURZNAME
    LOCKD=TSTD_${KURZNAME}_$THISHOSTNAME
    TSTPRG=${2:-$STARTSTOPDIR/${KURZNAME}_test}
    if [[ $MULTI = 1 ]]
     then
      echo "Die Resource $RES ist als MULTI gekennzeichnet!"
      exit 1
    elif ./sccl_test_resource $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    elif ./sccl_test_resource $LOCKD
     then
      echo "Die Test-Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    NEXTNODE=`./sccl_get_nextnode $KURZNAME`
    while [[ -n "$NEXTNODE" ]]
     do
      if ./sccl_start_tst $LOCKD $KURZNAME ${1:-60} "$TSTPRG" $NEXTNODE
       then
        set_lockdat $LOCK $KURZNAME $PIDSIG
        exit 0
      fi
      echo "WARNUNG: Das Test-Programm $1 konnte auf $NEXTNODE nicht gestartet werden."
      NEXTNODE=`./sccl_get_nextnode $KURZNAME $NEXTNODE`
    done
    echo "WARNUNG: Der Test-Knoten konnte nicht bestimmt werden."
    exit 0
  ;;
########################################################################################
# Pakte lokal pruefen und ggf. restarten
#
  STST)
    LOCK=RST_$KURZNAME
    LOCKD=RSTD_${KURZNAME}_$THISHOSTNAME
    TSTPRG=${3:-$STARTSTOPDIR/${KURZNAME}_test}
    if [[ $TSTPRG != /* ]]
     then
      TSTPRG="$STARTSTOPDIR/$TSTPRG"
    fi
    if ./sccl_test_res_on_node $LOCK
     then
      echo "Die Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    elif ./sccl_test_res_on_node $LOCKD
     then
      echo "Die Restart-Resource $RES zu $KURZNAME ist schon aktiv."
      exit 1
    fi
    if ./sccl_start_tst -n "${STSTMAX:-${2:-999}}" $LOCKD $KURZNAME ${1:-60} "$TSTPRG"
     then
      set_lockdat $LOCK $KURZNAME $PIDSIG
      exit 0
    fi
    echo "Das Restart-Programm $1 konnte nicht gestartet werden."
    exit 1 
  ;;
########################################################################################
# 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
      ./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
  ;;
########################################################################################
# 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 $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 $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 $SLAVENODES
       do
        if [[ "$SCCLINITIGNORE" != "$j:$i" ]]
         then
          ./sccl_restart -i "$THISINITIGNORE" $1 $i
        fi
      done
    elif [[ "$SCCLINITIGNORE" != "$j:$i" ]]
     then
      ./sccl_restart -i "$THISINITIGNORE" $1
    fi
    if [[ -s $LOCKDIR/$KURZNAME.RST ]]
     then
      tac $LOCKDIR/$KURZNAME.RST | while read j n
       do
        for i in $n
         do
          if [[ "$SCCLINITIGNORE" != "$j:$i" ]]
           then
            ./sccl_start -i "$THISINITIGNORE" $j $i
          fi
        done
      done
      rm $LOCKDIR/$KURZNAME.RST
    fi
    exit 0
  ;;
########################################################################################
# Paket als laufend markieren
#
  SETSTATE)
    set_lockdat $KURZNAME $KURZNAME $PIDSIG
    exit 0
  ;;
########################################################################################
  *)
    echo "Ungueltiger Resourcetyp $RESTYP in $RES"
    exit 1
  ;;
esac
