[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-ha-dev
Subject: [Linux-ha-dev] dovecot ocf resource agent
From: <jeroen () intuxicated ! org>
Date: 2011-02-03 12:13:47
Message-ID: fbaddcacd36ba1ca897f2ca2fac2109a () mail ! perrit ! nl
[Download RAW message or body]
Hi,
I created a resource agent for dovecot as well, basic testing using
ocf-tester has been done. It would be great if someone could have a look.
Again, I will happily modify it if necessary to get it included.
Best regards,
Jeroen Koekkoek
["dovecot.sh" (application/x-shellscript)]
#!/bin/sh
#
# Dovecot
#
# Description: Manages Dovecot as an OCF resource in an high-availability
# setup.
#
# Author: Jeroen Koekkoek
# License: GNU General Public License (GPL)
# Copyright: (C) 2011 Pagelink B.V.
#
# The OCF code was inspired by the Postfix resource script written by
# Raoul Bhatia <r.bhatia@ipax.at>.
#
# OCF parameters:
# OCF_RESKEY_dovecot
# OCF_RESKEY_doveconf
# OCF_RESKEY_config_file
#
################################################################################
# Initialization:
> ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
> ${OCF_RESKEY_dovecot="/usr/sbin/dovecot"}
> ${OCF_RESKEY_doveconf="/usr/bin/doveconf"}
> ${OCF_RESKEY_config_file="/etc/dovecot/dovecot.conf"}
USAGE="Usage: $0 {start|stop|reload|status|monitor|validate-all|meta-data}"
################################################################################
usage()
{
echo $USAGE >&2
}
meta_data()
{
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="dovecot">
<version>0.1</version>
<longdesc lang="en">
Resource script for Dovecot. It manages a Dovecot instance as an OCF resource.
</longdesc>
<shortdesc lang="en">Manages a Dovecot instance</shortdesc>
<parameters>
<parameter name="dovecot" unique="0" required="0">
<longdesc lang="en">
Full path to the dovecot binary.
For example, "/usr/sbin/dovecot".
</longdesc>
<shortdesc lang="en">Full path to dovecot binary</shortdesc>
<content type="string" default="/usr/sbin/dovecot" />
</parameter>
<parameter name="doveconf" unique="0" required="0">
<longdesc lang="en">
Full path to the doveconf binary.
For example, "/usr/bin/doveconf".
</longdesc>
<shortdesc lang="en">Full path to doveconf binary</shortdesc>
<content type="string" default="/usr/bin/doveconf" />
</parameter>
<parameter name="config_file" unique="1" required="0">
<longdesc>
Full pathname of the Dovecot configuration file.
For example, "/etc/dovecot/dovecot.conf"
</longdesc>
<shortdesc>Full pathname of configuration file</shortdesc>
<content type="string" default="/etc/dovecot/dovecot.conf" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="20s" />
<action name="stop" timeout="20s" />
<action name="reload" timeout="20s" />
<action name="monitor" depth="0" timeout="20s" interval="60s" />
<action name="validate-all" timeout="20s" />
<action name="meta-data" timeout="5s" />
</actions>
</resource-agent>
END
}
cmd_by_pid()
{
local pid=$1
if [ "$pid" = "" ]; then
return 1 # failure
fi
local cmd=`ps -p $pid -o ucomm | tail -n 1`
if [ "$cmd" = "" ]; then
return 1 # failure
fi
echo "$cmd"
return 0 # success
}
pids_by_ppid()
{
local pids
local proc
local ppid=$1
if [ "$ppid" = "" ]; then
return 1 # failure
fi
for proc in `ps ax -o pid= -o ppid= | sed \
's/^[[:space:]]*\([0-9]*\)[[:space:]]*\([0-9]*\)[[:space:]]*$/\1;\2/'`; do local \
pid=`echo $proc | cut -f 1 -d \;` local pid_ppid=`echo $proc | cut -f 2 -d \;`
if [ "$ppid" = "$pid_ppid" ]; then
pids="$pids $pid"
fi
done
echo "$pids"
return 0 # success
}
terminate()
{
local pid=$1
local signal=$2
local recheck=$3
local result
if [ -z "$recheck" ]; then
recheck=1
fi
kill -$signal $pid >/dev/null 2>&1; result=$?
if [ $result -eq 0 ] && [ $recheck -gt 0 ]; then
# Grant some time for shutdown and recheck n times.
local i=0
while [ $result -eq 0 ] && [ $i -lt $recheck ]; do
kill -0 $pid >/dev/null 2>&1; result=$?
let "i += 1"
if [ $result -eq 0 ]; then
sleep 1
fi
done
else
result=1
fi
if [ $result -ne 0 ]; then
return 0
fi
# The command name can provide valuable information to the administrator so
# we try our best to be as complete as possible.
local cmd=`cmd_by_pid $ppid`
if [ $? -eq 0 ]; then
ocf_log err "Dovecot child process '$cmd' with pid '$pid' failed to stop."
else
ocf_log err "Dovecot child process with pid '$pid' failed to stop."
fi
return 1
}
terminate_tree()
{
local cmd
local pid
local ppid=$1
local signal=$2
local recheck=$3
local result=0
if [ "$ppid" = "" ]; then
return 1 # failure
fi
if [ "$recheck" = "" ]; then
recheck=0
fi
for pid in `pids_by_ppid $ppid`; do
terminate_tree $pid
if [ $? -eq 1 ]; then
# terminate_tree failed to terminate $pid, but it might still be able to
# terminate other child processes.
result=1
fi
done
# If we failed to terminate all child processes, the parent process will not
# be killed, since that would leave processes floating around.
if [ $result -eq 0 ]; then
terminate $ppid $signal $recheck
recheck=$?
fi
return $result
}
dovecot_option()
{
local result
local value
if [ -z "$1" ]; then
return $OCF_ERR_GENERIC
fi
value=`$doveconf -c $config_file -h $1 2>/dev/null`; result=$?
if [ $result -ne 0 ]; then
return $OCF_ERR_CONFIGURED
fi
echo "$value"
return $OCF_SUCCESS
}
dovecot_pid()
{
local pid
if [ -f "$pid_file" ]; then
pid=`head -n 1 "$pid_file" 2>/dev/null`
if [ -n "$pid" ]; then
echo "$pid"
return $OCF_SUCCESS
fi
ocf_log err "dovecot pid file '$pid_file' empty."
return $OCF_ERR_GENERIC
fi
ocf_log err "dovecot pid file '$pid_file' does not exist."
return $OCF_NOT_RUNNING
}
dovecot_status()
{
local pid
local state
pid=`dovecot_pid`; state=$?
if [ $state -eq $OCF_SUCCESS ]; then
if ! kill -0 $pid >/dev/null 2>&1; then
return $OCF_NOT_RUNNING
else
echo "$pid"
return $OCF_SUCCESS
fi
fi
return $state
}
dovecot_start()
{
local pid
local result
local state
pid=`dovecot_status`; state=$?
if [ $state -eq $OCF_SUCCESS ]; then
ocf_log info "Dovecot already running."
return $state
elif [ $state -eq $OCF_ERR_GENERIC ]; then
ocf_log err "Dovecot returned error."
return $state
fi
$dovecot -c $config_file >/dev/null 2>&1; result=$?
if [ $result -ne 0 ]; then
ocf_log err "Dovecot returned error."
return $OCF_ERR_GENERIC
fi
ocf_log info "Dovecot started."
return $OCF_SUCCESS
}
dovecot_stop()
{
local pid
local ppid
local result
local state
ppid=`dovecot_status`; state=$?
if [ $state -eq $OCF_NOT_RUNNING ]; then
ocf_log info "Dovecot already stopped."
return $OCF_SUCCESS
elif [ $state -eq $OCF_ERR_GENERIC ]; then
ocf_log info "Dovecot returned error."
return $OCF_ERR_GENERIC
fi
local kill_master=0
local remove_pid_file=0
local shutdown_clients=0
# terminate $ppid 15 5; result=$?
terminate $ppid 0 1; result=$?
if [ $result -ne 0 ]; then
ocf_log err "Dovecot failed to stop. Escalating to KILL."
# Figure out if we need to shutdown all active clients as well. This
# behaviour is controlled by the shutdown_clients option in the Dovecot
# configuration file.
shutdown_clients=`dovecot_option shutdown_clients`; state=$?
if [ $state -ne $OCF_SUCCES ]; then
return $state
fi
local cmd
local anvil_pid=0
local config_pid=0
local log_pid=0
if [ "$shutdown_clients" = "yes" ]; then
result=0
for pid in `pids_by_ppid $ppid`; do
cmd=`cmd_by_pid $pid`
if [ "x$cmd" = "xanvil" ]; then
anvil_pid=$pid
elif [ "x$cmd" = "xconfig" ]; then
config_pid=$pid
elif [ "x$cmd" = "xlog" ]; then
log_pid=$pid
else
terminate_tree $pid 9 5 || result=1
kill_master=1
fi
done
if [ $result -eq 0 ] && [ $anvil_pid -ne 0 ]; then
terminate $anvil_pid 9 3; result=$?
kill_master=1
fi
if [ $result -eq 0 ] && [ $log_pid -ne 0 ]; then
terminate $log_pid 9 3; result=$?
kill_master=1
fi
else
result=0
for pid in `pids_by_ppid $ppid`; do
cmd=`cmd_by_pid $pid`
if [ "x$cmd" = "xconfig" ]; then
config_pid=$pid
fi
done
fi
if [ $result -eq 0 ] && [ $config_pid -ne 0 ]; then
terminate $config_pid 9 3; result=$?
kill_master=1
fi
if [ $result -eq 0 ] && [ $kill_master -eq 1 ]; then
terminate $ppid 9 5; result=$?
remove_pid_file=1
fi
else
remove_pid_file=1
fi
if [ $result -eq 0 ] && [ $remove_pid_file -eq 1 ]; then
if [ -f $pid_file ]; then
rm -f "$pid_file" >/dev/null 2>&1
fi
ocf_log info "Dovecot stopped."
return $OCF_SUCCESS
fi
ocf_log err "Dovecot failed to stop."
return $OCF_ERR_GENERIC
}
dovecot_reload()
{
local pid
local state
local result
pid=`dovecot_status`; state=$?
if [ $result -eq $OCF_SUCCESS ]; then
kill -1 $pid >/dev/null 2>&1; result=$?
if [ $result -eq 0 ]; then
state=$OCF_SUCCESS
else
state=$OCF_ERR_GENERIC
fi
fi
if [ $state -eq $OCF_SUCCESS ]; then
ocf_log info "Reloading Dovecot."
elif [ $state -eq $OCF_ERR_GENERIC ]; then
ocf_log err "Dovecot returned error."
fi
return $state
}
dovecot_validate_all()
{
local x
for x in $dovecot $doveconf; do
if [ ! -x $x ]; then
ocf_log err "Dovecot binary '$x' does not exist or cannot be executed."
exit $OCF_ERR_GENERIC
fi
done
if [ ! -f $OCF_RESKEY_conffile ]; then
ocf_log err "Dovecot configuration file '$config_file' does not exist."
exit $OCF_ERR_GENERIC
fi
return $OCF_SUCCESS
}
#
# Main
#
dovecot=$OCF_RESKEY_dovecot
doveconf=$OCF_RESKEY_doveconf
config_file=$OCF_RESKEY_config_file
pid_file=''
if [ -z "$config_file" ]; then
config_file="/etc/dovecot/dovecot.conf"
fi
pid_file="`dovecot_option base_dir`/master.pid"
if [ $# -ne 1 ]; then
usage
exit $OCF_ERR_ARGS
fi
case $1 in
meta-data)
meta_data
exit $OCF_SUCCESS
;;
usage|help)
usage
exit $OCF_SUCCESS
;;
esac
dovecot_validate_all
[ $? -eq $OCF_SUCCESS ] || exit $?
case $1 in
monitor|status)
pid=`dovecot_status`; state=$?
if [ $result -eq $OCF_SUCCESS ]; then
ocf_log info "Dovecot is running."
elif [ $result -eq $OCF_NOT_RUNNING ]; then
ocf_log info "Dovecot is stopped."
fi
exit $state
;;
start)
dovecot_start
exit $?
;;
stop)
dovecot_stop
exit $?
;;
reload)
dovecot_reload
exit $?
;;
validate-all)
exit $OCF_SUCCESS
;;
*)
usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic