#!/bin/bash
#
# cs_stresscib
#
# (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 10:50
#
# shellcheck disable=SC1090
#

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

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

test -z "${L_NODE}" &&\
	echo "ERR: undefined L_NODE" # && exit 3
	# echo "INF: undefined L_NODE"
	# TODO get L_NODE from cluster
test -z "${F_CRON}" &&\
	F_CRON="/etc/cron.d/cs_stresscib"
test -z "${F_LOG}" &&\
	F_LOG="/var/log/cs_stresscib.log"

attr_store="reboot"			# reboot or forever

# TODO better checks


function do_init() {
	# TODO 2nd arg for stress profile (hana ...)
	# check or create attributes in CIB?
	LNK=2
	test -L "$F_CRON" && LNK=0
	test $LNK -eq 0 && echo "ERR: do_init: existing symlink: $F_CRON: RC=2" >/dev/stderr && exit 2
	test $LNK -eq 0 ||\
		ln -s /usr/share/ClusterTools2/cs_stresscib.cron "$F_CRON" &&\
		echo "INF: created symlink: $F_CRON: RC=0" >/dev/stderr
		grep -v "^#" "$F_CRON"
	touch "$F_LOG"
	SVC=$(/sbin/chkconfig openais | tr -d " ")
	if [ "$SVC" != openaison ]; then
		echo "ERR: do_init: no chkconfig openais on: RC=2" >/dev/stderr
		exit 2
	fi
	time_stamp=$(/bin/date +%F_%H-%M-%S)
	attr_value=${time_stamp}
	for attr_node in ${L_NODE}; do
		attr_name="val_stresscib_${attr_node}"
		do_run_writehost 2>/dev/stderr ; RC=$?
		echo "$time_stamp : do_init : $HOSTNAME ${attr_name} ${attr_value} : RC=$RC" >>"$F_LOG"
		test $RC -eq 0 || echo "ERR: do_init: failed to initialise ${attr_name} : RC=$RC" 2>/dev/stderr
	done
}


function do_exit() {
	LNK=2
	test -L "$F_CRON" && LNK=0
	test -e "$F_CRON" || LNK=0
	test $LNK -eq 0 && rm -f "$F_CRON" &&\
		echo "INF: do_exit: removed symlink: $F_CRON: RC=0" >/dev/stderr && exit 0
	test $LNK -eq 0 || echo "ERR: do_exit: not a symlink: $F_CRON: RC=2" >/dev/stderr && exit 2
	# TODO remove attributes from CIB
}


function do_run() {

	/etc/init.d/openais status >/dev/null 2>&1; RC=$?
	if [ "$RC" != "0" ]; then
		echo "ERR: do_run: openais not running: RC=$RC" >>/dev/stderr
	# TODO double check if this works
		exit $RC
	fi

#
# stress profile for SAP HANA scale-out, to run every 20-30 seconds
# 	host attributes
#		write	6 x N_NODE
#		read	N_NODE x N_NODE
# 	cluster attributes
#		write	2
#		read	N_NODE		(planned ca.2 later)
#

	time_stamp=$(/bin/date +%F_%H-%M-%S)
	# write host specific attributes, 6 x $N_NODE times
	# TODO how many attributes: 6 x $N_NODE or $N_NODE ?
 	attr_value=${time_stamp}
	attr_node=$HOSTNAME
	for _ in {1..6}; do
 		attr_name="val_stresscib_${attr_node}"
		do_run_writehost 2>/dev/null; RC=$?
		echo "$time_stamp : do_run_writehost : ${attr_node} ${attr_name} ${attr_value} : RC=$RC"
	done

	time_stamp=$(/bin/date +%F_%H-%M-%S)
	# write cluster specific attributes, 2 times
	attr_value=${time_stamp}
	NODE_1=$(echo "$L_NODE" | cut -d" " -f1)
	# TODO better to get NODE_2 from last entry?
	NODE_2=$(echo "$L_NODE" | cut -d" " -f2)
	if [ "$HOSTNAME" = "$NODE_1" ] || [ "$HOSTNAME" = "$NODE_2" ]; then
		attr_name="val_stresscib_cluster"
		do_run_writecluster; RC=$?
		echo "$time_stamp : do_run_writecluster : cluster ${attr_name} ${attr_value} : RC=$RC"
	fi

	time_stamp=$(/bin/date +%F_%H-%M-%S)
	# read host specific attributes, $N_NODE x $N_NODE times
	# TODO who writes all hosts attributes? do_run_writehosts writes only two
	for attr_node in ${L_NODE}; do
		attr_name="val_stresscib_${attr_node}"
		attr_value=$(do_run_readhost); RC=$?
		echo "$time_stamp : do_run_readhost : ${attr_node} ${attr_name} ${attr_value} : RC=$RC"
	done

	time_stamp=$(/bin/date +%F_%H-%M-%S)
	# read cluster specific attributes, $N_NODE times
	attr_node=$HOSTNAME
	attr_name="val_stresscib_cluster"
	attr_value=$(do_run_readcluster | cut -d" " -f4 | cut -d"=" -f2); RC=$?
	echo "$time_stamp : do_run_readcluster : ${attr_node} ${attr_name} ${attr_value} : RC=$RC"
}


function do_run_writehost(){
	# echo "/usr/sbin/crm_attribute -N ${attr_node} -v \"$attr_value\" -n \"$attr_name\" -l $attr_store -q"
	/usr/sbin/crm_attribute -N "${attr_node}" -v "$attr_value" -n "$attr_name" -l $attr_store -q
}


function do_run_readhost(){
	/usr/sbin/crm_attribute -N "${attr_node}" -G -n "$attr_name" -l $attr_store -q
}


function do_run_writecluster(){
	/usr/sbin/crm_attribute -t crm_config -v "$time_stamp" -n "$attr_name"
}


function do_run_readcluster(){
	/usr/sbin/crm_attribute -t crm_config -G -n "$attr_name"
}


function do_run_cibadmin() {
	time_stamp=$(/bin/date +%F_%H-%M-%S)
	/usr/sbin/cibadmin -Q >/dev/null 2>&1; RC=$?
	echo "$time_stamp : do_run_cibadmin : $HOSTNAME : RC=$RC"
}


function do_show() {
	# TODO summary only?
	# TODO options?
	echo noop
}


function do_help() {
	echo "usage: $(basename "$EXE") [--help | --version | --init | --exit | --run ] "
	echo "usage: $(basename "$EXE") --run [123] "
	echo
	echo " --init		initialise cib stress cron job."
	echo " --exit		stop cib stress cron job."
	echo " --run		run cib stress, reads optional argument for load."
	echo " --show		show cib cron job stress log."
	echo " --help		show help."
	echo " --version	show version."
	echo
	echo "please adapt L_NODE in /etc/ClusterTools2/cs_stresscib."
}


# main()

case $1 in
	-v|--version)
		echo -n "$(basename "$EXE") "
		head -11 "$EXE" | grep "^# Version: "
		exit
	;;
	-i|--init)
		do_init
	;;
	-e|exit)
		do_exit
	;;
	-r|run)
		shift
		LOAD=1
		test -z "$1" || LOAD=$1
		case $LOAD in
			1)
				do_run >>"$F_LOG" 2>&1
			;;
			2)
				do_run >>"$F_LOG" 2>&1
				do_run_cibadmin >>"$F_LOG" 2>&1
			;;
			3)
				do_run >>"$F_LOG" 2>&1
				do_run_cibadmin >>"$F_LOG" 2>&1
				# TODO what else?
			;;
		esac
	;;
	-s|show)
		do_show
	;;
	*)
		do_help
		exit
	;;
esac
#
