summaryrefslogtreecommitdiffstats
path: root/heartbeat/named
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xheartbeat/named514
1 files changed, 514 insertions, 0 deletions
diff --git a/heartbeat/named b/heartbeat/named
new file mode 100755
index 0000000..f3a17e9
--- /dev/null
+++ b/heartbeat/named
@@ -0,0 +1,514 @@
+#!/bin/sh
+#
+# Description: Manages a named (Bind) server as an OCF High-Availability
+# resource
+#
+# Authors: Serge Dubrouski (sergeyfd@gmail.com)
+#
+# Copyright: 2011 Serge Dubrouski <sergeyfd@gmail.com>
+#
+# License: GNU General Public License (GPL)
+#
+###############################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+#Defaults
+OCF_RESKEY_named_default="/usr/sbin/named"
+OCF_RESKEY_rndc_default="/usr/sbin/rndc"
+OCF_RESKEY_host_default="/usr/bin/host"
+OCF_RESKEY_named_user_default=named
+OCF_RESKEY_named_config_default=""
+OCF_RESKEY_named_pidfile_default="/var/run/named/named.pid"
+OCF_RESKEY_named_rootdir_default=""
+OCF_RESKEY_named_options_default=""
+OCF_RESKEY_named_keytab_file_default=""
+OCF_RESKEY_rndc_options_default=""
+OCF_RESKEY_host_options_default=""
+OCF_RESKEY_monitor_request_default="localhost"
+OCF_RESKEY_monitor_response_default="127.0.0.1"
+OCF_RESKEY_monitor_ip_default="127.0.0.1"
+
+: ${OCF_RESKEY_named=${OCF_RESKEY_named_default}}
+: ${OCF_RESKEY_rndc=${OCF_RESKEY_rndc_default}}
+: ${OCF_RESKEY_host=${OCF_RESKEY_host_default}}
+: ${OCF_RESKEY_named_user=${OCF_RESKEY_named_user_default}}
+: ${OCF_RESKEY_named_config=${OCF_RESKEY_named_config_default}}
+: ${OCF_RESKEY_named_pidfile=${OCF_RESKEY_named_pidfile_default}}
+: ${OCF_RESKEY_named_rootdir=${OCF_RESKEY_named_rootdir_default}}
+: ${OCF_RESKEY_named_options=${OCF_RESKEY_named_options_default}}
+: ${OCF_RESKEY_named_keytab_file=${OCF_RESKEY_named_keytab_file_default}}
+: ${OCF_RESKEY_rndc_options=${OCF_RESKEY_rndc_options_default}}
+: ${OCF_RESKEY_host_options=${OCF_RESKEY_host_options_default}}
+: ${OCF_RESKEY_monitor_request=${OCF_RESKEY_monitor_request_default}}
+: ${OCF_RESKEY_monitor_response=${OCF_RESKEY_monitor_response_default}}
+: ${OCF_RESKEY_monitor_ip=${OCF_RESKEY_monitor_ip_default}}
+
+usage() {
+ cat <<EOF
+ usage: $0 start|stop|reload|status|monitor|meta-data|validate-all|methods
+
+ $0 manages named (Bind) server as an HA resource.
+
+ The 'start' operation starts named server.
+ The 'stop' operation stops named server.
+ The 'reload' operation reload named configuration.
+ The 'status' operation reports whether named is up.
+ The 'monitor' operation reports whether named is running.
+ The 'validate-all' operation reports whether parameters are valid.
+ The 'methods' operation reports on the methods $0 supports.
+EOF
+ return $OCF_ERR_ARGS
+}
+
+named_meta_data() {
+ cat <<EOF
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="named" version="1.0">
+<version>1.0</version>
+
+<longdesc lang="en">
+Resource script for named (Bind) server. It manages named as an HA resource.
+</longdesc>
+<shortdesc lang="en">Manages a named server</shortdesc>
+
+<parameters>
+<parameter name="named" unique="0" required="0">
+<longdesc lang="en">
+Path to the named command.
+</longdesc>
+<shortdesc lang="en">named</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_default}" />
+</parameter>
+
+<parameter name="rndc" unique="0" required="0">
+<longdesc lang="en">
+Path to the rndc command.
+</longdesc>
+<shortdesc lang="en">rndc</shortdesc>
+<content type="string" default="${OCF_RESKEY_rndc_default}" />
+</parameter>
+
+<parameter name="host" unique="0" required="0">
+<longdesc lang="en">
+Path to the host command.
+</longdesc>
+<shortdesc lang="en">host</shortdesc>
+<content type="string" default="${OCF_RESKEY_host_default}" />
+</parameter>
+
+<parameter name="named_user" unique="0" required="0">
+<longdesc lang="en">
+User that should own named process.
+</longdesc>
+<shortdesc lang="en">named_user</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_user_default}" />
+</parameter>
+
+<parameter name="named_config" unique="1" required="0">
+<longdesc lang="en">
+Configuration file for named.
+</longdesc>
+<shortdesc lang="en">named_config</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_config_default}" />
+</parameter>
+
+<parameter name="named_pidfile" unique="1" required="0">
+<longdesc lang="en">
+PIDFILE file for named.
+</longdesc>
+<shortdesc lang="en">named_pidfile</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_pidfile_default}" />
+</parameter>
+
+<parameter name="named_rootdir" unique="1" required="0">
+<longdesc lang="en">
+Directory that named should use for chroot if any.
+</longdesc>
+<shortdesc lang="en">named_rootdir</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_rootdir_default}" />
+</parameter>
+
+<parameter name="named_options" unique="0" required="0">
+<longdesc lang="en">
+Options for named process if any.
+</longdesc>
+<shortdesc lang="en">named_options</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_options_default}" />
+</parameter>
+
+<parameter name="named_keytab_file" unique="0" required="0">
+<longdesc lang="en">
+named service keytab file (for GSS-TSIG).
+</longdesc>
+<shortdesc lang="en">named_keytab_file</shortdesc>
+<content type="string" default="${OCF_RESKEY_named_keytab_file_default}" />
+</parameter>
+
+<parameter name="rndc_options" unique="0" required="0">
+<longdesc lang="en">
+Options for rndc process if any.
+</longdesc>
+<shortdesc lang="en">rndc_options</shortdesc>
+<content type="string" default="${OCF_RESKEY_rndc_options_default}" />
+</parameter>
+
+<parameter name="host_options" unique="0" required="0">
+<longdesc lang="en">
+Options for host process if any.
+</longdesc>
+<shortdesc lang="en">host_options</shortdesc>
+<content type="string" default="${OCF_RESKEY_host_options_default}" />
+</parameter>
+
+<parameter name="monitor_request" unique="0" required="0">
+<longdesc lang="en">
+Request that shall be sent to named for monitoring. Usually an A record in DNS.
+</longdesc>
+<shortdesc lang="en">monitor_request</shortdesc>
+<content type="string" default="${OCF_RESKEY_monitor_request_default}" />
+</parameter>
+
+<parameter name="monitor_response" unique="0" required="0">
+<longdesc lang="en">
+Expected response from named server.
+</longdesc>
+<shortdesc lang="en">monitor_response</shortdesc>
+<content type="string" default="${OCF_RESKEY_monitor_response_default}" />
+</parameter>
+
+<parameter name="monitor_ip" unique="0" required="0">
+<longdesc lang="en">
+IP Address where named listens.
+</longdesc>
+<shortdesc lang="en">monitor_ip</shortdesc>
+<content type="string" default="${OCF_RESKEY_monitor_ip_default}" />
+</parameter>
+</parameters>
+
+<actions>
+<action name="start" timeout="60s" />
+<action name="stop" timeout="60s" />
+<action name="reload" timeout="60s" />
+<action name="status" timeout="10s" />
+<action name="monitor" depth="0" timeout="30s" interval="30s"/>
+<action name="meta-data" timeout="5s" />
+<action name="validate-all" timeout="5s" />
+<action name="methods" timeout="5s" />
+</actions>
+</resource-agent>
+
+EOF
+}
+
+#
+# methods: What methods/operations do we support?
+#
+
+named_methods() {
+ cat <<EOF
+ start
+ stop
+ status
+ monitor
+ methods
+ meta-data
+ validate-all
+EOF
+}
+
+# Validate most critical parameters
+named_validate_all() {
+ check_binary $OCF_RESKEY_named
+ check_binary $OCF_RESKEY_rndc
+ check_binary $OCF_RESKEY_host
+
+ if [ -n "$OCF_RESKEY_named_config" -a \
+ ! -r "${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config}" ]; then
+ if ocf_is_probe; then
+ ocf_log info "Configuration file ${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config} not readable during probe."
+ else
+ ocf_exit_reason "Configuration file ${OCF_RESKEY_named_rootdir}/${OCF_RESKEY_named_config} doesn't exist"
+ return $OCF_ERR_INSTALLED
+ fi
+ fi
+
+ getent passwd $OCF_RESKEY_named_user >/dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ ocf_exit_reason "User $OCF_RESKEY_named_user doesn't exist";
+ return $OCF_ERR_INSTALLED;
+ fi
+
+ if [ -z "$OCF_RESKEY_monitor_request" -o \
+ -z "$OCF_RESKEY_monitor_response" -o \
+ -z "$OCF_RESKEY_monitor_ip" ]; then
+ ocf_exit_reason "None of monitor_request, monitor_response, and monitor_ip can be empty"
+ return $OCF_ERR_CONFIGURED
+ fi
+
+ # make sure that the pidfile directory exists
+ ocf_mkstatedir $OCF_RESKEY_named_user 755 `dirname $OCF_RESKEY_named_pidfile` || return $OCF_ERR_INSTALLED
+
+ return $OCF_SUCCESS
+}
+
+##
+# Attempt to generate a /etc/rndc.key if one is not present
+##
+rndc_key_generator()
+{
+ local rndc_options="-a -r /dev/urandom -u $OCF_RESKEY_named_user"
+
+ if [ -s /etc/rndc.key ]; then
+ # file already exists
+ return
+ fi
+
+ if ! have_binary "rndc-confgen"; then
+ # can't autogen key... Report this, but not as a warning or error.
+ # It is possible that the user configured the key in named.conf
+ ocf_log info "rndc-confgen tool not present, unable to autogen /etc/rndc.key."
+ return
+ fi
+
+ if [ -n "$OCF_RESKEY_rootdir" ]; then
+ rndc_options="$rndc_options -t $OCF_RESKEY_rootdir"
+ fi
+
+ rndc-confgen $rndc_options > /dev/null 2>&1;
+ if [ $? -eq 0 ]; then
+ if have_binary "restorecon"; then
+ restorecon /etc/rndc.key
+ fi
+ else
+ ocf_log info "failed to auto-generate /etc/rndc.key file."
+ fi
+}
+
+#
+# named_getpid. Get pid of named process with a given parameters.
+#
+
+named_getpid () {
+ local pattern="$OCF_RESKEY_named"
+
+ if [ -n "$OCF_RESKEY_named_rootdir" -a "x${OCF_RESKEY_named_rootdir}" != "x/" ]; then
+ pattern="$pattern.*-t $OCF_RESKEY_named_rootdir"
+ fi
+
+ if [ -n "$OCF_RESKEY_named_config" ]; then
+ pattern="$pattern.*-c $OCF_RESKEY_named_config"
+ fi
+
+ pid=`pgrep -f "$pattern"`
+ echo $pid
+}
+
+#
+# named_status. Simple check of the status of named process by pidfile.
+#
+
+named_status () {
+ ocf_pidfile_status ${OCF_RESKEY_named_pidfile} >/dev/null 2>&1
+}
+
+#
+# named_monitor. Send a request to named and check response.
+#
+
+named_monitor() {
+ local output
+
+ if ! named_status
+ then
+ ocf_log info "named is down"
+ return $OCF_NOT_RUNNING
+ fi
+
+ output=`$OCF_RESKEY_host $OCF_RESKEY_host_options $OCF_RESKEY_monitor_request $OCF_RESKEY_monitor_ip`
+
+ if [ $? -ne 0 ] || ! echo $output | grep -q '.* has .*address '"$OCF_RESKEY_monitor_response"
+ then
+ ocf_exit_reason "named didn't answer properly for $OCF_RESKEY_monitor_request."
+ ocf_log err "Expected: $OCF_RESKEY_monitor_response."
+ ocf_log err "Got: $output"
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
+#
+# Reload
+#
+
+named_reload() {
+ $OCF_RESKEY_rndc $OCF_RESKEY_rndc_options reload >/dev/null || return $OCF_ERR_GENERIC
+
+ return $OCF_SUCCESS
+}
+
+#
+# Start
+#
+
+named_start() {
+ local root_dir_opt
+ local pid
+
+ root_dir_opt=""
+ named_status && return $OCF_SUCCESS
+
+ # Remove pidfile if exists
+ rm -f ${OCF_RESKEY_named_pidfile}
+
+ if [ -n "${OCF_RESKEY_named_rootdir}" -a "x${OCF_RESKEY_named_rootdir}" != "x/" ]
+ then
+ root_dir_opt="-t ${OCF_RESKEY_named_rootdir}"
+ [ -s /etc/localtime ] && cp -fp /etc/localtime ${OCF_RESKEY_named_rootdir}/etc/localtime
+ fi
+
+ if [ -n "$OCF_RESKEY_named_config" ]; then
+ OCF_RESKEY_named_options="-c $OCF_RESKEY_named_config $OCF_RESKEY_named_options"
+ fi
+
+ rndc_key_generator
+
+ if ! ${OCF_RESKEY_named} -u ${OCF_RESKEY_named_user} $root_dir_opt ${OCF_RESKEY_named_options}
+ then
+ ocf_exit_reason "named failed to start."
+ return $OCF_ERR_GENERIC
+ fi
+
+
+ pid=`named_getpid`
+
+ if [ -n "$pid" ]; then
+ if [ ! -e ${OCF_RESKEY_named_pidfile} ]; then
+ echo $pid > ${OCF_RESKEY_named_pidfile}
+ fi
+ else
+ ocf_exit_reason "named failed to start. Probably error in configuration."
+ return $OCF_ERR_GENERIC
+ fi
+
+ while :
+ do
+ named_monitor && break
+ sleep 1
+ ocf_log debug "named hasn't started yet."
+ done
+ ocf_log info "named has started."
+
+ return $OCF_SUCCESS
+}
+
+#
+# Stop
+#
+
+named_stop () {
+ local timeout
+ local timewait
+
+ named_status || return $OCF_SUCCESS
+
+ $OCF_RESKEY_rndc $OCF_RESKEY_rndc_options stop >/dev/null
+ if [ $? -ne 0 ]; then
+ ocf_log info "rndc stop failed. Killing named."
+ kill `cat ${OCF_RESKEY_named_pidfile}`
+ fi
+
+ if [ -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)
+ timewait=$((OCF_RESKEY_CRM_meta_timeout/1500))
+ else
+ timewait=20
+ fi
+
+ sleep 1; timeout=0 # Sleep here for 1 sec to let rndc finish.
+ while named_status ; do
+ if [ $timeout -ge $timewait ]; then
+ break
+ else
+ sleep 1
+ timeout=`expr $timeout + 1`
+ ocf_log debug "named appears to hung, waiting ..."
+ fi
+ done
+
+ #If still up
+ if named_status 2>&1; then
+ ocf_exit_reason "named is still up! Killing"
+ kill -9 `cat ${OCF_RESKEY_named_pidfile}`
+ fi
+
+ rm -f ${OCF_RESKEY_named_pidfile}
+ return $OCF_SUCCESS
+}
+
+
+# Main part
+
+if [ $# -ne 1 ]; then
+ usage
+ exit $OCF_ERR_GENERIC
+fi
+
+case "$1" in
+ methods) named_methods
+ exit $?;;
+
+ meta-data) named_meta_data
+ exit $OCF_SUCCESS;;
+esac
+
+named_validate_all
+rc=$?
+
+[ "$1" = "validate-all" ] && exit $rc
+
+if [ $rc -ne 0 ]
+then
+ case "$1" in
+ stop) exit $OCF_SUCCESS;;
+ monitor) exit $OCF_NOT_RUNNING;;
+ status) exit $OCF_NOT_RUNNING;;
+ *) exit $rc;;
+ esac
+fi
+
+if [ `id -u` -ne 0 ]; then
+ ocf_exit_reason "$0 must be run as root"
+ exit $OCF_ERR_GENERIC
+fi
+
+case "$1" in
+ status) if named_status
+ then
+ ocf_log info "named is up"
+ exit $OCF_SUCCESS
+ else
+ ocf_log info "named is down"
+ exit $OCF_NOT_RUNNING
+ fi;;
+
+ monitor) named_monitor
+ exit $?;;
+
+ start) named_start
+ exit $?;;
+
+ stop) named_stop
+ exit $?;;
+ reload) named_reload
+ exit $?;;
+ *)
+ exit $OCF_ERR_UNIMPLEMENTED;;
+esac
+
+# vim:ts=4:sw=4:et: