#!/bin/bash -fp
#
# swstat v1.7 2013-08-04 , Finn Magnusson, finn.magnusson@ericsson.com
# Type "swstat" on its own for help

###########################################################################################
# Pathes to files:
# The timeout (in minutes) indicates after how many minutes mobatch will timeout. 
# Make it long (90 minutes) because of the delete transaction.
# The maxProcess indicates how many moshell sessions mobatch will run in parallel. Default= 20.
###########################################################################################
maxProcess=20
timeout=90
moshelldir=`dirname "$0"`
if [[ $moshelldir != /* ]] ; then moshelldir=`pwd`/$moshelldir ; fi
logdir="$moshelldir/logfiles/logs_swstat"
mobatch=$moshelldir/mobatch
moshell=$moshelldir/moshell
vobsinstallation=0
unamea=$(uname -a)
gawkext=""
gawklib=""
if [[ $unamea = [Ll][iI][nN][uU][xX]*x86_64* ]] ; then gawklib="lin64"   ; if [[ $vobsinstallation = 1 ]] ; then gawkext=".lin64" ; fi
elif [[ $unamea = [Ll][iI][nN][uU][xX]* ]]      ; then gawklib="linux"   ; if [[ $vobsinstallation = 1 ]] ; then gawkext=".linux" ; fi
elif [[ $unamea = SunOS*sparc* ]]               ; then gawklib="solaris" ; if [[ $vobsinstallation = 1 ]] ; then gawkext=".solaris" ; fi
elif [[ $unamea = SunOS* ]]                     ; then gawklib="sol86"   ; if [[ $vobsinstallation = 1 ]] ; then gawkext=".sol86" ; fi
else gawklib="cygwin" ; gawkext=".exe"
fi
gawkprog="gawk${gawkext}" 
gawk="$moshelldir/$gawkprog"
#special case where moshell has been installed on a linux 32 bit machine but should be run on linux 64 sharing the same file system
if [[ $unamea = [Ll][iI][nN][uU][xX]*x86_64* && $vobsinstallation != 1 && `file "$moshelldir/gawk"` = *32-bit* ]] ; then gawklib="linux" ; fi
filefunc="$moshelldir/commonjars/lib/${gawklib}/filefuncs"
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}$moshelldir/commonjars/lib/${gawklib}
export LANG=C
export LC_ALL=C

defLogDir=$moshelldir/commonjars/defLogDir.sh
temp_logdir=$($defLogDir swstat)
if [[ -w $temp_logdir && -d $temp_logdir ]] ; then logdir=$temp_logdir ; fi
tempsitedir=$logdir/temp_sitefiles
mkdir -p $tempsitedir
###########################################################################################


function print_usage()
{
cat <<EOF
Usage:  swstat [-p <maxProcess>] [-d <package revision>] <sitefile> [<upgradepackage revision>]
	Purpose: to print the SW version and CV currently running in a number of nodes.
		 to print state of other UPs loaded on the nodes
		 to delete a given Upgrade Package revision from the nodes
			
	examples: swstat victoria-sites.txt	       ==> to print which Upgrade Package is currently running
		  swstat victoria-sites.txt r14d       ==> to print which UP is running AND state of UP R14D.		  
		  swstat -d r14d victoria-sites.txt    ==> to delete package revision R14D in all victoria sites.

	Arguments:
	 - The first argument is the sitefile, containing IP/DNS addresses and/or 
	site names whose IP address are defined in the IP database.
	See example of sitefile in: moshell/examples/mobatch_files
	See example of ipdatabase in: moshell/examples/mobatch_files
	 - the second argument (optional) is used to print the state of another UP and 
	 should match the revision of that UP.
	 
	 Options (optional):
	   -p <maxProcess> in order to specify the maximum number of parallel processes (default is 20). 
	   -d <package revision> in order to delete an upgrade package of a certain revision.
	 It is possible to specify several packages by using the pipe sign. E.g: -d "R14B|R14C"
	 (In this case, double quotes are necessary).

	Output: Prints following info for a list of sites (queries done in parallel for quicker result)
	 - without the second argument:
=============================================================================================================
site     UP      CV_loaded                       CV_startable                    OTHER UPs           u/c  u/d
=============================================================================================================
H3RG     R6C     P2.0.13_B1.4_CR38_94rbs         P2.0.13_Rev_B1.4_CR39_94rbs     R4D:1,R4E:0,R5D:1   37%  40%

UP State values: 0=NOT_INSTALLED, 1=INSTALL_COMPLETED, 2=UPGRADE_EXECUTING, 3=AWAITING_CONFIRMATION, 4=ONLY_DELETEABLE
                 5=INSTALL_EXECUTING, 6=INSTALL_NOT_COMPLETED, 7=UPGRADE_COMPLETED (states 5/6/7 not applicable on cello 3)

	 - with the second argument:
=====================================================================================================================
site     UP      R7B     CV_loaded                       CV_startable                    OTHER UPs           u/c  u/d    
=====================================================================================================================
H3RG     R6C     1       P2.0.13_B1.4_CR38_94rbs         P2.0.13_Rev_B1.4_CR39_94rbs     R4D:1,R4E:0,R5D:1   37%  40%    

EOF
}

#Note: 
#options used when swstat is called by swup (not intended to be used when swstat is run on its own):
#	-i <upgradepackage name>  to check if the upgrade package has previously been installed
#	-u <upgradepackage name>  to check if the upgrade package has been correctly installed
#	-c <upgradepackage name>  to check if the upgrade package is in awaitingconfirm state


password="unknown"
package_to_delete="unknown"
while getopts "i:u:c:f:d:p:" options
do
case $options in
i) check_for_install=1
   upgradepackage=$OPTARG
   ;;
u) check_for_upgrade=1
   upgradepackage=$OPTARG
  ;;    
c) check_for_confirm=1
   upgradepackage=$OPTARG
  ;;  
f) check_for_finish=1
   upgradepackage=$OPTARG
    ;;
d) package_to_delete=$OPTARG   
   delete_package=1
   ;;
p) maxProcess=$OPTARG
   ;;
*) ;;  
esac
done 
shift $(($OPTIND - 1))
#if test $OPTIND -eq 1 ; then print_usage ; exit 1; fi

case $# in
1) if test -f "$1" ; then sitefile="$1" ; sitefilename=$(basename $sitefile) ; else echo "Cannot read sitefile. Exiting ..." ; exit 1 ; fi
   ;;
2) if test -f "$1" ; then sitefile="$1" ; sitefilename=$(basename $sitefile) ; else echo "Cannot read sitefile. Exiting ..." ; exit 1 ; fi
   upgradepackage=$2
   ;;
*) print_usage ; exit 1
  ;;   
esac


command="lt config|upgrade;pr upgrade;get config loaded|startable|upgrade;get upgrade admin|state;vols"
if test $package_to_delete != "unknown" ; then command="lt upgrade;ma delpack upgrade admin productrevision.=.(${package_to_delete});del delpack" ; fi

$gawk -v sitefile="$sitefile" -v command="$command" -v logdir="$logdir" -v sitefilename="$sitefilename" -v monode="$monode" -v upgradepackage="$upgradepackage" -v check_for_confirm=$check_for_confirm -v password=$password -v check_for_upgrade=$check_for_upgrade -v check_for_install=$check_for_install -v check_for_finish=$check_for_finish -v tempsitedir="$tempsitedir" -v other_up=$other_up -v check_vols=$check_vols -v delete_package="$delete_package" -v package_to_delete="$package_to_delete" -v maxProcess=$maxProcess -v mobatch=$mobatch -v timeout=$timeout -v vobsinstallation="$vobsinstallation" '
BEGIN {
	"date +%y%m%d-%H%M" | getline date
        close("date +%y%m%d-%H%M")
        logdir=sprintf("%s/%s_%s",logdir,date,sitefilename)
	logfile_all=sprintf("%s/swstat_%s.res",logdir,sitefilename)
	if (system(sprintf("mkdir -p %s",logdir)) == 0)
	{
		if (delete_package == 1) printf("\nDeleting packages with revisions matching %s...\n\n",package_to_delete)
		#printf("%s -t %s -p %s %s \x27 %s \x27 %s\n",mobatch,timeout,maxProcess,sitefile,command,logdir)
		system(sprintf("%s -t %s -p %s %s \x27 %s\x27 %s",mobatch,timeout,maxProcess,sitefile,command,logdir))
		if (delete_package != 1)
		{
			printf("\nLogging final result to file %s\n",logfile_all)
			printf("To sort by a specific column, run: sort -k <column_number> <logfile>\n")
			printf("Example: to sort by the second column, run: sort -k 2 <logfile>\n\n")
			if (upgradepackage != "")
				heading=sprintf("\
UP State values: 0=NOT_INSTALLED, 1=INSTALL_COMPLETED, 2=UPGRADE_EXECUTING, 3=AWAITING_CONFIRMATION, 4=ONLY_DELETEABLE\n\
                 5=INSTALL_EXECUTING, 6=INSTALL_NOT_COMPLETED, 7=UPGRADE_COMPLETED (states 5/6/7 not applicable on cello 3)\n\
=========================================================================================================================\n\
%-7s  %-6s  %-6s  %s %s  %-39s  %-39s  %s\n\
=========================================================================================================================",\
"site","UP",upgradepackage,"u/c","u/d","CV_Loaded","CV_Startable","Other UPs")
			else
				heading=sprintf("\
UP State values: 0=NOT_INSTALLED, 1=INSTALL_COMPLETED, 2=UPGRADE_EXECUTING, 3=AWAITING_CONFIRMATION, 4=ONLY_DELETEABLE\n\
                 5=INSTALL_EXECUTING, 6=INSTALL_NOT_COMPLETED, 7=UPGRADE_COMPLETED (states 5/6/7 not applicable on cello 3)\n\
=========================================================================================================================\n\
%-7s  %-6s  %s %s  %-39s  %-39s  %s\n\
=========================================================================================================================",\
"site","UP","u/c","u/d","CV_Loaded","CV_Startable","Other UPs")
			print heading
			if (logfile_all != "") print heading > logfile_all
			while (sprintf("ls -l %s",logdir) |& getline) 
			{
				gsub("\r","")
				if ($1 ~ /^-rw/ && $NF !~ /swstat_.*.res/ )
				{
					i++
					logfile[i]=sprintf("%s/%s",logdir,$NF)
					sitename[i]=gensub(/.log/,"",1,$NF)
				}
			}
			close(sprintf("ls -l %s",logdir))
			nr_of_files=i
			for (i=1;i<=nr_of_files;i++)
			{
				while (getline < logfile[i])
				{
					gsub("\r","")
					print_info[sitename[i]]=0
					while (getline line < logfile[i] )
					{
						gsub("\r","",line)
						if ((line ~ "Checking ip contact...Not OK"))
						{	
							loaded[sitename[i]]="NO CONTACT"
						}
						else if ((line ~ /Fetching IOR file...Failed!|Cannot connect to MO service, exiting.../))
						{	
							loaded[sitename[i]]="FAIL"
						}
						else
						{
							last=split(line,array," ")
							if (array[1] == "/d") d_usage[sitename[i]]=array[4] 
							else if (array[1] == "/c") c_usage[sitename[i]]=array[4]
							else if (line ~ "currentLoadedConfigurationVersion") loaded[sitename[i]]=array[last]
							else if (line ~ "startableConfigurationVersion") startable[sitename[i]]=array[last]
							else if (line ~ "currentUpgradePackage" ) up_name[sitename[i]]=array[last]
							#if (upgradepackage != "") up_name[sitename[i]]=upgradepackage
							else if ((line ~ /UpgradePackage=.* +state/))#&&(line !~ up_name[sitename[i]]))
							{
								#split(line,array," ")
								up_states[array[1]]=array[3]
								#printf("up_states[%s,%s]=%s\n",sitename[i],array[1],array[3])
								nr_of_ups[sitename[i]]++
								if (line ~ up_name[sitename[i]]) up_state[sitename[i]]=array[last]
							}
							else if ((line ~ /UpgradePackage=.* +admin/))#&&(line !~ up_name[sitename[i]]))
							{
								#split(line,array," ")
								var=array[1]
								getline line < logfile[i] ; gsub("\r","",line)
								getline line < logfile[i] ; gsub("\r","",line)
								last=split(line,array," ")
								up_revs[var]=array[last]
								if (var ~ up_name[sitename[i]]) up_rev[sitename[i]]=array[last]
							}
							#else if ((line ~ up_name[sitename[i]])&&(line ~ "state")) 
							#{
							#	up_state[sitename[i]]=array[last]
							#}
							#else if ((line ~ up_name[sitename[i]])&&(line ~ "administrativeData")) 
							#{
							#	getline line < logfile[i] ; gsub("\r","",line)
							#	getline line < logfile[i] ; gsub("\r","",line)
							#	last=split(line,array," ")
							#	up_rev[sitename[i]]=array[last]
							#}	
						}
					}
				}
				close(logfile[i])
				j=0
				for (comb in up_revs)
				{
					if ((tolower(comb) ~ tolower(upgradepackage))&&(upgradepackage != ""))
					{
						check_up_state[sitename[i]]=up_states[comb]
						check_up_rev[sitename[i]]=up_revs[comb]
					}
					else otherUpStatesTemp[++j]=up_revs[comb]":"up_states[comb]
				}
				#if (check_up_state[sitename[i]]=="")
				n=asort(otherUpStatesTemp)
				for (j=1;j<=n;j++)
					otherUpStates[sitename[i]]=sprintf("%s,%s",otherUpStates[sitename[i]],otherUpStatesTemp[j])
				otherUpStates[sitename[i]]=gensub(/^,/,"","g",otherUpStates[sitename[i]])
				if (upgradepackage != "") output=sprintf("%-7s  %-6s  %-6s  %3s %3s  %-39s  %-39s  %s",sitename[i],up_rev[sitename[i]],check_up_state[sitename[i]],c_usage[sitename[i]],d_usage[sitename[i]],loaded[sitename[i]],startable[sitename[i]],otherUpStates[sitename[i]]) 
				else output=sprintf("%-7s  %-6s  %3s %3s  %-39s  %-39s  %s",sitename[i],up_rev[sitename[i]],c_usage[sitename[i]],d_usage[sitename[i]],loaded[sitename[i]],startable[sitename[i]],otherUpStates[sitename[i]]) 			
				print output
				if (logfile_all != "") print output >> logfile_all
				close(logfile_all)
				delete otherUpStatesTemp
				delete up_revs
			}
		}
		if (check_for_install == 1)
		{
		        list_of_ready_sites=sprintf("%s/%s_%s_install",tempsitedir,date,sitefilename)
			print "\nThis print is for checking sites that already have the package installed."
			print "List of sites ready for install copied to " list_of_ready_sites
			print "" > list_of_ready_sites
			for (site in up_rev)
			{
				#if (tolower(up_state[site]) !~ "installed") print site >> list_of_ready_sites
				if ((check_up_state[site] != 1)&&(tolower(upgradepackage) !~ tolower(up_rev[site])))  print site >> list_of_ready_sites
			}
			print "To install, run command: swup -i "list_of_ready_sites" <swfile>\n"
		}
		if (check_for_upgrade == 1)
		{
		        list_of_ready_sites=sprintf("%s/%s_%s_upgrade",tempsitedir,date,sitefilename)
			print "\nList of sites ready for upgrade copied to " list_of_ready_sites
			print "" > list_of_ready_sites
			for (site in check_up_state)
			{
				#if (tolower(up_state[site]) ~ "(installed)") print site >> list_of_ready_sites
				if (check_up_state[site] == 1) print site >> list_of_ready_sites
			}
			print "To upgrade, run command: swup -u "list_of_ready_sites" <swfile>\n"
		}
		if (check_for_confirm == 1)
		{
		        list_of_ready_sites=sprintf("%s/%s_%s_confirm",tempsitedir,date,sitefilename)
			print "\nList of sites ready for confirm copied to " list_of_ready_sites
			print "" > list_of_ready_sites
			for (site in check_up_state)
			{
				#if (tolower(up_state[site]) ~ "confirm") print site >> list_of_ready_sites
				if (check_up_state[site] == 3) print site >> list_of_ready_sites
			}
			print "To confirm, run command: swup -c "list_of_ready_sites" <swfile>\n"
		}
		if (check_for_finish == 1)
		{
		        list_of_ready_sites=sprintf("%s/%s_%s_finish",tempsitedir,date,sitefilename)
			print "\nList of sites ready for finish copied to " list_of_ready_sites
			print "" > list_of_ready_sites
			for (site in up_rev)
			{
				#if (tolower(up_state[site]) ~ "installed") print site >> list_of_ready_sites
				if (tolower(gensub("/","%","g",upgradepackage)) ~ tolower(gensub("/","%","g",up_rev[site]))) print site >> list_of_ready_sites
			}
			print "To restart, run command: swup -r "list_of_ready_sites"\n"
		}
		
	}
	else print "Unable to create log directory."
}
'

