| #!/bin/bash | |
| # | |
| # | |
| # ClusterMon OCF RA. | |
| # Starts crm_mon in background which logs cluster status as | |
| # html to the specified file. | |
| # | |
| # Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Brée | |
| # All Rights Reserved. | |
| # | |
| # 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. | |
| # | |
| # OCF instance parameters: | |
| # OCF_RESKEY_user | |
| # OCF_RESKEY_pidfile | |
| # OCF_RESKEY_update | |
| # OCF_RESKEY_extra_options | |
| # OCF_RESKEY_htmlfile | |
| ####################################################################### | |
| # Initialization: | |
| : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} | |
| . ${OCF_FUNCTIONS} | |
| : ${__OCF_ACTION=$1} | |
| ####################################################################### | |
| meta_data() { | |
| cat <<END | |
| <?xml version="1.0"?> | |
| <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> | |
| <resource-agent name="ClusterMon" version="1.0"> | |
| <version>1.0</version> | |
| <longdesc lang="en"> | |
| This is a ClusterMon Resource Agent. | |
| It outputs current cluster status to the html. | |
| </longdesc> | |
| <shortdesc lang="en">Runs crm_mon in the background, recording the cluster status to an HTML file</shortdesc> | |
| <parameters> | |
| <parameter name="user" unique="0"> | |
| <longdesc lang="en"> | |
| The user we want to run crm_mon as | |
| </longdesc> | |
| <shortdesc lang="en">The user we want to run crm_mon as</shortdesc> | |
| <content type="string" default="root" /> | |
| </parameter> | |
| <parameter name="update" unique="0"> | |
| <longdesc lang="en"> | |
| How frequently should we update the cluster status (in milliseconds). | |
| For compatibility with old documentation, values less than 1000 will be treated | |
| as seconds. | |
| </longdesc> | |
| <shortdesc lang="en">Update interval in milliseconds</shortdesc> | |
| <content type="integer" default="15000" /> | |
| </parameter> | |
| <parameter name="extra_options" unique="0"> | |
| <longdesc lang="en"> | |
| Additional options to pass to crm_mon. Eg. -n -r | |
| </longdesc> | |
| <shortdesc lang="en">Extra options</shortdesc> | |
| <content type="string" default="" /> | |
| </parameter> | |
| <parameter name="pidfile" unique="1"> | |
| <longdesc lang="en"> | |
| PID file location to ensure only one instance is running | |
| </longdesc> | |
| <shortdesc lang="en">PID file</shortdesc> | |
| <content type="string" default="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.pid" /> | |
| </parameter> | |
| <parameter name="htmlfile" unique="1" required="0"> | |
| <longdesc lang="en"> | |
| Location to write HTML output to. | |
| </longdesc> | |
| <shortdesc lang="en">HTML output</shortdesc> | |
| <content type="string" default="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.html" /> | |
| </parameter> | |
| </parameters> | |
| <actions> | |
| <action name="start" timeout="20" /> | |
| <action name="stop" timeout="20" /> | |
| <action name="monitor" depth="0" timeout="20" interval="10" /> | |
| <action name="meta-data" timeout="5" /> | |
| <action name="validate-all" timeout="30" /> | |
| </actions> | |
| </resource-agent> | |
| END | |
| } | |
| ####################################################################### | |
| ClusterMon_usage() { | |
| cat <<END | |
| usage: $0 {start|stop|monitor|validate-all|meta-data} | |
| Expects to have a fully populated OCF RA-compliant environment set. | |
| END | |
| } | |
| ClusterMon_exit() { | |
| if [ $1 != 0 ]; then | |
| exit $OCF_ERR_GENERIC | |
| else | |
| exit $OCF_SUCCESS | |
| fi | |
| } | |
| ClusterMon_start() { | |
| cmd_prefix="" | |
| cmd_suffix="" | |
| if [ ! -z $OCF_RESKEY_user ]; then | |
| su - $OCF_RESKEY_user -c "$CMON_CMD" | |
| else | |
| $CMON_CMD | |
| fi | |
| ClusterMon_exit $? | |
| } | |
| ClusterMon_stop() { | |
| if [ -f $OCF_RESKEY_pidfile ]; then | |
| pid=`cat $OCF_RESKEY_pidfile` | |
| if [ ! -z $pid ]; then | |
| kill -s 9 $pid | |
| rm -f $OCF_RESKEY_pidfile | |
| fi | |
| fi | |
| ClusterMon_exit 0 | |
| } | |
| ClusterMon_monitor() { | |
| local USERARG="" | |
| local header | |
| local pid | |
| if [ -f $OCF_RESKEY_pidfile ]; then | |
| pid=`cat $OCF_RESKEY_pidfile` | |
| if [ ! -z $pid ]; then | |
| if [ -n "$OCF_RESKEY_user" ]; then | |
| USERARG="-u $OCF_RESKEY_user" | |
| fi | |
| # Use column header wide as command, to ensure it's shown in full | |
| header=$(echo $CMON_CMD | tr 'crmon, \t' 'xxxxxxxx') | |
| ps $USERARG -o "args=${header}" -p $pid 2>/dev/null | \ | |
| grep -qE "[c]rm_mon.*${OCF_RESKEY_pidfile}" | |
| case $? in | |
| 0) exit $OCF_SUCCESS;; | |
| 1) exit $OCF_NOT_RUNNING;; | |
| *) exit $OCF_ERR_GENERIC;; | |
| esac | |
| fi | |
| fi | |
| exit $OCF_NOT_RUNNING | |
| } | |
| CheckOptions() { | |
| while getopts Vi:nrh:cdp: OPTION | |
| do | |
| case $OPTION in | |
| V|n|r|c|d);; | |
| i) ocf_log warn "You should not have specified the -i option, since OCF_RESKEY_update is set already!";; | |
| h) ocf_log warn "You should not have specified the -h option, since OCF_RESKEY_htmlfile is set already!";; | |
| p) ocf_log warn "You should not have specified the -p option, since OCF_RESKEY_pidfile is set already!";; | |
| *) return $OCF_ERR_ARGS;; | |
| esac | |
| done | |
| if [ $? -ne 0 ]; then | |
| return $OCF_ERR_ARGS | |
| fi | |
| # We should have eaten all options at this stage | |
| shift $(($OPTIND -1)) | |
| if [ $# -gt 0 ]; then | |
| false | |
| else | |
| true | |
| fi | |
| } | |
| ClusterMon_validate() { | |
| # Existence of the user | |
| if [ ! -z $OCF_RESKEY_user ]; then | |
| getent passwd "$OCF_RESKEY_user" >/dev/null | |
| if [ $? -eq 0 ]; then | |
| : Yes, user exists. We can further check his permission on crm_mon if necessary | |
| else | |
| ocf_log err "The user $OCF_RESKEY_user does not exist!" | |
| exit $OCF_ERR_ARGS | |
| fi | |
| fi | |
| # Pidfile better be an absolute path | |
| case $OCF_RESKEY_pidfile in | |
| /*) ;; | |
| *) ocf_log warn "You should have pidfile($OCF_RESKEY_pidfile) of absolute path!" ;; | |
| esac | |
| # Check the update interval | |
| if ocf_is_decimal "$OCF_RESKEY_update" && [ $OCF_RESKEY_update -gt 0 ]; then | |
| : | |
| else | |
| ocf_log err "Invalid update interval $OCF_RESKEY_update. It should be positive integer!" | |
| exit $OCF_ERR_ARGS | |
| fi | |
| if CheckOptions $OCF_RESKEY_extra_options; then | |
| : | |
| else | |
| ocf_log err "Invalid options $OCF_RESKEY_extra_options!" | |
| exit $OCF_ERR_ARGS | |
| fi | |
| # Htmlfile better be an absolute path | |
| case $OCF_RESKEY_htmlfile in | |
| /*) ;; | |
| *) ocf_log warn "You should have htmlfile($OCF_RESKEY_htmlfile) of absolute path!" ;; | |
| esac | |
| echo "Validate OK" | |
| return $OCF_SUCCESS | |
| } | |
| if [ $# -ne 1 ]; then | |
| ClusterMon_usage | |
| exit $OCF_ERR_ARGS | |
| fi | |
| : ${OCF_RESKEY_update:="15000"} | |
| : ${OCF_RESKEY_pidfile:="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.pid"} | |
| : ${OCF_RESKEY_htmlfile:="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.html"} | |
| if [ ${OCF_RESKEY_update} -ge 1000 ]; then | |
| OCF_RESKEY_update=$(( $OCF_RESKEY_update / 1000 )) | |
| fi | |
| CMON_CMD="${HA_SBIN_DIR}/crm_mon -p $OCF_RESKEY_pidfile -d -i $OCF_RESKEY_update $OCF_RESKEY_extra_options -h $OCF_RESKEY_htmlfile" | |
| case $__OCF_ACTION in | |
| meta-data) meta_data | |
| exit $OCF_SUCCESS | |
| ;; | |
| start) ClusterMon_start | |
| ;; | |
| stop) ClusterMon_stop | |
| ;; | |
| monitor) ClusterMon_monitor | |
| ;; | |
| validate-all) ClusterMon_validate | |
| ;; | |
| usage|help) ClusterMon_usage | |
| exit $OCF_SUCCESS | |
| ;; | |
| *) ClusterMon_usage | |
| exit $OCF_ERR_UNIMPLEMENTED | |
| ;; | |
| esac | |
| exit $? |