#!/bin/sh
###############################################################################
# $Author: krempaska $
# $Date: 2009/03/10 17:46:43 $
# $Id: bootlink,v 1.10 2009/03/10 17:46:43 krempaska Exp $
# $Name:  $
# $Source: /cvs/G/DRV/misc/App/scripts/bootlink,v $
# $Revision: 1.10 $
###############################################################################
# File name:
# Description: creates a new link to the IOC booting directory 
# This script works only if yoa are located:
# - on the boot pc or
# - on a machine of the bootpc subnet or
# - on office subnet and want to change boot link on machine.
# Notes:
# 1. This script does not jump between different facilities networks! 
# 2. If more IOCs are specified in the command line, they have to boot from
#    unique bootpc and the symbolic link of the specified targetbase will 
#    be done for all this IOCs. 
###############################################################################
#Note: this variables have to be don on bpc, (gw)
#export INSTBASE=/psi-xfel/devl
#export INSTBASELIST="/psi-xfel/devl /psi-xfel/work /psi-xfel/prod"

#---------------------------
# This is supposed to be called only if running on a bootpc
# It creates a new symbolic link of /ioc/$ioc to the boot directory
#---------------------------
function do_slink () {
  #echo "do_slink() params $*"
  targetbase=$1
  shift
  for ioc in $*
   do
   
   if [ "-" = "$targetbase" ]
   then
     old=$(readlink /ioc/$ioc)
     echo "Link on $bootpc for $ioc is \"$old\""
     continue
   fi
   
   echo "Changing symbolic link for /ioc/$ioc...";
   old=$(readlink /ioc/$ioc)
   new="$targetbase/iocBoot/ioc/$ioc"
   echo "Current link is to:   $old"
   echo "Requested link is to: $new"
   if [ "$old" = "$new" ] 
   then
       echo "No operation will be done, it already points to \"$old\"."
       continue
   fi
   if [ -d "$new" ]
   then
     rm -f /ioc/$ioc
     ln -s $new /ioc/$ioc
     chk=$(readlink /ioc/$ioc)
     if [ "$chk" = "$new" ] 
     then
       echo "Changed on $bootpc";
       echo "from $old";
       echo "to   $new"
     else
       echo "ERROR: change on $bootpc from \"$old\" to \"$new\" failed"
       echo "link points now to \"$chk\". Check permissions:"
       ls -l /ioc/$ioc
     fi  
   else
     echo "Target directory \"$tdir\" does not exist, no link has been done."
   fi
  done
  return
}

#---------------------------
# Sets the ssh gateway name based on the bootpc value
#---------------------------
function get_gw () {
   case "$bootpc" in
        "slsbpc") #SLS machine
	  ssh_gw="slsbridge"
	  ;;
	"x01dc-bpc")
	  ssh_gw="x01dc-gw"    
	  ;;
        "x02da-bpc")
	    ssh_gw="x02da-gw"    
	    ;;
	"x03ma-bpc")
	    ssh_gw="x03ma-gw"    
	    ;;
	"x04db-bpc")
	    ssh_gw="x04db-gw"    
	    ;;
	"x04sa-bpc")
	    ssh_gw="x04sa-gw"    
	    ;;
	"x05da-bpc")
	    ssh_gw="x05da-gw"   
             ;;
 	"x05la-bpc")
	    ssh_gw="x05la-gw"   
             ;;
 	"x06da-bpc")
	    ssh_gw="x06da-gw"   
             ;;
 	"x06sa-bpc")
	    ssh_gw="x06sa-gw"   
             ;;
 	"x07da-bpc")
	    ssh_gw="x07da-gw"   
            ;;
  	"x07db-bpc")
	    ssh_gw="x07db-gw"   
            ;;
 	"x07ma-bpc")
	    ssh_gw="x07ma-gw"   
            ;;	 
 	"x09la-bpc")
	    ssh_gw="x09la-gw"   
            ;;
 	"x10da-bpc")
	    ssh_gw="x10da-gw"   
            ;;
 	"x10sa-bpc")
	    ssh_gw="x10sa-gw"   
            ;;
 	"x11la-bpc")
	    ssh_gw="x11la-gw"   
            ;;
 	"x12sa-bpc")
	    ssh_gw="x12sa-gw"   
            ;;
        "fin-cbpce"|"fin-cbpc01e")
	  ssh_gw="fin-cgwe"
          ;;
        "hipa-bpc01")
	  ssh_gw="hipa-gw01"
          ;;
	*)
	  ssh_gw=""
	  ;;
   esac	  
}

if [ "$1" = "-v" ];then echo "\$Header: /cvs/G/DRV/misc/App/scripts/bootlink,v 1.10 2009/03/10 17:46:43 krempaska Exp $";exit;fi

