summaryrefslogtreecommitdiffstats
path: root/heartbeat/anything
diff options
context:
space:
mode:
Diffstat (limited to 'heartbeat/anything')
-rwxr-xr-xheartbeat/anything344
1 files changed, 344 insertions, 0 deletions
diff --git a/heartbeat/anything b/heartbeat/anything
new file mode 100755
index 0000000..137a612
--- /dev/null
+++ b/heartbeat/anything
@@ -0,0 +1,344 @@
+#!/bin/sh
+#
+# OCF Resource Agent compliant resource script.
+#
+# Copyright (c) 2009 IN-telegence GmbH & Co. KG, Dominik Klein
+# 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_binfile
+# OCF_RESKEY_cmdline_options
+# OCF_RESKEY_workdir
+# OCF_RESKEY_pidfile
+# OCF_RESKEY_logfile
+# OCF_RESKEY_errlogfile
+# OCF_RESKEY_user
+# OCF_RESKEY_monitor_hook
+# OCF_RESKEY_stop_timeout
+#
+# This RA starts $binfile with $cmdline_options as $user in $workdir and writes a $pidfile from that.
+# If you want it to, it logs:
+# - stdout to $logfile, stderr to $errlogfile or
+# - stdout and stderr to $logfile
+# - or to will be captured by lrmd if these options are omitted.
+# Monitoring is done through $pidfile or your custom $monitor_hook script.
+# The RA expects the program to keep running "daemon-like" and
+# not just quit and exit. So this is NOT (yet - feel free to
+# enhance) a way to just run a single one-shot command which just
+# does something and then exits.
+
+# Initialization:
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+# Parameter defaults
+
+OCF_RESKEY_binfile_default=""
+OCF_RESKEY_workdir_default=""
+OCF_RESKEY_pidfile_default="${HA_VARRUN}/anything_${OCF_RESOURCE_INSTANCE}.pid"
+OCF_RESKEY_logfile_default="/dev/null"
+OCF_RESKEY_user_default="root"
+OCF_RESKEY_stop_timeout_default=""
+
+: ${OCF_RESKEY_binfile=${OCF_RESKEY_binfile_default}}
+: ${OCF_RESKEY_workdir=${OCF_RESKEY_workdir_default}}
+: ${OCF_RESKEY_pidfile=${OCF_RESKEY_pidfile_default}}
+: ${OCF_RESKEY_logfile=${OCF_RESKEY_logfile_default}}
+: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
+: ${OCF_RESKEY_stop_timeout=${OCF_RESKEY_stop_timeout_default}}
+
+getpid() {
+ grep -o '[0-9]*' $1
+}
+
+anything_status() {
+ if test -f "$pidfile"
+ then
+ if pid=`getpid $pidfile` && [ "$pid" ] && kill -s 0 $pid
+ then
+ return $OCF_SUCCESS
+ else
+ # pidfile w/o process means the process died
+ return $OCF_ERR_GENERIC
+ fi
+ else
+ return $OCF_NOT_RUNNING
+ fi
+}
+
+anything_start() {
+ if ! anything_status
+ then
+ #Make sure that PID Directory exists and is writable by proper user
+ piddir=`dirname $pidfile`
+ if ! su -s /bin/sh - $user -c "test -w $piddir"; then
+ #PID Directory is not writeable by user
+ ocf_log warn "Directory $piddir is not writable by $user, attempting to fix."
+ ocf_log info "Creating directory $piddir"
+ mkdir -p $piddir
+ ocf_log info "Changing permissions for $piddir for user $user"
+ chown $user: $piddir
+ else
+ ocf_log debug "Directory $piddir exists, and is writeable by $user. All fine"
+ fi
+ if [ -n "$logfile" -a -n "$errlogfile" ]
+ then
+ # We have logfile and errlogfile, so redirect STDOUT und STDERR to different files
+ cmd="su - $user -c \"cd $workdir; nohup $binfile $cmdline_options >> $logfile 2>> $errlogfile & \"'echo \$!' "
+ else
+ # We only have logfile so redirect STDOUT and STDERR to the same file
+ cmd="su - $user -c \"cd $workdir; nohup $binfile $cmdline_options >> $logfile 2>&1 & \"'echo \$!' "
+ fi
+ ocf_log debug "Starting $process: $cmd"
+ # Execute the command as created above
+ eval $cmd | tail -n 1 > $pidfile
+ if anything_status
+ then
+ ocf_log debug "$process: $cmd started successfully, calling monitor"
+ anything_monitor
+ myres=$?
+ return $myres
+ else
+ ocf_log err "$process: $cmd could not be started"
+ return $OCF_ERR_GENERIC
+ fi
+ else
+ # If already running, consider start successful
+ ocf_log debug "$process: $cmd is already running"
+ return $OCF_SUCCESS
+ fi
+}
+
+anything_stop() {
+ local rc=$OCF_SUCCESS
+
+ if [ -n "$OCF_RESKEY_stop_timeout" ]
+ then
+ stop_timeout=$OCF_RESKEY_stop_timeout
+ elif [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
+ # Allow 2/3 of the action timeout for the orderly shutdown
+ # (The origin unit is ms, hence the conversion)
+ stop_timeout=$((OCF_RESKEY_CRM_meta_timeout/1500))
+ else
+ stop_timeout=10
+ fi
+ if anything_status
+ then
+ pid=`getpid $pidfile`
+ kill $pid
+ i=0
+ while [ $i -lt $stop_timeout ]
+ do
+ if ! anything_status
+ then
+ rm -f $pidfile
+ return $OCF_SUCCESS
+ fi
+ sleep 1
+ i=$((i+1))
+ done
+ ocf_log warn "Stop with SIGTERM failed/timed out, now sending SIGKILL."
+ kill -s 9 $pid
+ while :
+ do
+ if ! anything_status
+ then
+ ocf_log warn "SIGKILL did the job."
+ rc=$OCF_SUCCESS
+ break
+ fi
+ ocf_log info "The job still hasn't stopped yet. Waiting..."
+ sleep 1
+ done
+ fi
+ rm -f $pidfile
+ return $rc
+}
+
+anything_monitor() {
+ anything_status
+ ret=$?
+ if [ $ret -eq $OCF_SUCCESS ]
+ then
+ if [ -n "$OCF_RESKEY_monitor_hook" ]; then
+ eval "$OCF_RESKEY_monitor_hook"
+ if [ $? -ne $OCF_SUCCESS ]; then
+ return ${OCF_ERR_GENERIC}
+ fi
+ return $OCF_SUCCESS
+ else
+ true
+ fi
+ else
+ return $ret
+ fi
+}
+
+# FIXME: Attributes special meaning to the resource id
+process="$OCF_RESOURCE_INSTANCE"
+binfile="$OCF_RESKEY_binfile"
+cmdline_options="$OCF_RESKEY_cmdline_options"
+workdir="$OCF_RESKEY_workdir"
+pidfile="$OCF_RESKEY_pidfile"
+[ -z "$pidfile" ] && pidfile=${HA_VARRUN}/anything_${process}.pid
+logfile="${OCF_RESKEY_logfile:-/dev/null}"
+errlogfile="$OCF_RESKEY_errlogfile"
+user="$OCF_RESKEY_user"
+[ -z "$user" ] && user=root
+
+anything_validate() {
+ if ! su - $user -c "test -x $binfile"
+ then
+ ocf_log err "binfile $binfile does not exist or is not executable by $user."
+ exit $OCF_ERR_INSTALLED
+ fi
+ if ! getent passwd $user >/dev/null 2>&1
+ then
+ ocf_log err "user $user does not exist."
+ exit $OCF_ERR_INSTALLED
+ fi
+ for logfilename in "$logfile" "$errlogfile"
+ do
+ if [ -n "$logfilename" ]; then
+ mkdir -p `dirname $logfilename` || {
+ ocf_log err "cannot create $(dirname $logfilename)"
+ exit $OCF_ERR_INSTALLED
+ }
+ fi
+ done
+ [ "x$workdir" != x -a ! -d "$workdir" ] && {
+ ocf_log err "working directory $workdir doesn't exist"
+ exit $OCF_ERR_INSTALLED
+ }
+ return $OCF_SUCCESS
+}
+
+anything_meta() {
+cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="anything" version="1.0">
+<version>1.0</version>
+<longdesc lang="en">
+This is a generic OCF RA to manage almost anything.
+</longdesc>
+<shortdesc lang="en">Manages an arbitrary service</shortdesc>
+
+<parameters>
+<parameter name="binfile" required="1" unique="0">
+<longdesc lang="en">
+The full name of the binary to be executed. This is expected to keep running with the same pid and not just do something and exit.
+</longdesc>
+<shortdesc lang="en">Full path name of the binary to be executed</shortdesc>
+<content type="string" default="${OCF_RESKEY_binfile_default}"/>
+</parameter>
+<parameter name="cmdline_options" required="0">
+<longdesc lang="en">
+Command line options to pass to the binary
+</longdesc>
+<shortdesc lang="en">Command line options</shortdesc>
+<content type="string" />
+</parameter>
+<parameter name="workdir" required="0" unique="0">
+<longdesc lang="en">
+The path from where the binfile will be executed.
+</longdesc>
+<shortdesc lang="en">Full path name of the work directory</shortdesc>
+<content type="string" default="${OCF_RESKEY_workdir_default}"/>
+</parameter>
+<parameter name="pidfile">
+<longdesc lang="en">
+File to read/write the PID from/to.
+</longdesc>
+<shortdesc lang="en">File to write STDOUT to</shortdesc>
+<content type="string" default="${OCF_RESKEY_pidfile_default}"/>
+</parameter>
+<parameter name="logfile" required="0">
+<longdesc lang="en">
+File to write STDOUT to
+</longdesc>
+<shortdesc lang="en">File to write STDOUT to</shortdesc>
+<content type="string" default="${OCF_RESKEY_logfile_default}" />
+</parameter>
+<parameter name="errlogfile" required="0">
+<longdesc lang="en">
+File to write STDERR to
+</longdesc>
+<shortdesc lang="en">File to write STDERR to</shortdesc>
+<content type="string" />
+</parameter>
+<parameter name="user" required="0">
+<longdesc lang="en">
+User to run the command as
+</longdesc>
+<shortdesc lang="en">User to run the command as</shortdesc>
+<content type="string" default="${OCF_RESKEY_user_default}"/>
+</parameter>
+<parameter name="monitor_hook">
+<longdesc lang="en">
+Command to run in monitor operation
+</longdesc>
+<shortdesc lang="en">Command to run in monitor operation</shortdesc>
+<content type="string"/>
+</parameter>
+<parameter name="stop_timeout">
+<longdesc lang="en">
+In the stop operation: Seconds to wait for kill -TERM to succeed
+before sending kill -SIGKILL. Defaults to 2/3 of the stop operation timeout.
+</longdesc>
+<shortdesc lang="en">Seconds to wait after having sent SIGTERM before sending SIGKILL in stop operation</shortdesc>
+<content type="string" default="${OCF_RESKEY_stop_timeout_default}"/>
+</parameter>
+</parameters>
+<actions>
+<action name="start" timeout="20s" />
+<action name="stop" timeout="20s" />
+<action name="monitor" depth="0" timeout="20s" interval="10s" />
+<action name="meta-data" timeout="5s" />
+<action name="validate-all" timeout="5s" />
+</actions>
+</resource-agent>
+END
+exit 0
+}
+
+case "$1" in
+ meta-data|metadata|meta_data)
+ anything_meta
+ ;;
+ start)
+ anything_start
+ ;;
+ stop)
+ anything_stop
+ ;;
+ monitor)
+ anything_monitor
+ ;;
+ validate-all)
+ anything_validate
+ ;;
+ *)
+ ocf_log err "$0 was called with unsupported arguments: $*"
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac