#!/bin/bash
#
# cs_show_cluster_transition
#
# (c) 2011-2017 SUSE Linux GmbH, Germany.
# (c) 2018-2019 SUSE LLC
# Author: L.Pinne.
# GNU General Public License v2. No warranty.
# http://www.gnu.org/licenses/gpl.html
#
# Version: 2019-11-28 SLES11
#
# shellcheck disable=SC1090
#

EXE="$0"

CFG="/etc/ClusterTools2/cs_show_cluster_transition"
test -s $CFG && source $CFG

RDM=$RANDOM
JCTL=""

test -z "/etc/corosync/corosync.conf" &&\
test -z "${CLUSTER_LOG}" &&\
	 CLUSTER_LOG=$(grep "logfile:.*/" /etc/corosync/corosync.conf |\
		 tr -d "    " | cut -d":" -f2)
test -z "${CLUSTER_LOG}" &&\
	 CLUSTER_LOG="/var/log/messages"

ZIPPED_LOG="${CLUSTER_LOG}*bz2"

if [ ! -s "${CLUSTER_LOG}" ]; then
	if command -v journalctl 2>/dev/null; then
		JCTL="/tmp/journalctl.$RDM"
		CLUSTER_LOG=${JCTL}
	fi
fi

#	 TRANST_PATTERN="
#"crmd.*State.transition.S_IDLE"
#"crmd.*State.transition.S_POLICY_ENGINE"
#"crmd.*State.transition.S_TRANSITION_ENGINE"
#"crmd.*State.transition.S_STARTING"
#"crmd.*State.transition.S_PENDING"
#"crmd.*State.transition.S_ELECTION"
#"crmd.*State.transition.S_INTEGRATION"
#"crmd.*State.transition.S_FINALIZE_JOIN"
#"crmd.*State.transition.S_NOT_DC"
#"

function help() {
	echo "	$(basename "$EXE")"
	echo "	$(basename "$EXE") OPTION"
	echo
	echo " --help		show help."
	echo " --version	show version."
#	echo " --zip		show transitions from compressed logs, too."
	echo " --error	show errors."
}


function show_sleha_release() {
	# TODO
	for b in SUSE_SLES_SAP sle-hae sle-ha SLES_SAP; do
	f=/etc/products.d/$b.prod
	test -r "$f" &&\
		sed -n "s%.*<version>\([1-9][0-9].*[0-9]*\)</version>$%\1%p" "$f"
	done
}


# TODO sort: As LC_TIME differs from LC_CTYPE, the results may be strange.
# TODO better awk

function awk_transition_11-34() {
	# for SLE-HA11 sp3,sp4
	echo "logs: $LOG" >/dev/stderr
	for f in ${LOG}; do
		test -r "$f" && cat "$f"
	done | sort -M -k1,3 |\
	awk '	$0~/crmd.*State.transition/ {print $1,$2,$3,$4,$10,"->",$12}
		$0~/syslog-ng.s...ting.[du][po]/ {print $1,$2,$3,$4,$6,$7,$8}
		$0~/crmd.*cluster.nodes.*eligible/ {print $1,$2,$3,$4,$10,$11,$12,$14}
		$0~/crmd.*status.\[o.*line\]/	{print $1,$2,$3,$4,$10,$14}
		$0~/crmd.*Executing.*fencing/   {print $1,$2,$3,$4,$10,$14}
		$0~/crmd.*update_dc.*Unset.DC/	{print $1,$2,$3,$4,$9,$10,$11,$12}
		$0~/crmd.*update_dc.*Set.DC.to/	{print $1,$2,$3,$4,$9,$10,$11,$12}' |\
	awk '$7=="S_IDLE"{print $0,"\n"}; $7!="S_IDLE"{print $0}'
}

function awk_transition_12-34() {
	# TODO for SLE-HA12 sp3,sp4
	echo "logs: $LOG" >/dev/stderr
	for f in ${LOG}; do
		test -r "$f" && cat "$f"
	done | sort -M -k1,3 |\
	awk '	$0~/crmd.*State.transition/ {print $1,$7,"->",$9}
		$0~/kernel.*bootconsole.*enabled/ {print $0}' |\
	awk '$7=="S_IDLE"{print $0,"\n"}; $7!="S_IDLE"{print $0}'
}

# TODO SLE12 '$0~/crmd.*State.transition/ {print $1,$2,$3,$10,"->",$12}' 
# TODO SLE12 '$0~/crmd.*cluster.nodes.*eligible/ {print $1,$2,$3,$7,$8,$9,$11,$13}'
# TODO SLE12 '$0~/crmd.*Executing.*fencing/ {print $1,$2,$3,$8,$12}'


# TODO LARS, FABIAN: Implement other patterns
# currently not used, so disable shellcheck complains
# shellcheck disable=SC2317
function filter_transition() {
	# for SLE-HA11 sp3,sp4
        echo "logs: $LOG" >/dev/stderr
        for f in ${LOG}; do
                test -r "$f" && cat "$f"
        done | sort -M -k1,3 |\
        perl -e 'while (<>) {
                  if ( /((\S+\s+){4}).*crmd.*State.transition.*(S_\w+)\s*->\s*(S_\w+)/ ) {
                      printf "%s: %s -> %s\n", $1, $3, $4;
                        if ( $4 eq "S_IDLE" ) { printf "\n"; }
                  }
               }'
}


function awk_crmd-error() {
	echo "logs: $LOG" >/dev/stderr
	for f in ${LOG}; do
		test -r "$f" && cat "$f"
	done | sort -M -k1,3 |\
	grep -e "crmd:.*ERROR"
}


# main()

# TODO reading from pipe 

case $1 in
	-h|--help)
		help
		exit
	;;
	-v|--version)
		echo -n "$(basename "$EXE") "
		head -11 "$EXE" | grep "^# Version: "
		exit
	;;
	-z|--zip)
		test -n "${JCTL}" && journalctl --no-pager >$JCTL
		LOG=""
		for z in ${ZIPPED_LOG}; do
			test -s "$z" && LOG="${LOG} ${z}"
		done
		# unzipped log has to be last in loop :-/
		{ test -n "${CLUSTER_LOG}" && test -s "${CLUSTER_LOG}"; } && LOG="${LOG} ${CLUSTER_LOG}"
		#awk_transition_11-34
		echo noop	
		exit
	;;
	-e|--error)
		test -n "${JCTL}" && journalctl --no-pager >$JCTL
		{ test -n "${CLUSTER_LOG}" && test -s "${CLUSTER_LOG}"; } && LOG="${CLUSTER_LOG}"
		awk_crmd-error
		exit
	;;
	*)
		test -n "${JCTL}" && journalctl --no-pager >$JCTL
		{ test -n "${CLUSTER_LOG}" && test -s "${CLUSTER_LOG}"; } && LOG="${CLUSTER_LOG}"
		rel=$(show_sleha_release)
		if [ "$rel" == "11.3" ] || [ "$rel" == "11.4" ]; then
			#filter_transition
			awk_transition_11-34
		else
			awk_transition_12-34
		fi
		exit
	;;
esac
#
