Hi
I wrote an RA, which can start virtually anything in a very basic meaning.
You can configure
* binfile
* cmdline_options
* logfile
* errlogfile
* user
Names should be self-explaining I guess.
The RA starts the command configured with $binfile and $cmdline_options
as $user and redirects stdout and stderr to appropriate files.
It stops the command with kill. If kill does not work, it uses kill -9.
Monitors are done with ps. No deep check here but a pointer where to
implement that if needed.
If this is considered useful and you would like to include it into the
project - please do. I'd like to contribute it under the GPL.
This was written on Linux and as I lack experience with other *nixes,
there may be places to improve for other operating systems.
Let me know what you think and/or send patches if you want to improve
the RA.
Regards
Dominik
known limitations so far:
It can not handle programs that display a different name in ps than you
entered on the command line. For example, proftpd is started with
something like "$binfile -c $configfile" but ps shows "proftpd
(accepting connections)".
#!/bin/bash
#
# OCF Resource Agent compliant resource script.
#
# Copyright (c) 2008 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_logfile
# OCF_RESKEY_errlogfile
# OCF_RESKEY_user
# Initialization:
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
anything_status() {
[ -n "$cmdline_options" ] && cmd="$binfile $cmdline_options" ||
cmd="$binfile"
if pgrep -u $user -f "$cmd" > /dev/null 2>&1
then
return $OCF_RUNNING
else
return $OCF_NOT_RUNNING
fi
}
anything_start() {
if ! anything_status
then
if [ -n "$logfile" -a -n "$errlogfile" ]
then
# We have logfile and errlogfile, so redirect STDOUT
und STDERR to different files
cmd="su - $user -c \"nohup $binfile $cmdline_options >>
$logfile 2>> $errlogfile &\""
else if [ -n "$logfile" ]
then
# We only have logfile so redirect STDOUT and
STDERR to the same file
cmd="su - $user -c \"nohup $binfile
$cmdline_options >> $logfile 2>&1 &\""
else
# We have neither logfile nor errlogfile, so
redirect STDOUT and STDERR to a generic logfile
cmd="su - $user -c \"nohup $binfile
$cmdline_options >> /var/log/$(basename $binfile)\_$(date +%Y.%m.%d) 2>&1 &\""
fi
fi
ocf_log debug "Starting $process: $cmd"
# Execute the command as created above
eval $cmd
if anything_status
then
ocf_log debug "$process: $cmd started successfully"
return $OCF_SUCCESS
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() {
if anything_status
then
tries=5
i=0
while [ $i -lt $tries ]
do
# there may be programs without command line options
[ -n "$cmdline_options" ] && cmd="$binfile
$cmdline_options" || cmd="$binfile"
pkill -u $user -f "$cmd"
sleep 1
if ! anything_status
then
return $OCF_SUCCESS
fi
let "i++"
done
# one last attempt with sigkill
ocf_log warn "Stop $process: Looks like $process could not be
stopped by SIGTERM, now sending SIGKILL"
ocf_log warn "$(pgrep -u $user -f \"$cmd\" -l)"
pkill -u $user -9 -f "$cmd"
if ! anything_status
then
ocf_log debug "Stop $process: Seems like SIGKILL did
the job"
ocf_log debug "$(pgrep -u $user -f \"$cmd\" -l)"
return $OCF_SUCCESS
else
ocf_log err "Stop $process: failed"
return $OCF_ERR_GENERIC
fi
else
# was not running, so stop can be considered successful
return $OCF_SUCCESS
fi
return $OCF_ERR_GENERIC
}
anything_monitor() {
anything_status
ret=$?
if [ $ret -eq $OCF_SUCCESS ]
then
# implement your deeper monitor operation here
return $OCF_SUCCESS
else
return $ret
fi
}
binfile="$OCF_RESKEY_binfile"
cmdline_options="$OCF_RESKEY_cmdline_options"
logfile="$OCF_RESKEY_logfile"
errlogfile="$OCF_RESKEY_errlogfile"
process="$OCF_RESOURCE_INSTANCE"
user="$OCF_RESKEY_user"
[ -z "$user" ] && user=root
#ocf_log debug "binfile $binfile"
#ocf_log debug "cmdline_options $cmdline_options"
#ocf_log debug "logfile $logfile"
#ocf_log debug "errlogfile $errlogfile"
#ocf_log debug "process $process"
anything_validate() {
if [ ! -x "$binfile" ]
then
exit $OCF_ERR_INSTALLED
fi
if ! id $user &>/dev/null
then
exit $OCF_ERR_INSTALLED
fi
for filename in "$logfile" "$errlogfile"
do
if [ -n "$filename" ]
then
if [ ! -d "$(dirname $filename)" ]
then
ocf_log err "$(dirname $filename) for $filename
does not exist! Please create it."
exit $OCF_ERR_INSTALLED
fi
fi
done
return $OCF_SUCCESS
}
anything_meta() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="anything_ra">
<version>1.0</version>
<longdesc lang="en">
This is a custom OCF RA to start IN-telegence programs
</longdesc>
<shortdesc lang="en">DK's custom OCF resource agent</shortdesc>
<parameters>
<parameter name="binfile" required="1" unique="1">
<longdesc lang="en">
The full name of the binary to be executed
</longdesc>
<shortdesc lang="en">Full path name of the binary to be executed</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="cmdline_options">
<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="logfile">
<longdesc lang="en">
File to write STDOUT to
</longdesc>
<shortdesc lang="en">File to write STDOUT to</shortdesc>
<content type="string" />
</parameter>
<parameter name="errlogfile">
<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">
<longdesc lang="en">
User to run the command as
</longdesc>
<shortdesc lang="en">User to run the command as</shortdesc>
<content type="string" default="root"/>
</parameter>
</parameters>
<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="100" />
<action name="monitor" depth="0" timeout="20" interval="10" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="5" />
</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
;;
promote|demote|notify)
exit $OCF_SUCCESS
;;
*)
ocf_log err "$0 was called with unsupported arguments: $*"
exit $OCF_ERR_GENERIC
;;
esac
_______________________________________________
Linux-HA mailing list
[email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha
See also: http://linux-ha.org/ReportingProblems