#!/bin/bash
################################################################################
# Filename: ./src/base/sbin/qrm-execd
# 
# The contents of this file are subject to the Qlusters Public License
# Version 1.1 (the License); you may not use this file except in compliance
# with the License.
# You may obtain a copy of the License at
# http://www.openqrm.org/content/view/33/69/.
# 
# Software distributed under the License is distributed on an AS IS basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
# the specific language governing rights and limitations under the License.
# 
# The Original Code is openQRM.
# 
# The Initial Developer of the Original Code is Qlusters Corporation. Portions
# created by Qlusters Corporation are Copyright (C) 2003-2005. All Rights
# Reserved.
# 
# Contributor(s):
# 
# Description:
# 
# Comments:
################################################################################
### ====================================================================== ###
##                                                                          ##
##  qrmexecd                                                                ##
##                                                                          ##
##  QRM-daemon for remote exection of QRM-commands                          ##
##                                                                          ##
##                                                                          ##
### ====================================================================== ###

# exit status of the QRM-script :
# 1 : unknown node
# 2 : could not update local config
# 3 : node not responding
# 4 : config file not found
# 5 : assignment locked
# 6 : error in usage
# 7 : kernel does not exists
# 8 : image does not exists

QRM_NODES_BASE_DIR=`pushd \`dirname $0\`/../../ 1>/dev/null && pwd && popd 1>/dev/null`
# include functions
. $QRM_NODES_BASE_DIR/qrm/include/qrm-functions
. $QRM_NODES_BASE_DIR/qrm/include/qrm-nodes-functions

# script passed parameters
eval $@
node_id=$id

# validation
if [ -z "$q_peer" ]; then
	qerror "Required configuration parameter missing : q_peer"
	exit 6
fi


# trap exit for save halt
trap "qrm_save_halt" SIGKILL
trap "qrm_save_halt" EXIT


# local used functions
function q_verify_exec_peer() {
	if [ "$QIPADDRESS" == "$q_peer" ]; then
		return 0
	else
		qerror "Command from in-valid peer-address $QIPADDRESS received"
		return 1
	fi
}

# killing qrminfod for various reasons
function runKill() {

        local sig=$1

        proc_id=($(proc_lookup))
        while [ "${proc_id}" ]; do
                qdebug "`date`: send kill ${sig} to qrm-infod. pid ${proc_id}, node_id $q_node_id, node_ip ${q_node_ip}" 
                kill $sig ${proc_id}
                sleep 1
                proc_id=($(proc_lookup))
        done

}

function sendSignal() {

        local sig=$1

        proc_id=($(proc_lookup))
        qdebug "`date`: send kill ${sig} to qrm-infod. pid ${proc_id}, node_id $q_node_id, node_ip ${q_node_ip}" 
        kill $sig ${proc_id}
        sleep 1
}

function proc_lookup(){

	ps ax --format pid,cmd | awk '$0 ~ "qrm-infod" && $0 !~ "awk" {print $1}'

        return $?
}

function q_run_command() {
	case "$QRMACTION" in
		'reboot')
			qinfo "Performing reboot operation on node $q_node_id"
			if [ "$q_command_reboot" != "" ]; then
				$q_command_reboot
			else
				/sbin/reboot
			fi
		;;
		'forcereboot')
			if [ "$q_command_forcereboot" != "" ]; then
				$q_command_forcereboot
			else
				/sbin/reboot -f
			fi
		;;
		'shutdown')
			qinfo "Performing shutdown operation on node $q_node_id"
			if [ "$q_command_shutdown" != "" ]; then
				$q_command_shutdown
			else
				/sbin/halt
			fi
		;;
		'send_stats')
			qinfo "Performing send stat operation on node $q_node_id"
			if [ "$q_command_send_stats" != "" ]; then
				$q_command_send_stats
			else
				sendSignal -10
			fi
		;;
		'update_qrminfod')		              
            		qinfo "Performing update_qrminfod operation on node $q_node_id"
	                runKill -9
        	        get_nodes_parameter
                	q_qrm_environment_load
        	        $QRM_NODES_BASE_DIR/qrm/sbin/qrm-infod id=$CS_ID &
                        qdebug "qrminfod restarted for node id=$CS_ID"
        	;;
		'qrm_xha-collect-states')
			qinfo "Performing qrm_xha-collect-states operation on node $q_node_id"
			ACTION_OUTPUT=`$QRM_NODES_BASE_DIR/bin/internal/$QRMACTION 2>&1`
			qdebug "$ACTION_OUTPUT"
		;;
		'qrm_xha-action')
			qinfo "Performing qrm_xha-action operation on node $q_node_id"
			TEMP=($QRMCOMMAND)
			ARG=${TEMP[1]}
			if ! echo $ARG | grep -E -x '[0-9a-zA-Z_-]+' > /dev/null; then
				qdebug "$QRMCOMMAND contains illegal characters in argument"
				return 1
			fi
			$QRM_NODES_BASE_DIR/bin/internal/$QRMACTION $ARG 1>>$q_logfile 2>>$q_logfile
		;;
		'vmware')
			ARGS=($QRMCOMMAND)
			set -- ${ARGS[*]}
			shift
			$QRM_NODES_BASE_DIR/qrm/plugins/vmware/bin/qrm-vmware-manage "$@"
			qdebug "$QRM_NODES_BASE_DIR/qrm/plugins/vmware/bin/qrm-vmware-manage $@"
		;;
		*)
			qdebug "Invalid command $QRMCOMMAND received from $QIPADDRESS"
		;;
 	esac
}


# main loop
qinfo "qrmexecd started for node $q_node_id"
while read QRMLISTEN; do
	if [ ! -z "$QRMLISTEN" ]; then
		QIPADDRESS=`echo $QRMLISTEN | cut -d':' -f 1 2>/dev/null`
		QRMCOMMAND=`echo $QRMLISTEN | cut -d':' -f 2- 2>/dev/null`
		TEMP=($QRMCOMMAND)
		QRMACTION=${TEMP[0]}
		if [ ! -z "$QIPADDRESS" ] || [ ! -z "$QRMCOMMAND" ]; then
			if q_verify_exec_peer; then 
				q_run_command
			fi
		fi
	fi
done
# never reached
qerror "qrmexecd exits abnormally"


