#!/bin/sh
# Copyright (c) 2012. Synology, Inc. All Rights Reserved.
#
# OCF Resource Agent resource script wrapper.
#
# OCF instance parameters
#       OCF_RESKEY_initscript
#       OCF_RESKEY_logfile
#       OCF_RESKEY_errlogfile
#       OCF_RESKEY_monitor_hook

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
. $prefix/etc.defaults/rc.subr

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin
PATH=$PATH:$prefix/sbin:$prefix/bin

SYNOHA_BIN="$prefix/sbin/synoha"

wrapper="$OCF_RESOURCE_INSTANCE"
initscript="$OCF_RESKEY_initscript"
logfile="$OCF_RESKEY_logfile"
errlogfile="$OCF_RESKEY_errlogfile"
type="$OCF_RESKEY_type"

ocf_wrapper_meta()
{
	cat << END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="$1">
	<version>1.0</version>
	<longdesc lang="en">This is a generic OCF resource agent wrapper.</longdesc>
	<shortdesc lang="en">Manages an arbitrary service</shortdesc>

	<parameters>
		<parameter name="initscript" required="1" unique="1">
			<longdesc lang="en">Init script to be wrapped and executed.</longdesc>
			<shortdesc lang="en">Init script to be wrapped and executed.</shortdesc>
			<content type="string" default="" />
		</parameter>
		<parameter name="type" required="1" unique="1">
			<content type="string" 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" />
		</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="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>
	</parameters>
	<actions>
		<action name="start"        timeout="30s" />
		<action name="stop"         timeout="30s" />
		<action name="monitor"      timeout="30s" interval="10" depth="0" />
		<action name="meta-data"    timeout="5" />
		<action name="validate-all" timeout="5" />
	</actions>
</resource-agent>
END

	exit $OCF_SUCCESS
}

# According to LSB 3.1 (ISO/IEC 23360:2006), if the `status` action is
# requested, the init scripts will return the following exit status codes.
#
# 0             program is running or service is OK
# 1             program is dead and /var/run pid file exists
# 2             program is dead and /var/lock lock file exists
# 3             program is not runnning
# 4             program or service status is unknown
# 5-99          reserved for future LSB use
# 100-149       reserved for distribution use
# 150-199       reserved for application use
# 200-254       reserved
ocf_wrapper_status()
{
	[ -x "$initscript" ] || return $OCF_ERR_GENERIC

	if [ ! -e $HA_RSCTMP/ocf."$type".run ]; then
		return $OCF_NOT_RUNNING
	fi

	$initscript status &> /dev/null
	if [ "$?" = "0" ]; then
		return $OCF_SUCCESS
	else
		return $OCF_NOT_RUNNING
	fi
}

# For all other init-scripts actions, the init script shall return an exit
# status of zero if the action was successful. Otherwise, the exit status
# shall be non-zero, as defined below. In addition to straightforward success
# , the following situations are also to be considered successful:
#
# - restarting a service (instead of reloading it) with the force-reload argument
# - running `start` on a service already running
# - running `stop` on a service already stopped or not running
# - running `restart` on a service already stopped or not running
# - running `try-restart` on a service already stopped or not running
#
# In case of an error while processing any init-script action except for
# `status`, the init script shall print an error message and exit with a
# non-zero code:
#
# 0             successful
# 1             generic or unspecified error
# 2             invalid or excess argument(s)
# 3             unimplemented feature (for example, `reload`)
# 4             user had insufficient privilege
# 5             program is not installed
# 6             program is not configured
# 7             program is not running
# 8-99          reserved for future LSB use
# 100-149       reserved for distribution use
# 150-199       reserved for application use
# 200-254       reserved
ocf_wrapper_start()
{
	#if ocf_wrapper_status; then
	if [ -e $HA_RSCTMP/ocf."$type".run ]; then
		ocf_log debug "$wrapper: $initscript is already running"
		return $OCF_SUCCESS
	else
		local cmd
		if [ -n "$logfile" -a -n "$errlogfile" ]; then
			cmd="$initscript start >> $logfile 2>> $errlogfile"
		elif [ -n "$logfile" ]; then
			cmd="$initscript start >> $logfile 2>&1"
		else
			cmd="$initscript start"
		fi

		$SYNO_BOOT_BIN --set-check-fs
		ocf_log debug "$wrapper: Starting $initscript"
		eval $cmd

		touch $HA_RSCTMP/ocf."$type".run

		/sbin/initctl emit --no-wait syno.volume.ready

		ocf_wrapper_status
		if [ "$OCF_SUCCESS" = "$?" ]; then
			ocf_log debug "$wrapper: $init started successfully"
			return $OCF_SUCCESS
		else 
			ocf_log err "$wrapper: $init could not be started"
			#return $OCF_ERR_GENERIC
			# skip check
			return $OCF_SUCCESS
		fi
	fi
}

