1#!@BASH_SHELL@
2#
3# Description:  Manages a syslog-ng instance, provided by NTT OSSC as an
4#               OCF High-Availability resource under Heartbeat/LinuxHA control
5#
6# Copyright (c) 2009 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21#
22##############################################################################
23# OCF parameters:
24#   OCF_RESKEY_syslog_ng_binary : Path to syslog-ng binary.
25#                                 Default is "/sbin/syslog-ng"
26#   OCF_RESKEY_configfile       : Configuration file
27#   OCF_RESKEY_start_opts       : Startup options
28#   OCF_RESKEY_kill_term_timeout: Number of seconds to await to confirm a
29#                                 normal stop method
30#
31#   Only OCF_RESKEY_configfile must be specified. Each of the rests
32#   has its default value or refers OCF_RESKEY_configfile to make
33#   its value when no explicit value is given.
34#
35# Further infomation for setup:
36#   There are sample configurations at the end of this file.
37#
38###############################################################################
39
40: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
41. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
42
43# Parameter defaults
44
45OCF_RESKEY_configfile_default=""
46OCF_RESKEY_syslog_ng_binary_default="/sbin/syslog-ng"
47OCF_RESKEY_syslog_ng_ctl_default="/sbin/syslog-ng-ctl"
48OCF_RESKEY_qdisk_dir_default=""
49OCF_RESKEY_control_file_default=""
50OCF_RESKEY_persist_file_default=""
51OCF_RESKEY_pidfile_default=""
52OCF_RESKEY_start_opts_default=""
53OCF_RESKEY_kill_term_timeout_default="10"
54
55: ${OCF_RESKEY_configfile=${OCF_RESKEY_configfile_default}}
56: ${OCF_RESKEY_syslog_ng_binary=${OCF_RESKEY_syslog_ng_binary_default}}
57: ${OCF_RESKEY_syslog_ng_ctl=${OCF_RESKEY_syslog_ng_ctl_default}}
58: ${OCF_RESKEY_qdisk_dir=${OCF_RESKEY_qdisk_dir_default}}
59: ${OCF_RESKEY_control_file=${OCF_RESKEY_control_file_default}}
60: ${OCF_RESKEY_persist_file=${OCF_RESKEY_persist_file_default}}
61: ${OCF_RESKEY_pidfile=${OCF_RESKEY_pidfile_default}}
62: ${OCF_RESKEY_start_opts=${OCF_RESKEY_start_opts_default}}
63: ${OCF_RESKEY_kill_term_timeout=${OCF_RESKEY_kill_term_timeout_default}}
64
65usage()
66{
67	cat <<-!
68usage: $0 action
69
70action:
71        start       : start a new syslog-ng instance
72
73        stop        : stop the running syslog-ng instance
74
75        status      : return the status of syslog-ng, run or down
76
77        monitor     : return TRUE if the syslog-ng appears to be working.
78
79        meta-data   : show meta data message
80
81        validate-all: validate the instance parameters
82!
83	return $OCF_ERR_UNIMPLEMENTED
84}
85
86metadata_syslog_ng()
87{
88	cat <<END
89<?xml version="1.0"?>
90<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
91<resource-agent name="syslog-ng">
92<version>1.0</version>
93
94<longdesc lang="en">
95This script manages a syslog-ng instance as an HA resource.
96
97For Premium Edition you should set the following parameters
98(based on default path being "/opt/syslog-ng"):
99syslog_ng_binary="/opt/syslog-ng/sbin/syslog-ng"
100syslog_ng_ctl="/opt/syslog-ng/sbin/syslog-ng-ctl"
101control_file="/opt/syslog-ng/var/run/syslog-ng.ctl"
102persist_file="/opt/syslog-ng/var/syslog-ng.persist"
103pidfile="/opt/syslog-ng/var/run/syslog-ng.pid"
104
105Additional parameter for Premium Edition 6 only:
106qdisk_dir="/opt/syslog-ng/var/"
107</longdesc>
108<shortdesc lang="en">Syslog-ng resource agent</shortdesc>
109
110<parameters>
111
112<parameter name="configfile" unique="0" required="1">
113<longdesc lang="en">
114This parameter specifies a configuration file 
115for a syslog-ng instance managed by this RA.
116</longdesc>
117<shortdesc lang="en">Configuration file</shortdesc>
118<content type="string" default="${OCF_RESKEY_configfile_default}"/>
119</parameter>
120
121<parameter name="syslog_ng_binary" unique="0">
122<longdesc lang="en">
123This parameter specifies syslog-ng's executable file.
124</longdesc>
125<shortdesc lang="en">syslog-ng executable</shortdesc>
126<content type="string" default="${OCF_RESKEY_syslog_ng_binary_default}"/>
127</parameter>
128
129<parameter name="syslog_ng_ctl" unique="0">
130<longdesc lang="en">
131This parameter specifies the path of the syslog-ng-ctl executable file.
132</longdesc>
133<shortdesc lang="en">syslog-ng-ctl executable</shortdesc>
134<content type="string" default="${OCF_RESKEY_syslog_ng_ctl_default}"/>
135</parameter>
136
137<parameter name="qdisk_dir" unique="0">
138<longdesc lang="en">
139This parameter specifies the directory used for holding disk buffers of
140syslog-ng (only supported in Premium Edition 6).
141</longdesc>
142<shortdesc lang="en">disk buffer directory (PE6 only)</shortdesc>
143<content type="string" default="${OCF_RESKEY_qdisk_dir_default}"/>
144</parameter>
145
146<parameter name="control_file" unique="0">
147<longdesc lang="en">
148This parameter specifies the path, where syslog-ng would place its control
149socket, through which it can be controlled.
150</longdesc>
151<shortdesc lang="en">process control socket</shortdesc>
152<content type="string" default="${OCF_RESKEY_control_file_default}"/>
153</parameter>
154
155<parameter name="persist_file" unique="0">
156<longdesc lang="en">
157This parameter specifies the path for syslog-ng's persist file, which holds
158persistent information about the mapping of destinations and disk buffers,
159the internal state of sources, etc.
160</longdesc>
161<shortdesc lang="en">persist file path</shortdesc>
162<content type="string" default="${OCF_RESKEY_persist_file_default}"/>
163</parameter>
164
165<parameter name="pidfile" unique="0">
166<longdesc lang="en">
167This parameter specifies the path where the pid file of syslog-ng resides.
168</longdesc>
169<shortdesc lang="en">pidfile path</shortdesc>
170<content type="string" default="${OCF_RESKEY_pidfile_default}"/>
171</parameter>
172
173<parameter name="start_opts" unique="0">
174<longdesc lang="en">
175This parameter specifies startup options for a 
176syslog-ng instance managed by this RA. When no value is given, no startup 
177options is used. Don't use option '-F'. It causes a stuck of a start action.
178</longdesc>
179<shortdesc lang="en">Start options</shortdesc>
180<content type="string" default="${OCF_RESKEY_start_opts_default}"/>
181</parameter>
182
183<parameter name="kill_term_timeout" unique="0">
184<longdesc lang="en">
185On a stop action, a normal stop method(pkill -TERM) is firstly used.
186And then the confirmation of its completion is waited for
187the specified seconds by this parameter.
188The default value is 10.
189</longdesc>
190<shortdesc lang="en">Number of seconds to await to confirm a normal stop method</shortdesc>
191<content type="integer" default="${OCF_RESKEY_kill_term_timeout_default}"/>
192</parameter>
193
194</parameters>
195
196<actions>
197<action name="start" timeout="60s" />
198<action name="stop" timeout="120s" />
199<action name="status" timeout="60s" />
200<action name="monitor" depth="0" timeout="60s" interval="60s" />
201<action name="meta-data" timeout="5s" />
202<action name="validate-all"  timeout="5s"/>
203</actions>
204</resource-agent>
205END
206	return $OCF_SUCCESS
207}
208
209monitor_syslog_ng()
210{
211	set -- $(pgrep -f "$PROCESS_PATTERN" 2>/dev/null)
212	case $# in
213		0) ocf_log debug "No syslog-ng process for $CONFIGFILE"
214		   return $OCF_NOT_RUNNING;;
215		1) return $OCF_SUCCESS;;
216	esac
217	ocf_log warn "Multiple syslog-ng process for $CONFIGFILE"
218	return $OCF_SUCCESS
219}
220
221start_syslog_ng()
222{
223	monitor_syslog_ng
224	if [[ $? = "$OCF_SUCCESS" ]]; then
225		return $OCF_SUCCESS
226	fi
227
228	# set -- $SYSLOG_NG_OPTS
229	# ocf_run "$SYSLOG_NG_EXE" -f "$SYSLOG_NG_CONF" "$@"
230	# reduce to this?
231	ocf_run "$SYSLOG_NG_EXE" -f "$CONFIGFILE" $START_OPTS
232	ocf_status=$?
233	if [[ "$ocf_status" != "$OCF_SUCCESS" ]]; then
234		return $OCF_ERR_GENERIC
235	fi
236
237	while true; do
238		monitor_syslog_ng
239		if [[ $? = "$OCF_SUCCESS" ]]; then
240			return $OCF_SUCCESS
241		fi
242		sleep 1
243	done
244}
245
246stop_syslog_ng()
247{
248	if [ -x "$SYSLOG_NG_CTL" ]; then
249		if [ -n "${OCF_RESKEY_control_file}" ] && [ -S "${OCF_RESKEY_control_file}" ]; then
250			"$SYSLOG_NG_CTL" stop "$CONTROL_FILE"
251			CTL_STATUS=$?
252			[ $CTL_STATUS -ne 0 ] && pkill -TERM -f "$PROCESS_PATTERN"
253		else
254			pkill -TERM -f "$PROCESS_PATTERN"
255		fi
256	else
257		pkill -TERM -f "$PROCESS_PATTERN"
258	fi
259
260	typeset lapse_sec=0
261	while pgrep -f "$PROCESS_PATTERN" > /dev/null; do
262		sleep 1
263		lapse_sec=$(( lapse_sec + 1 ))
264		ocf_log debug "stop_syslog_ng[$SYSLOG_NG_NAME]: stop NORM $lapse_sec/$KILL_TERM_TIMEOUT"
265		if [ $lapse_sec -ge $KILL_TERM_TIMEOUT ]; then
266			break
267		fi
268	done
269
270	# if the process can't be removed, then the following part is
271	# not going to be executed (the RA will be killed by lrmd on
272	# timeout) and the pidfile will remain; don't know if that
273	# has any consequences
274	# 2009/09/18 Nakahira
275	# If the syslog-ng process hangs, syslog-ng RA waits
276	# $KILL_TERM_TIMEOUT seconds.
277	# The stop timeout of RA should be longer than $KILL_TERM_TIMEOUT.
278	lapse_sec=0
279	while pgrep -f "$PROCESS_PATTERN" > /dev/null; do
280		pkill -KILL -f "$PROCESS_PATTERN"
281		sleep 1
282		lapse_sec=$(( lapse_sec + 1 ))
283		ocf_log debug "stop_syslog_ng[$SYSLOG_NG_NAME]: suspend syslog_ng by SIGKILL ($lapse_sec/@@@)"
284	done
285
286	return $OCF_SUCCESS
287}
288
289status_syslog_ng()
290{
291	# ???? why not monitor and then print running or stopped
292	monitor_syslog_ng
293	rc=$?
294	if [ $rc = $OCF_SUCCESS ]; then
295		echo "Syslog-ng service is running."
296	elif [ $rc = $OCF_NOT_RUNNING ]; then
297		echo "Syslog-ng service is stopped."
298	else
299		echo "Mutiple syslog-ng process for $CONFIGFILE."
300	fi
301	return $rc
302}
303
304validate_all_syslog_ng()
305{
306	ocf_log info "validate_all_syslog_ng[$SYSLOG_NG_NAME]"
307	return $OCF_SUCCESS
308}
309
310if [[ "$1" = "meta-data" ]]; then
311	metadata_syslog_ng
312	exit $?
313fi
314
315CONFIGFILE="${OCF_RESKEY_configfile}"
316if [[ -z "$CONFIGFILE" ]]; then
317	ocf_log err "undefined parameter:configfile"
318	exit $OCF_ERR_CONFIGURED
319fi
320
321SYSLOG_NG_NAME=${CONFIGFILE##*/}
322SYSLOG_NG_NAME=${SYSLOG_NG_NAME%.*}
323
324SYSLOG_NG_EXE="${OCF_RESKEY_syslog_ng_binary}"
325if [[ ! -x "$SYSLOG_NG_EXE" ]]; then
326	ocf_log err "Invalid value:syslog_ng_binary:$SYSLOG_NG_EXE"
327	exit $OCF_ERR_CONFIGURED
328fi
329
330SYSLOG_NG_CTL="${OCF_RESKEY_syslog_ng_ctl}"
331
332# actually, the pidfile has no function; the status is checked by
333# testing for a running process only
334
335KILL_TERM_TIMEOUT="${OCF_RESKEY_kill_term_timeout}"
336if ! ocf_is_decimal "$KILL_TERM_TIMEOUT"; then
337	ocf_log err "Invalid value:kill_term_timeout:$KILL_TERM_TIMEOUT"
338	exit $OCF_ERR_CONFIGURED
339fi
340
341QDISK_DIR="${OCF_RESKEY_qdisk_dir}"
342CONTROL_FILE="${OCF_RESKEY_control_file}"
343PERSIST_FILE="${OCF_RESKEY_persist_file}"
344PID_FILE="${OCF_RESKEY_pidfile}"
345EXECUTABLE=$(basename "$SYSLOG_NG_EXE")
346PROCESS_PATTERN="$EXECUTABLE -f $CONFIGFILE"
347
348COMMAND=$1
349
350[ -n "$QDISK_DIR" ] && QDISK_DIR="--qdisk-dir $QDISK_DIR"
351[ -n "$PERSIST_FILE" ] && PERSIST_FILE="--persist-file $PERSIST_FILE"
352[ -n "$CONTROL_FILE" ] && CONTROL_FILE="--control $CONTROL_FILE"
353[ -n "$PID_FILE" ] && PID_FILE="--pidfile $PID_FILE"
354
355START_OPTS="${OCF_RESKEY_start_opts} $QDISK_DIR $CONTROL_FILE $PERSIST_FILE $PID_FILE"
356
357case "$COMMAND" in
358	start)
359		ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng start"
360		start_syslog_ng
361		func_status=$?
362		ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng start $func_status"
363		exit $func_status
364		;;
365	stop)
366		ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng stop"
367		stop_syslog_ng
368		func_status=$?
369		ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng stop $func_status"
370		exit $func_status
371		;;
372	status)
373		status_syslog_ng
374		exit $?
375		;;
376	monitor)
377		#ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng monitor"
378		monitor_syslog_ng
379		func_status=$?
380		#ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng monitor $func_status"
381		exit $func_status
382		;;
383	validate-all)
384		validate_all_syslog_ng
385		exit $?
386		;;
387	*)
388		usage
389		;;
390esac
391
392# vim: set sw=4 ts=4 :
393
394### A sample snippet of cib.xml for a syslog-ng resource
395##
396#         <primitive id="prmApSyslog-ng" class="ocf" type="syslog-ng" provider="heartbeat">
397#           <instance_attributes id="prmDummyB_instance_attrs">
398#             <attributes>
399#	       <nvpair id="atr:Syslog-ng:syslog-ng:configfile" name="configfile" value="/etc/syslog-ng/syslog-ng-ext.conf"/>
400#             </attributes>
401#           </instance_attributes>
402#           <operations>
403#             <op id="op:prmSyslog-ng:start"   name="start" timeout="60s" on_fail="restart"/>
404#             <op id="op:prmSyslog-ng:monitor" name="monitor" interval="10s" timeout="60s" on_fail="restart"/>
405#             <op id="op:prmSyslog-ng:stop"    name="stop" timeout="60s" on_fail="block"/>
406#           </operations>
407#         </primitive>
408
409### A sample syslog-ng configuration file for a log collecting host
410###
411### This sample is for a log collecting host by syslog-ng.
412### A syslog-ng process configurated by this sample accepts all messages
413### from a certain network. Any message from the network is preserved into
414### a file for security infomation. Restricting messages to "authpriv" from
415### the network is done on log sending hosts. (See the sample below)
416### Any internal message of the syslog-ng process is preserved into its
417### dedicated file. And any "authpriv" internal message of the syslog-ng
418### process is also preserved into the security infomation file.
419###
420### Change "f_incoming" to suit your enviroment.
421### If you use it as a configuration file for the sample cib.xml above,
422### save it into "/etc/syslog-ng/syslog-ng-ext.conf".
423##
424#options {
425#    sync (0);
426#    time_reopen (10);
427#    log_fifo_size (1000);
428#    long_hostnames (off);
429#    use_dns (yes);
430#    use_fqdn (no);
431#    create_dirs (no);
432#    keep_hostname (yes); };
433#
434#source s_internal { internal(); };
435#source s_incoming { udp(port(514)); };
436#filter f_internal { facility(authpriv); };
437#filter f_incoming { netmask("172.20.0.0/255.255.192.0"); };
438#
439#destination d_internal { file("/var/log/syslog-ng-ext.log" perm(0640));};
440#destination d_incoming {
441#    file("/var/log/secure-ext.log" create_dirs(yes) perm(0640)); };
442#
443#log { source(s_internal); destination(d_internal); };
444#log { source(s_internal); filter(f_internal); destination(d_incoming); };
445#log { source(s_incoming); filter(f_incoming); destination(d_incoming); };
446
447### A sample snippet of syslog-ng configuration file for a log sending host
448###
449### This sample is for a log sending host that uses syslog-ng.
450###
451### Replace "syslog-ng-ext" to the IP address or the hostname of your
452### log collecting host and append it to "syslog-ng.conf" of each log sending
453### host. See the install default syslog-ng.conf to know what "s_sys" and
454### "f_auth" are.
455##
456#destination d_outgoing  { udp("syslog-ng-ext" port(514)); };
457#log { source(s_sys); filter(f_auth); destination(d_outgoing); };
458
459### A sample snippet of syslog configuration file for a log sending host
460###
461### This sample is for a log sending host that uses syslog.
462###
463### Replace "syslog-ng-ext" to the IP address or the hostname of your
464### log collecting host and append it to "syslog.conf" of each log sending
465### host.
466##
467# authpriv.*                                              @syslog-ng-ext
468