#!/bin/bash
#
# External STONITH module for Egenera pServers.
#
# Copyright (c) 2004 SUSE LINUX AG - Lars Marowsky-Bree <lmb@suse.de>
# Copyright (c) 2009 Karl W. Lewis <karl.w.lewis - AT - gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like.  Any license provided herein, whether implied or
# otherwise, applies only to this software file.  Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
#

SSH_COMMAND="/usr/bin/ssh -q -x -n -l root"
GET_MASTER="/root/bin/get_master.sh"
GET_STATUS="/root/bin/get_status.sh"
PSERVER_COMMAND="/opt/panmgr/bin/esh pserver"

#These TIMEOUT values were obtained from the 'pserver -l pan/pserver' command
# on a given Egenera frame under "Timeouts"  YMMV.

BOOT_TIMEOUT=270
REBOOT_TIMEOUT=450
SHUTDOWN_TIMEOUT=180

TIMEOUT=${REBOOT_TIMEOUT}
STATUS="UNKNOWN"

#LOG=/var/log/egenera-stonith.log
#echo `date` >> ${LOG}
#echo ${hostlist} >> ${LOG}
#echo ${lpan_name} >> ${LOG}
#echo $1 >> ${LOG}
#echo $2 >> ${LOG}
#echo "executing--------------" >> ${LOG}

# Rewrite the hostlist to accept "," as a delimeter for hostnames too.
hostlist=`echo ${hostlist} | tr ',' ' '`

is_host_up() {
    TIME=$((${TIMEOUT}/5))
    for j in 1 2 3 4 5 6
    do
        STATUS=`${SSH_COMMAND} ${MASTER_BLADE} "${GET_STATUS} ${h} ${lpan_name} UP"`
        if [ "${STATUS}" = "Down" ]
        then
            sleep ${TIME}
        else
            SYSTEM_STATUS="On Target"
            return 1
        fi
    done
    return 0
}

is_host_down() {
    TIME=$((${TIMEOUT}/5))
    for j in 1 2 3 4 5 6
    do
        STATUS=`${SSH_COMMAND} ${MASTER_BLADE} "${GET_STATUS} ${h} ${lpan_name} DOWN"`
        if [ "${STATUS}" = "Up" ]
        then
            sleep ${TIME}
        else
            SYSTEM_STATUS="On Target"
            return 1
        fi
    done
    return 0
}

MASTER_BLADE=`${SSH_COMMAND} cblade-1 "${GET_MASTER}" | tail -1`

if [ -z "${MASTER_BLADE}" ]
then
    MASTER_BLADE=`${SSH_COMMAND} cblade-2 "${GET_MASTER}" | tail -1`
fi

case ${1} in
gethosts)
    for h in ${hostlist}
    do
        echo ${h}
    done
    exit 0
    ;;
on|off|reboot)
    for h in ${hostlist}
    do
        if [ "${h}" != "${2}" ]
        then
            continue
        else
            if [ "${1}" = "on" ]
            then
                CMD="--boot"
            elif [ "${1}" = "off" ]
            then
                CMD="--shutdown --force"
            else #must be "reboot"
                CMD="--reboot --force"
            fi
            ${SSH_COMMAND} ${MASTER_BLADE} "${PSERVER_COMMAND} ${CMD} ${lpan_name}/${h}"
            if [ "${1}" = "on" ]
            then
                TIMEOUT=${BOOT_TIMEOUT}
            elif [ "${1}" = "reboot" ]
            then
                TIMEOUT=${REBOOT_TIMEOUT}
            else
                TIMEOUT=${SHUTDOWN_TIMEOUT}
            fi
            if [ "${1}" = "off" ]
            then
                is_host_down ${h}
            else
                is_host_up ${h}
            fi
        fi
        if [ "${SYSTEM_STATUS}" = "On Target" ]
        then
            exit 0
        else
            exit 1
        fi
    done
    exit 1 # We got here only if the host was not in the list....
    ;;
status)
    if [ -z "${hostlist}" ] || [ -z "${lpan_name}" ] || [ -z "${MASTER_BLADE}" ] 
    then
        exit 1
    fi
    exit 0
    ;;
getconfignames)
    echo "hostlist lpan_name"
    exit 0
    ;;
getinfo-devid)
    echo "Egenera STONITH device"
    exit 0
    ;;
getinfo-devname)
    echo "Egenera STONITH external device"
    exit 0
    ;;
getinfo-devdescr)
    echo "Egenera-based Linux host reset"
    exit 0
    ;;
getinfo-devurl)
    echo "http://www.egenera.com"
    exit 0
    ;;
getinfo-xml)
    cat << EGENERAXML
<parameters>
<parameter name="hostlist" unique="1" required="1">
<content type="string" />
<shortdesc lang="en">
Hostlist
</shortdesc>
<longdesc lang="en">
The list of hosts that the STONITH device controls
</longdesc>
</parameter>
<parameter name="lpan_name" unique="1" required="1">
<content type="string" />
<shortdesc lang="en">
LPAN_Name
</shortdesc>
<longdesc lang="en">
The name of the LPAN that the cluster blades, that this STONITH device controls, live in
</longdesc>
</parameter>
</parameters>
EGENERAXML
    exit 0
    ;;
*)
    exit 1
    ;;
esac

