#!/bin/bash
#
# cs_detect_sleha
#
# (c) 2016 SUSE Linux GmbH, Germany. Author: L.Pinne.
# GNU General Public License v2. No warranty.
# http://www.gnu.org/licenses/gpl.html
#
# Version: 2016-08-05 11:11 SLES11
#

EXE="$0"
ERR="/dev/null"

CFG="/etc/ClusterTools2/cs_detect_sleha"
test -s $CFG && source $CFG
DELCIBCFG="/etc/ClusterTools2/cs_delcib"
test -s $DELCIBCFG && source $DELCIBCFG

test -z "${ZYPTMO}" &&\
	ZYPTMO="5"

test -z "${SLEHA_BASE_FIL}" &&\
	SLEHA_BASE_FIL="
/etc/corosync/corosync.conf
/var/lib/pacemaker/cib/cib.xml
"
test -z "${SLEHA_MISC_FIL}" &&\
	SLEHA_MISC_FIL="
/etc/sysconfig/sbd
/etc/products.d/sle-hae.prod
/etc/corosync/authkey
/var/lib/corosync/ringid_*
/var/lib/pacemaker/pengine/*last
/etc/csync2/csync2.cfg
/etc/drbd.conf
/var/cache/zypp/raw/*/suse/setup/descr/ha_sles*.pat.gz
"
test -z "${SLEHA_KERN_FIL}" &&\
	SLEHA_KERN_FIL="
/etc/drbd.conf
/etc/ocfs2/cluster.conf
/etc/sysconfig/o2cb
/etc/rear/local.conf
"
test -z "${SLEHA_BASE_RPM}" &&\
	SLEHA_BASE_RPM="
openais
corosync
crmsh
pacemaker
resource-agents
cluster-glue
libglue2
libcorosync4
libpacemaker3
libopenais3
"
test -z "${SLEHA_MISC_RPM}" &&\
	SLEHA_MISC_RPM="
sle-hae-release
sle-hae-release-cd
release-notes-hae
ocfs2-tools
csync2
pacemaker-mgmt
pacemaker-mgmt-client
pacemaker-cli
hawk
drbd
drbd-pacemaker
yast2-cluster
yast2-drbd
yast2-iplb
ldirectord
lvm2-clvm
cmirrord
conntrack-tools
pssh
python-pssh
python-dateutil
sleha-bootstrap
ctdb
libdlm3
libdlm
cluster-network-kmp-default
hawk-templates
scsires
sbd
"
test -z "${SLEHA_KERN_RPM}" &&\
	SLEHA_KERN_RPM="
ocfs2-tools-o2cb
ocfs2-kmp-default
ocfs2-kmp-xen
drbd-utils
drbd-kmp-default
drbd-kmp-xen
rear
rear116
"
# some RPMs are in SLES or SLE-SDK as well
test -z "${SLEHA_EXTR_RPM}" &&\
	SLEHA_EXTR_RPM="
libgnutls-extra26
rubygems
lighttpd
"
# some RPMs are in SLES-for-SAP only
test -z "${SLEHA_4SAP_RPM}" &&\
        SLEHA_4SAP_RPM="
SAPHanaSR
SAPHanaSR-ScaleOut
sap_suse_cluster_connector
"
# find . -name "*.rpm" | while read; do rpm -qip $REPLY |\
# awk '$1=="Name" {print $3}'; done | sort
# remove SLEHA_EXTR_RPM from the list
test -z "${SLEHA_REPO_RPM}" &&\
        SLEHA_REPO_RPM="
cluster-glue
cluster-network-kmp-default
cluster-network-kmp-trace
cluster-network-kmp-xen
cmirrord
conntrack-tools
corosync
crmsh
csync2
ctdb
drbd
drbd-bash-completion
drbd-heartbeat
drbd-kmp-default
drbd-kmp-trace
drbd-kmp-xen
drbd-pacemaker
drbd-udev
drbd-utils
drbd-xen
fence-agents
gfs2-kmp-default
gfs2-kmp-trace
gfs2-kmp-xen
graphviz-python
hawk
hawk-templates
ipvsadm
ldirectord
libcorosync4
libcorosync-devel
libdlm
libdlm3
libdlm-devel
libglue2
libglue-devel
libnetfilter_conntrack3
libnetfilter_conntrack-devel
libnfnetlink-devel
libopenais3
libopenais-devel
libpacemaker3
libpacemaker-devel
libqb0
libqb-devel
librsync
lvm2-clvm
nagios-plugins-metadata
ocfs2console
ocfs2-kmp-default
ocfs2-kmp-trace
ocfs2-kmp-xen
ocfs2-tools
ocfs2-tools-devel
ocfs2-tools-o2cb
openais
pacemaker
pacemaker-cli
pacemaker-mgmt
pacemaker-mgmt-client
pacemaker-mgmt-devel
pacemaker-remote
pssh
python-dateutil
python-pexpect
python-pssh
python-suds
rear
rear116
rear-SUSE
release-notes-hae
resource-agents
rubygem-bundler
sbd
scsires
sleha-bootstrap
sle-hae-release
sle-hae-release-cd
sle-ha-guide_en-pdf
sleha-guide_ja
sleha-guide_ja-pdf
sleha-guide_zh_CN
sleha-guide_zh_CN-pdf
sleha-guide_zh_TW
sleha-guide_zh_TW-pdf
sle-ha-manuals_en
sle-ha-nfs-quick_en-pdf
sqlite2
yast2-cluster
yast2-drbd
yast2-iplb
yast2-multipath
yast2-rear
"
# from cs_delcib
test -z "${FIL}" &&\
        FIL="