ocf_wrapper_stop()
{
	#if ! ocf_wrapper_status; then
	if [ ! -e $HA_RSCTMP/ocf."$type".run ]; then
		# was not running, so stop can be considered successful
		ocf_log debug "$wrapper: $initscript is already stopped"
		return $OCF_SUCCESS
	else
		ocf_log debug "$wrapper: Stopping $initscript"
		$initscript stop
	
		ocf_wrapper_status
		if [ "$OCF_SUCCESS" = "$?" ]; then
			ocf_log debug "$wrapper: $init stopped successfully"
			rm -fr $HA_RSCTMP/ocf."$type".run
			return $OCF_SUCCESS
		else
			ocf_log err "$wrapper: $init could not be stopped"
			rm -fr $HA_RSCTMP/ocf."$type".run
			#return $OCF_ERR_GENERIC
			# skip check
			return $OCF_SUCCESS
		fi
	fi
}

ocf_wrapper_monitor()
{
	if [ ! -e $HA_RSCTMP/ocf."$type".run ]; then
		return $OCF_NOT_RUNNING
	fi
	ocf_wrapper_status
	if [ "$OCF_SUCCESS" = "$?" ] ; then
		if [ -n "$OCF_RESKEY_monitor_hook" ]; then
			eval "$OCF_RESKEY_monitor_hook"
			return $?
		else
			return $OCF_SUCCESS
		fi
	else
		#synoha_log notice "ocf_wrapper_fs monitor not running"
		#return $OCF_NOT_RUNNING
		# skip check
		return $OCF_SUCCESS
	fi
}

ocf_wrapper_validate()
{
	if ! [ -x $initscript ]; then
		ocf_log err "$initscript doesn't exist."
		exit $OCF_ERR_INSTALLED
	fi

	for logfilename in "$logfile" "$errlogfile"; do
		[ -n "$logfilename" ] && {
			mkdir -p `dirname $logfilename` || {
				ocf_log err "Cannot create $(dirname $logfilename)"
				exit $OCF_ERR_INSTALLED
			}
		}
	done

	return $OCF_SUCCESS
}

ocf_wrapper_notify()
{
	return $OCF_ERR_UNIMPLEMENTED
}

ocf_wrapper_demote()
{
	return $OCF_ERR_UNIMPLEMENTED
}

ocf_wrapper_promote()
{
	return $OCF_ERR_UNIMPLEMENTED
}

ocf_wrapper_reload()
{
	return $OCF_ERR_UNIMPLEMENTED
}

case "$1" in
	meta-data|metadata|meta_data)
		ocf_wrapper_meta
		;;
	start)
		synoha_log notice "ocf_wrapper_fs start"
		ocf_wrapper_start
		;;
	stop)
		synoha_log notice "ocf_wrapper_fs stop"
		ocf_wrapper_stop
		;;
	monitor)
		ocf_wrapper_monitor
		;;
	validate-all)
		ocf_wrapper_validate
		;;
	notify)
		ocf_wrapper_notify
		;;
	demote)
		ocf_wrapper_demote
		;;
	promote)
		ocf_wrapper_promote
		;;
	reload)
		ocf_wrapper_reload
		;;
	*)
		ocf_log err "$0 was called with unsupported arguments: $*"
		exit $OCF_ERR_UNIMPLEMENTED
		;;
esac

# vim:ft=sh