#calling from the script $1=action: do_slink, $2=target, $3=bootpc, $4=ioc1, $5=ioc2,...
if [ $# > 3 ] && [ "$1" = "do_slink" ]
then
 #echo "calling $0 with parameters: $@"
 #check if you are on the bootpc
 val=$(echo $(nslookup $(hostname).psi.ch ));
 hname=$(echo $val|awk '{print $6}')
 #cut the domain part of the hname
 hname=$(echo $hname|awk 'BEGIN {FS="."} {print $1}')
 bootpc=$2
 #echo $bootpc
 #for slsbpc (slsbpc1/2) cluster exception
 if [ $hname = "slsbpc2" ] || [ $hname = "slsbpc1" ];then hname="slsbpc";fi
 
 if [ "$hname" != "$bootpc" ];then echo "I am not on the $bootpc but on $hname";exit;fi
 shift
 shift
 do_slink $@;
 exit;
fi

if [ $# -lt 2 ] || [ "$1" = "-?" ]
then 
    echo "Usage: $0 (<newbase>|-) <IOC> [<IOC2> [...]]"
    echo "Description: Change boot path for list of IOCs."
    echo "If <newbase> = \"-\" it shows the current links."
    echo "Example: $0 /work X07DA-VME-OP1"
    exit
fi
if [ -z "$ORACLE_HOME" ] ; then
    echo "ORACLE_HOME not defined" >&2
    exit 1
fi

targetbase=$1
#chkslsbase.sh checks if the bootdirectory specified in the $1 argument is valid
#it has to be one of $SLSBASELIST or $INSTBASELIST
#check if the requested directory is defined in one of the environment
#variables $*LIST
in_list=$(awk -vb="${*%/}" -vl="$SLSBASELIST $INSTBASELIST $PSIXFELBASELIST" '
    BEGIN{
        split(b,s)
        for (j in s) {
            split(l,f)
            for (i in f) {
                if (f[i] == s[j]) {
                    print f[i]
                    exit
                }
            }
        }
    }')

#if [ "$(chkslsbase.sh $targetbase)" = "" ] && [ "$targetbase" != "-" ]
if [ "$in_list" = "" ] && [ "$targetbase" != "-" ]
then
    echo -ne "first argument (\"$targetbase\") has to be one out of\n$SLSBASELIST\t$INSTBASELIST\n"
    exit
fi
shift

#for the list of all IOCs specified in the command line arguments get bootpc
#if it's not the same it exits
#get bootpc for the first IOC
bootpc=$(echo $(
    sqlplus -s gfa_public/pub01@GFAPRD << EOF
    SET HEADING OFF;
    SELECT DESTINATION FROM HOSTS.RELATIONS WHERE REL_TYPE_ID=3 AND HOST_NAME='$1';
    EXIT
    EOF
    ))
if [ "$bootpc" = "no rows selected" ]
  then
   echo "No bootpc for the $ioc found in the HOSTS database."
   exit
fi    
bootpcprev=$bootpc

for ioc in $*
do
    #get bootpc from HOSTS
    bootpcprev=$bootpc
    bootpc=$(echo $(
    sqlplus -s gfa_public/pub01@GFAPRD << EOF
    SET HEADING OFF;
    SELECT DESTINATION FROM HOSTS.RELATIONS WHERE REL_TYPE_ID=3 AND HOST_NAME='$ioc';
    EXIT
    EOF
    ))
    if [ "$bootpc" = "no rows selected" ]
    then
	    echo "No bootpc for the $ioc found in the HOSTS database."
	    exit
    fi
    # if some bpc differs stop
    if [ "$bootpcprev" != "$bootpc" ]
    then
       echo "BootPC $bootpc for the IOC $ioc differs from other $bootpcprev!"
       exit
    fi
done

#get instbase from last booted table
slsbase=$(echo $(
  sqlplus -s gfa_public/pub01@GFAPRD << EOF
  SET HEADING OFF;
  SELECT SLSBASE FROM HOSTS.IOC_LASTBOOTED WHERE  SYSTEM = '$ioc';
  EXIT
  EOF
  ))
if [ "$list" = "no rows selected" ]
then
   echo "IOC $ioc not in bootinfo DB"
   exit
fi
slsbase=$(echo $list|awk '{print $2}');

#I need to go to the bootpc and do the sym. link operations directly there
#1.get the subnet location of the currently used host 
#2.do the link depending on the location of your host and bootpc
#2.a) if you are on the same subnet as your currently used host 
#     and if you are on the bootpc, do the link (call function do_slink()),
#     otherwise do ssh to the bootpc and do the link
#  b) if you are on the other subnet (office), get the ssh gateway name 
#     (by using naming convention), do ssh to the gw, ssh bootpc and do the link 
#Note: If you are on a facility subnet, i.e.SLSMACHINE, you cannot jump to FELOBLA!
#      So if you are on x07da-cons-1, the call "bootlink /work X09LA-VME-ES1" wan't work! 

#get the bootpc IP -> from the HOSTS database
bootpcIP=$(echo $(
 sqlplus -s gfa_public/pub01@GFAPRD << EOF
 SET HEADING OFF;
 SELECT IP FROM HOSTS.INTERFACES HI, HOSTS.IP_ADDRESSES HIP WHERE HI.INTERF_ID=HIP.INTERF_ID AND HI.HOST_NAME = '$bootpc';
 EXIT
 EOF
))
if [ "$slsbase" = "$targetbase" ]
then
  echo "According to bootinfo, IOC $ioc has booted already from $slsbase"
  echo "continue anyway..."
fi
    
#get the currently used host IP -> nslookup
#added .psi.ch because on slsbpc in /etc/resolve.conf the line:
#search psi.ch is missing
val=$(echo $(nslookup $(hostname).psi.ch ));
hname=$(echo $val|awk '{print $6}')
currhostIP=$(echo $val|awk '{print $8}')
   
#on which subnet am I?
NET=$(echo $currhostIP | awk 'BEGIN { FS = "." } ; { print $1"."$2"."$3"." }')
case "$NET" in
  172.20.*.*)
    #SLS machine subnet
    echo "You are on the SLS machine subnet $NET";
    #tuto musim asi hardcoding of IP address
    #172.20.20.70.|69|71
    #if [ "$bootpcIP" = "$currhostIP" ] 
    if [ "$currhostIP" = "172.20.20.70" ] || [ "$currhostIP" = "172.20.20.69" ] || [ "$currhostIP" = "172.20.20.71" ] 
    then
      do_slink $targetbase $*
    else
      #echo "THis option is on work, please, login to the slsbpc directly."
      SCRPATH="$INSTBASE/sls/bin"
      echo "Logging to $bootpc and calling $SCRPATH/bootlink..."
      ssh $bootpc $SCRPATH/bootlink do_slink $bootpc $targetbase $*
    fi
    ;;
  129.129.[01][0-9].*|129.129.12[0-2].*|129.129.[01][01][0-9].*)
    echo "You are on one of beamlines subnets $NET.";
    if [ "$bootpcIP" = "$currhostIP" ] 
    then
      do_slink $targetbase $*
    else
      SCRPATH="$INSTBASE/sls/bin"
      echo "Logging to $bootpc..."
      ssh $bootpc $SCRPATH/bootlink do_slink $bootpc $targetbase $*
    fi
    ;;
  172.21.70.*)
    echo "You are on FELOBLA subnet $NET";
    if [ "$bootpcIP" = "$currhostIP" ] 
    then
      do_slink $targetbase $ioc
    else
      #ssh $bootpc /psi-xfel/devl/bin/bootlink do_slink $targetbase $ioc $bootpc
      ssh $bootpc /psi-xfel/devl/bin/bootlink do_slink $bootpc $targetbase $*
    fi
    ;;
  129.129.151.*)
    echo "You are on HIPA subnet $NET";
    if [ "$bootpcIP" = "$currhostIP" ] 
    then
      do_slink $targetbase $*
    else
      ssh $bootpc /hipa/prod/bin/bootlink do_slink $bootpc $targetbase $*
    fi
    ;;
  129.129.153.*)
    echo "You are on PROSCAN subnet $NET";
    echo "on work!";
    ;;
  *)
    echo "You are on OFFICE subnet $NET and you need to go to $bootpc";
    #get on which gw we have to go
    #ssh gateway name is defined according naming convention for each facility
    get_gw
    echo "Loging to $ssh_gw..."
    if [ "$CLIENT" = "sls" ]
    then
       SCRPATH="$INSTBASE/sls/bin"
    else
       SCRPATH="$INSTBASE/bin"
    fi
    ssh -t $ssh_gw ssh $bootpc $SCRPATH/bootlink do_slink $bootpc $targetbase $*
    ;;
esac
exit
###############################################################################
#
# $Log: bootlink,v $
# Revision 1.10  2009/03/10 17:46:43  krempaska
# a but in if statement fixed
#
# Revision 1.9  2009/03/10 17:25:45  krempaska
# now it works also for hipa, the call of chkslsbase.sh script was replaced by the awk call which does exectly like this script
#
# Revision 1.8  2009/01/16 13:41:02  krempaska
# fixed for SLS machine
#
# Revision 1.7  2009/01/16 13:00:32  krempaska
# added psi.ch domain to hostname beacause of SLS netvork, which has not domain search in /etc/desolve.conf yet
#
# Revision 1.6  2009/01/13 16:34:07  krempaska
# modified create link: It goes first on the bootpc and then reads/creates a link, adapted also for psi-xfel, prepared for hipa (and proscan)
#
#
##############################################################################
