diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index 6bd18f248..b9c7ce8a7 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,249 +1,250 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README README.galera AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd metadata.rng ocf_PROGRAMS = if USE_IPV6ADDR_AGENT ocf_PROGRAMS += IPv6addr endif halib_PROGRAMS = if IPV6ADDR_COMPATIBLE halib_PROGRAMS += send_ua endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_SOURCES = send_ua.c IPv6addr_utils.c send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = AoEtarget \ AudibleAlarm \ ClusterMon \ CTDB \ Delay \ Dummy \ EvmsSCC \ Evmsd \ Filesystem \ ICP \ IPaddr \ IPaddr2 \ IPsrcaddr \ LVM \ LinuxSCSI \ lvmlockd \ LVM-activate \ MailTo \ ManageRAID \ ManageVE \ NodeUtilization \ Pure-FTPd \ Raid1 \ Route \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ VIPArip \ VirtualDomain \ WAS \ WAS6 \ + WAS8 \ WinPopup \ Xen \ Xinetd \ ZFS \ aliyun-vpc-move-ip \ anything \ apache \ asterisk \ aws-vpc-move-ip \ aws-vpc-route53 \ awseip \ awsvip \ azure-lb \ clvm \ conntrackd \ corosync-qnetd \ crypt \ db2 \ dhcpd \ dnsupdate \ dummypy \ docker \ docker-compose \ dovecot \ eDir88 \ ethmonitor \ exportfs \ fio \ galera \ garbd \ gcp-ilb \ gcp-vpc-move-ip \ iSCSILogicalUnit \ iSCSITarget \ ids \ iface-bridge \ iface-macvlan \ iface-vlan \ ipsec \ iscsi \ jboss \ jira \ kamailio \ lxc \ lxd-info \ machine-info \ mariadb \ mdraid \ minio \ mysql \ mysql-proxy \ nagios \ named \ nfsnotify \ nfsserver \ nginx \ nvmet-subsystem \ nvmet-namespace \ nvmet-port \ ocivip \ openstack-cinder-volume \ openstack-floating-ip \ openstack-info \ openstack-virtual-ip \ oraasm \ oracle \ oralsnr \ ovsmonitor \ pgagent \ pgsql \ pingd \ podman \ portblock \ postfix \ pound \ proftpd \ rabbitmq-cluster \ rabbitmq-server-ha \ redis \ rkt \ rsyncd \ rsyslog \ scsi2reservation \ sfex \ sg_persist \ mpathpersist \ slapd \ smb-share \ storage-mon \ sybaseASE \ symlink \ syslog-ng \ tomcat \ varnish \ vdo-vol \ vmware \ vsftpd \ zabbixserver if BUILD_AZURE_EVENTS ocf_SCRIPTS += azure-events endif if BUILD_AZURE_EVENTS_AZ ocf_SCRIPTS += azure-events-az endif if BUILD_GCP_PD_MOVE ocf_SCRIPTS += gcp-pd-move endif if BUILD_GCP_VPC_MOVE_ROUTE ocf_SCRIPTS += gcp-vpc-move-route endif if BUILD_GCP_VPC_MOVE_VIP ocf_SCRIPTS += gcp-vpc-move-vip endif ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ ocf-distro \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ lvm-clvm.sh \ lvm-plain.sh \ lvm-tag.sh \ openstack-common.sh \ ora-common.sh \ mysql-common.sh \ nfsserver-redhat.sh \ findif.sh \ ocf.py # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs check: $(ocf_SCRIPTS:=.check) %.check: % OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) ./$< meta-data | xmllint --path $(abs_srcdir) --noout --relaxng $(abs_srcdir)/metadata.rng - do_spellcheck = printf '[%s]\n' "$(agent)"; \ OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) \ ./$(agent) meta-data 2>/dev/null \ | xsltproc $(top_srcdir)/make/extract_text.xsl - \ | aspell pipe list -d en_US --ignore-case \ --home-dir=$(top_srcdir)/make -p spellcheck-ignore \ | sed -n 's|^&\([^:]*\):.*|\1|p'; spellcheck: @$(foreach agent,$(ocf_SCRIPTS), $(do_spellcheck)) clean-local: rm -rf __pycache__ *.pyc diff --git a/heartbeat/WAS8 b/heartbeat/WAS8 new file mode 100644 index 000000000..67804f741 --- /dev/null +++ b/heartbeat/WAS8 @@ -0,0 +1,615 @@ +#!/bin/sh +# +# +# WAS +# +# Description: Manages a Websphere Application Server as an HA resource +# +# +# Author: Bi Zhi Yuan +# Support: users@clusterlabs.org +# License: GNU General Public License (GPL) +# Copyright: (C) 2006 International Business Machines China, Ltd., 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 WAS8) +# OCF_RESKEY_port +# (WAS--port-number, used for the advanced edition of WAS8) +# OCF_RESKEY_server_name +# (WAS server name, used for the advanced edition of WAS8) +# OCF_RESKEY_profile_name +# (WAS profile name, used for the single server edition of WAS8) + +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +####################################################################### + +WASDIR=/opt/IBM/WebSphere/AppServer +if + [ ! -d $WASDIR ] +then + WASDIR=/usr/WebSphere/AppServer +fi +STARTTIME=300 # 5 minutes +DEFAULT_WASPORTS="9080" +DEFAULT_WAS_SERVER_NAME="server1" +DEFAULT_WAS_PROFILE_NAME="AppSrv01" +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--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 tag. + + We run servlet/snoop on the first transport port listed in + the config file for the "monitor" operation. + + END +} + +meta_data() { + cat < + + +1.0 + + +Resource script for WAS. It manages a Websphere Application Server (WAS) as +an HA resource. + +Manages a WebSphere Application Server instance + + + + +The WAS-configuration file. + +configration file + + + + + +The WAS-(snoop)-port-number. + +port + + + + + +The WAS server-name. + +serverName + + + + + +The WAS profile-name. + +profileName + + + + + + + + + + + + + + + +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... +# +# 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 ${WASDIR}/profiles/${WAS_PROFILE_NAME}/config/cells/${WAS_CELL}/nodes/${WAS_NODE}/serverindex.xml | + 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 +# is the one we should run servlet/snoop on. +# +GetWASSnoopPort() { + GetWASPorts "$@" | sed -n '8p' +} + +# +# 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:9080/snoop 2>&1` + rc=$? + if + [ $rc -eq 0 ] + then + ocf_log "info" "WAS monitor succeeded" + return $OCF_SUCCESS + else + ocf_log "err" "WAS: $1: wget failure: $output" + rc=$OCF_NOT_RUNNING + fi + + return $rc +} + +# +# Start WAS instance +# +WAS_start() { +# Launch Arguments: +# +# -nowait +# -quiet +# -logfile +# -replacelog +# -trace +# -script [