diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:52:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 07:52:36 +0000 |
commit | 7de03e4e519705301265c0415b3c0af85263a7ac (patch) | |
tree | 29d819c5227e3619d18a67d2a5dde963b3229dbe /heartbeat/WAS | |
parent | Initial commit. (diff) | |
download | resource-agents-7de03e4e519705301265c0415b3c0af85263a7ac.tar.xz resource-agents-7de03e4e519705301265c0415b3c0af85263a7ac.zip |
Adding upstream version 1:4.13.0.upstream/1%4.13.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'heartbeat/WAS')
-rwxr-xr-x | heartbeat/WAS | 572 |
1 files changed, 572 insertions, 0 deletions
diff --git a/heartbeat/WAS b/heartbeat/WAS new file mode 100755 index 0000000..15b56e9 --- /dev/null +++ b/heartbeat/WAS @@ -0,0 +1,572 @@ +#!/bin/sh +# +# +# WAS +# +# Description: Manages a Websphere Application Server as an HA resource +# +# +# Author: Alan Robertson +# Support: users@clusterlabs.org +# License: GNU General Public License (GPL) +# Copyright: (C) 2002 - 2005 International Business Machines, Inc. +# +# +# An example usage in /etc/ha.d/haresources: +# node1 10.0.0.170 WAS::/opt/WebSphere/ApplicationServer/config/server-cfg.xml +# +# See usage() function below for more details... +# +# OCF parameters are as below: +# OCF_RESKEY_config +# (WAS-configuration file, used for the single server edition of WAS) +# OCF_RESKEY_port +# (WAS-<snoop>-port-number, used for the advanced edition of WAS) + +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +WASDIR=/opt/WebSphere/AppServer +if + [ ! -d $WASDIR ] +then + WASDIR=/usr/WebSphere/AppServer +fi +STARTTIME=300 # 5 minutes +DEFAULT_WASPORTS="9080" +# +# +WASBIN=$WASDIR/bin +DEFAULT=$WASDIR/config/server-cfg.xml + +# +# Print usage message +# +usage() { + methods=`WAS_methods | grep -v methods` + methods=`echo $methods | tr ' ' '|'` + cat <<-END + usage: $0 ($methods) + + For the single server edition of WAS, you have to set the following + enviroment virable: + OCF_RESKEY_config + (WAS-configuration file) + + For the advanced edition of WAS, you have to set the following + enviroment virable: + OCF_RESKEY_port + (WAS-<snoop>-port-number) + + $0 manages a Websphere Application Server (WAS) as an HA resource + + The 'start' operation starts WAS. + The 'stop' operation stops WAS. + The 'status' operation reports whether WAS is running + The 'monitor' operation reports whether the WAS seems to be working + (httpd also needs to be working for this case) + The 'validate-all' operation reports whether the OCF instance parameter (OCF_RESKEY_config or OCF_RESKEY_port) is valid + The 'methods' operation reports on the methods $0 supports + + This is known to work with the Single Server edition of Websphere, + and is believed to work with the Advanced edition too. + Since the Advanced Edition has no configuration file (it's in a the + database) you need to give a port number instead of a + configuration file for this config parameter. + + The default configuration file for the single server edition is: + $DEFAULT + + The default snoop-port for the advanced edition is: $DEFAULT_WASPORTS + + The start and stop operations must be run as root. + + The status operation will report a pid of "-" for the + WAS root process using unless it is run as root. + + If you don't have xmllint on your system, parsing of WAS + configuration files is very primitive. + In this case, the port specification we need from the XML + config file has to be on the same line as the + first part of the <transports/> tag. + + We run servlet/snoop on the first transport port listed in + the config file for the "monitor" operation. + + END +} + +meta_data() { + cat <<END +<?xml version="1.0"?> +<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> +<resource-agent name="WAS" version="1.0"> +<version>1.0</version> + +<longdesc lang="en"> +Resource script for WAS. It manages a Websphere Application Server (WAS) as +an HA resource. +</longdesc> +<shortdesc lang="en">Manages a WebSphere Application Server instance</shortdesc> + +<parameters> +<parameter name="config" unique="0" required="0"> +<longdesc lang="en"> +The WAS-configuration file. +</longdesc> +<shortdesc lang="en">configration file</shortdesc> +<content type="string" default="$DEFAULT" /> +</parameter> + +<parameter name="port" unique="0"> +<longdesc lang="en"> +The WAS-(snoop)-port-number. +</longdesc> +<shortdesc lang="en">port</shortdesc> +<content type="integer" default="$DEFAULT_WASPORTS" /> +</parameter> +</parameters> + +<actions> +<action name="start" timeout="300s" /> +<action name="stop" timeout="300s" /> +<action name="status" depth="0" timeout="30s" interval="10s" /> +<action name="monitor" depth="0" timeout="30s" interval="10s" /> +<action name="validate-all" timeout="5s" /> +<action name="meta-data" timeout="5s" /> +<action name="methods" timeout="5s" /> +</actions> +</resource-agent> +END +} + +# +# Reformat the XML document in a sort of canonical form +# if we can. If we don't have xmllint, we just cat it out +# and hope for the best ;-) +# +xmlcat() { + if + [ "X$XMLcat" = X ] + then + XMLcat=`which xmllint 2>/dev/null` + if + [ "X${XMLcat}" = X -o ! -x "${XMLcat}" ] + then + XMLcat=cat + else + XMLcat="$XMLcat --recover --format" + fi + fi + for j in "$@" + do + ${XMLcat} "$j" + done +} + +# +#This is a bit skanky, but it works anyway... +# +#<transports xmi:type="applicationserver:HTTPTransport" xmi:id="HttpTransport_1" hostname="*" port="9080"/> +#<transports xmi:type="applicationserver:HTTPTransport" xmi:id="HttpTransport_2" hostname="*" port="9443" sslEnabled="true"/> +#<transports xmi:type="applicationserver:HTTPTransport" xmi:id="HttpTransport_3" hostname="*" port="9090" external="false"/> +# +# It's not really skanky if we can find xmllint on the system, because it +# reformats tags so they are all on one line, which is all we we need... +# + +# +# Get the numbers of the ports WAS should be listening on... +# +# If we don't have xmllint around, then the applicationserver and the +# port= specification have to be on the same line in the XML config file. +# +GetWASPorts() { + case $1 in + [0-9]*) echo "$1" | tr ',' '\012';; + *) + xmlcat $1 | grep -i 'transports.*applicationserver:HTTPTransport' | + grep port= | + sed -e 's%.*port= *"* *%%' \ + -e 's%[^0-9][^0-9]*.*$%%' + # Delete up to port=, throw away optional quote and optional + # white space. + # Throw away everything after the first non-digit. + # This should leave us the port number all by itself... + esac +} + +# +# We assume that the first port listed in the <transports/> +# is the one we should run servlet/snoop on. +# +GetWASSnoopPort() { + GetWASPorts "$@" | head -n1 +} + +# +# Return information on the processname/id for the WAS ports +# +# pid/java is the expected output. Several lines, one per port... +# +# +WASPortInfo() { + pat="" + once=yes + PortCount=0 + for j in $* + do + case $pat in + "") pat="$j";; + *) pat="$pat|$j";; + esac + PortCount=`expr $PortCount + 1` + done + netstat -ltnp 2>/dev/null| egrep -i "($pat) .*LISTEN" | sed 's%.*LISTEN *%%' +} + +# +# Return the number of WAS ports which are open +# +CheckWASPortsInUse() { + count=`WASPortInfo "$@" | wc -l` + echo $count +} + +# +# Return the pid(s) of the processes that have WAS ports open +# +WASPIDs() { + WASPortInfo "$@" | sort -u | cut -f1 -d/ +} + +# +# The version of ps that returns all processes and their (long) args +# It's only used by WAS_procs, which isn't used for anything ;-) +# +ps_long() { + ps axww +} + + +# +# The total set of WAS processes (single server only) +# +WAS_procs() { + ps_long | grep -i "config=$1" | grep -i java | cut -d' ' -f1 +} + + + +# +# methods: What methods/operations do we support? +# +WAS_methods() { + cat <<-! + start + stop + status + methods + validate-all + meta-data + usage + ! + if + have_binary $WGET + then + echo monitor + fi +} + +# +# Return WAS status (silently) +# +WAS_status() { + WASPorts=`GetWASPorts $1` + PortsInUse=`CheckWASPortsInUse $WASPorts` + case $PortsInUse in + 0) false;; + *) true;; + esac +} + +# +# Report on WAS status to stdout... +# +WAS_report_status() { + WASPorts=`GetWASPorts $1` + PortCount=`echo $WASPorts | wc -w` + PortCount=`echo $PortCount` + PortsInUse=`CheckWASPortsInUse $WASPorts` + case $PortsInUse in + 0) ocf_log debug "WAS: server $1 is stopped."; return $OCF_NOT_RUNNING;; + *) + pids=`WASPIDs $WASPorts` + if + [ $PortsInUse -ge $PortCount ] + then + ocf_log debug "WAS: server $1 is running (pid" $pids "et al)." + else + ocf_log debug "WAS: server $1 is running (pid $pids et al) but not listening on all ports." + fi + return $OCF_SUCCESS;; + esac +} + +# +# Monitor WAS - does it really seem to be working? +# +# For this we invoke the snoop applet via wget. +# +# This is actually faster than WAS_status above... +# +WAS_monitor() { + trap '[ -z "$tmpfile" ] || rmtempfile "$tmpfile"' 0 + tmpfile=`maketempfile` || return 1 + SnoopPort=`GetWASSnoopPort $1` + output=`$WGET -nv -O$tmpfile http://localhost:$SnoopPort/servlet/snoop 2>&1` + rc=$? + if + [ $rc -eq 0 ] + then + if + grep -i 'user-agent.*Wget' $tmpfile >/dev/null + then + : OK + else + ocf_log "err" "WAS: $1: no user-agent from snoop application" + rc=$OCF_ERR_GENERIC + fi + else + ocf_log "err" "WAS: $1: wget failure: $output" + rc=$OCF_ERR_GENERIC + fi + return $rc +} + +# +# Start WAS instance +# +WAS_start() { +# Launch Arguments: +# +# -configFile <configFile> +# -nodeName <nodeName> +# -serverName <serverName> +# -oltEnabled +# -oltHost <hostname> +# -oltPort <port> +# -debugEnabled +# -jdwpPort <port> +# -debugSource <sourcePath> +# -serverTrace <traceString> +# -serverTraceFile <traceFile> +# -script [<scriptFile>] +# -platform <platformName> +# -noExecute +# -help + if + [ -x $WASBIN/startServer.sh ] + then + cmd="$WASBIN/startServer.sh -configFile $1" + else + cmd="$WASBIN/startupServer.sh" + fi + + if + ocf_run $cmd + then + if + WAS_wait_4_start $STARTTIME "$@" + then + #true + return $OCF_SUCCESS + else + ocf_log "err" "WAS server $1 did not start correctly" + return $OCF_ERR_GENERIC + fi + else + #false + return $OCF_ERR_GENERIC + fi +} + +# +# Wait for WAS to actually start up. +# +# It seems to take between 30 and 60 seconds for it to +# start up on a trivial WAS instance. +# +WAS_wait_4_start() { + max=$1 + retries=0 + shift + while + [ $retries -lt $max ] + do + if + WAS_status "$@" + then + return $OCF_SUCCESS + else + sleep 1 + fi + retries=`expr $retries + 1` + done + WAS_status "$@" +} + + +# +# Shut down WAS +# +WAS_stop() { + # They don't return good return codes... + # And, they seem to allow anyone to stop WAS (!) + if + [ -x $WASBIN/stopServer.sh ] + then + ocf_run $WASBIN/stopServer.sh -configFile $1 + else + WASPorts=`GetWASPorts $1` + kill `WASPIDs $WASPorts` + fi + if + WAS_status $1 + then + ocf_log "err" "WAS: $1 did not stop correctly" + #false + return $OCF_ERR_GENERIC + else + #true + return $OCF_SUCCESS + fi +} + +# +# Check if the port is valid +# +CheckPort() { + ocf_is_decimal "$1" && [ $1 -gt 0 ] +} + +WAS_validate_all() { + if [ -x $WASBIN/startServer.sh ]; then + # $arg should be config file + if [ ! -f "$arg" ]; then + ocf_log err "Configuration file [$arg] does not exist" + exit $OCF_ERR_ARGS + fi + + # $arg should specify a valid port number at the very least + local WASPorts=`GetWASPorts $arg` + if [ -z "$WASPorts" ]; then + ocf_log err "No port number specified in configuration file [$arg]" + exit $OCF_ERR_CONFIGURED + fi + + local port + local have_valid_port=false + for port in $WASPorts; do + if CheckPort $port; then + have_valid_port=true + break + fi + done + if [ "false" = "$have_valid_port" ]; then + ocf_log err "No valid port number specified in configuration file [$arg]" + exit $OCF_ERR_CONFIGURED + fi + + elif [ -x $WASBIN/startupServer.sh ]; then + # $arg should be port number + if CheckPort "$arg"; then + ocf_log err "Port number is required but [$arg] is not valid port number" + exit $OCF_ERR_ARGS + fi + else + # Do not know hot to validate_all + ocf_log warn "Do not know how to validate-all, assuming validation OK" + return $OCF_SUCCESS + fi +} +# +# 'main' starts here... +# + +if + ( [ $# -ne 1 ] ) +then + usage + exit $OCF_ERR_ARGS +fi + +# +# Supply default configuration parameter(s) +# + +if + ( [ -z $OCF_RESKEY_config ] && [ -z $OCF_RESKEY_port ] ) +then + if + [ -f $DEFAULT ] + then + arg=$DEFAULT + else + arg=$DEFAULT_WASPORTS + fi +elif + [ ! -z $OCF_RESKEY_config ] +then + arg=$OCF_RESKEY_config +else + arg=$OCF_RESKEY_port +fi + +if + [ ! -f $arg ] +then + case $arg in + [0-9]*) ;; # ignore port numbers... + *) ocf_log "err" "WAS configuration file $arg does not exist!" + usage + exit $OCF_ERR_ARGS;; + esac +fi + + +# What kind of method was invoked? +case "$1" in + + meta-data) meta_data + exit $OCF_SUCCESS;; + + start) WAS_start $arg + exit $?;; + + stop) WAS_stop $arg + exit $?;; + + status) WAS_report_status $arg + exit $?;; + + monitor) WAS_monitor $arg + exit $?;; + + validate-all) WAS_validate_all $arg + exit $?;; + + methods) WAS_methods + exit $?;; + + usage) usage + exit $OCF_SUCCESS;; + + *) usage + exit $OCF_ERR_UNIMPLEMENTED;; +esac |