/var/lib/corosync/*
/var/lib/heartbeat/cores/*/*
/var/lib/heartbeat/crm/*
/var/lib/pengine/*
/var/lib/pacemaker/cib/*
/var/lib/pacemaker/pengine/*
"
test -z "${BAK}" &&\
        BAK="/var/adm/backup/cib.xml-$(date +%Y%m%d-%H%M%S)"
#

CFGVAR="
ZYPTMO
SLEHA_BASE_FIL
SLEHA_KERN_FIL
SLEHA_MISC_FIL
SLEHA_BASE_RPM
SLEHA_KERN_RPM
SLEHA_MISC_RPM
SLEHA_EXTR_RPM
SLEHA_4SAP_RPM
SLEHA_REPO_RPM
"

# TODO show RPM list from pattern file

function help(){
	echo "usage:	$(basename $0) [OPTION]"
	echo
	echo " --help		show help"
	echo " --version	show version"
	echo " --writecfg	show some internal variables"
	echo
	echo " --detect	shown number of installed substantial RPMs, files "
	echo " --installed	show installed substantial RPMs"
	echo " --available	show available base RPMs"
	echo " --standalone	show installed standalone RPMs, files"
	echo " --files	show common files"
	echo " --pedantic	show even minimal traces of SLE-HA"
	echo " --uninstall	uninstall substantial RPMs of SLE-HA"
	echo " --removeall	remove RPMs, files, repos of SLE-HA (DANGER)"
	echo
}


function writecfg(){
	# TODO --writecfg <variable_name> show single variable
	#echo "INFO: ### $FUNCNAME $1 start ###" >/dev/stderr
	echo -e "# $CFG \n# For SLES11.\n#"
	for c in $CFGVAR; do
		echo "${c}=\""
		echo ${!c} | tr " " "\n"
		echo "\""
		echo "#"
	done
	#echo "INFO: ### $FUNCNAME $1 end ###" >/dev/stderr
}


function get_inst_rpmall(){
	RC=0
	ALL_RPM=$(timeout $ZYPTMO rpm -qa 2>$ERR | sort; RC=$?)
	if [ $RC -ne 0 ]; then
		echo "ERR: Can not read from rpm. RC=$RC"
		exit $RC
	fi
}


function get_avail_rpmall(){
	RC=0
	ALL_RPM=""
	timeout $ZYPTMO zypper ref 2>$ERR 1>$ERR
	ALL_RPM=$( (timeout $ZYPTMO zypper se -s 2>$ERR ; RC=$?) |\
		awk -F"|" '$1!~/\.\.\./ {print $2,$4}' | tr -s " " |\
		cut -b2- | sed -e s/" "$//g -e s/" "/"-"/g | sort -u )
		# TODO above lines in one awk and one sed
	if [ $RC -ne 0 -o "$ALL_RPM" = "" ]; then
		echo "ERR: Can not read from zypper. RC=$RC"
		ALL_RPM=$(timeout $ZYPTMO rpm -qa 2>$ERR | sort; RC=$?)
		if [ $RC -ne 0 ]; then
			echo "ERR: Can not read from rpm. RC=$RC"
			exit $RC
		fi
	fi
	# TODO better error handling
}


function remove_files(){
	echo "INFO: ### $FUNCNAME $1 start ###"
	for f in $SLEHA_BASE_FIL $SLEHA_MISC_FIL $SLEHA_KERN_FIL; do
		rm -rf $f
	done
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function remove_rpms(){
	echo "INFO: ### $FUNCNAME $1 start ###"
	case $1 in
		base)
		for f in $SLEHA_BASE_RPM; do
			rpm -e --allmatches --nodeps $f 2>$ERR
		done
		;;
		misc)
		for f in $SLEHA_MISC_RPM; do
			rpm -e --allmatches --nodeps $f 2>$ERR
		done
		;;
		kern)
		for f in $SLEHA_KERN_RPM; do
			rpm -e --allmatches --nodeps $f 2>$ERR
		done
		;;
		4sap)
		for f in $SLEHA_4SAP_RPM; do
			rpm -e --allmatches --nodeps $f 2>$ERR
		done
		;;
		repo)
		for f in $SLEHA_REPO_RPM; do
			rpm -e --allmatches --nodeps $f 2>$ERR
		done
		;;
	esac
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function remove_repos(){
	echo "INFO: ### $FUNCNAME $1 start ###"
	# TODO timeout $ZYPTMO zypper rs (removeservice)
	# TODO timeout $ZYPTMO zypper rr (removerepo)
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function remove_cib(){
	echo "INFO: ### $FUNCNAME $1 start ###"
	#test -x /usr/sbin/cs_delcib && /usr/sbin/cs_delcib --offline
	for f in $FIL $BAK; do
		rm -rf $f
	done
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function detect_files(){
	# TODO read variable name from call, avoid case
	echo "INFO: ### $FUNCNAME $1 start ###"
	case $1 in
		base)
		for f in $SLEHA_BASE_FIL; do
			ls -l $f 2>$ERR
		done
		;;
		misc)
		for f in $SLEHA_MISC_FIL; do
			ls -l $f 2>$ERR
		done
		;;
		kern)
		for f in $SLEHA_KERN_FIL; do
			ls -l $f 2>$ERR
		done
		;;
	esac
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function detect_inst_rpms(){
	# TODO read variable name from call, avoid case
	echo "INFO: ### $FUNCNAME $1 start ###"
	( case $1 in
		base)
		for r in $SLEHA_BASE_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		misc)
		for r in $SLEHA_MISC_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		kern)
		for r in $SLEHA_KERN_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		4sap)
		for r in $SLEHA_4SAP_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		repo)
		for r in $SLEHA_REPO_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
	esac ) | sort -u
	echo "INFO: ### $FUNCNAME $1 end ###"
}


function detect_avail_rpms(){
	# TODO read variable name from call, avoid case
	echo "INFO: ### $FUNCNAME $1 start ###"
	( case $1 in
		base)
		for r in $SLEHA_BASE_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		misc)
		for r in $SLEHA_MISC_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		kern)
		for r in $SLEHA_KERN_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		4sap)
		for r in $SLEHA_4SAP_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
		repo)
		for r in $SLEHA_REPO_RPM; do
			echo $ALL_RPM | tr " " "\n" | grep "${r}-"
		done
		;;
	esac ) | tr -s " " | sort -u |\
	sed s/"Abort..retry..ignore.*options...a.."// |\
	grep -v "in.*\.\.\.$" | grep -v "^S.\|.Name" | grep -v -- "^--+" |\
	grep -v "^Repository" | grep -v "^All.repositories" |\
	grep -v "^No.packages.found" | grep -v "srcpackage"
	echo "INFO: ### $FUNCNAME $1 end ###"
	# TODO better grep, maybe positive filter function
}


function detect_repos(){
	echo "INFO: ### $FUNCNAME $1 start ###"
	# TODO detect repos
	#case $1 in
	#timeout $ZYPTMO zypper ... --with-repos --sort-by-priority --details --uri
	#esac
	echo "INFO: ### $FUNCNAME $1 start ###"
}


# main()
case $1 in
	-v|--version)
		echo -n "$(basename $EXE) "
		head -11 $EXE | grep "^# Version: "
		exit
	;;
	-h|--help)
		help
		exit
	;;
	-w|--writecfg)
		writecfg
		exit
	;;
	-a|--available)
		get_avail_rpmall
		detect_avail_rpms base
		detect_inst_rpms kern
		detect_inst_rpms 4sap 
		exit
	;;
	-i|--installed)
		get_inst_rpmall
		detect_inst_rpms base
		detect_inst_rpms kern 
		detect_inst_rpms 4sap 
		exit
	;;
	-f|--files)
		detect_files base
		detect_files kern
		detect_files misc
		exit
	;;
	-s|--standalone)
		detect_files kern
		get_inst_rpmall
		detect_inst_rpms kern
		exit
	;;
	-p|--pedantic|--paranoid|--penetrant)
		detect_files base
		detect_files kern
		detect_files misc
		get_avail_rpmall
		detect_avail_rpms repo
		detect_avail_rpms 4sap 
		exit
	;;
	-u|--uninstall)
		YESNO=no
		read -p "Uninstall RPMs of SLE-HA? [yes/no]: " YESNO
		[[ $YESNO == "yes" ]] || exit
		# remove_rpm repo # but NOT: libgnutls, ligthttpd, rubygems
		remove_rpms base
		remove_rpms kern
		remove_rpms misc
		remove_rpms 4sap 
		exit
	;;
	-r|--removeall)
		YESNO=no
		read -p "Remove RPMs, files, repos of SLE-HA? (DANGER) [yes/no]: " YESNO
		[[ $YESNO == "yes" ]] || exit
		echo remove_files base
		echo remove_files kern
		echo remove_files misc
		echo remove_cib
		echo remove_rpms repo
		echo remove_rpms 4sap 
		# TODO remove_repos
		exit
	;;
	-d|--detect|*)
		#set -x
		RC=0
		RC=$(
		 ( detect_files base
                   detect_files kern
                   detect_files misc
                   detect_files 4sap
		   get_inst_rpmall
                   ( detect_inst_rpms base
		     detect_inst_rpms kern
		     detect_inst_rpms misc
		   ) | grep -v -- "-devel" | grep -v "sdksp.*-"
		 )   | grep -v "^INFO:.*###" | tr -s "\n" 2>$ERR | wc -l )
		echo "${EXE}: Found $RC hints on installed SLE-HA" >/dev/stderr
		exit $RC
		# TODO add function's real rc ($?) to RC as well
		# TODO better excluding for RPMs from SDK (-devel)
	;;
esac
#
