#!/bin/sh
#
# GLUSTER OCF resource agent
# Description: manage GLUSTERFSD server daemons
#
# Copyright Patrick Irvine <pirv@cybersites.ca>
# (C) 2010 CyberSites.ca. 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.
#
# See usage() and meta_data() below for more details...
#
# OCF instance parameters:
#	OCF_RESKEY_volfile: the glusterfsd VOLUME_FILE (config file)
#
# Initialization:
: ${OCF_ROOT=/usr/lib/ocf}
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs

CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot"

usage() {
  methods=`gluster_methods`
  methods=`echo $methods | tr ' ' '|'`
  cat <<-!
	usage: $0 {$methods}

	$0 manages a glusterfsd server

	The 'start' operation starts the server.
	The 'stop' operation stops the server.
	The 'status' operation reports whether the server is running. 
	The 'monitor' operation reports whether the server is running 
	The 'validate-all' operation reports whether the parameters are valid
	The 'methods' operation reports on the methods $0 supports

	!
}

meta_data() {
	cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="gluster">
<version>1.0</version>

<longdesc lang="en">
OCF Resource Agent for glusterfsd. start or stop glusterfsd servers.
</longdesc>
<shortdesc lang="en">Control Glusterfs server deamons</shortdesc>

<parameters>

<parameter name="volume" unique="0" required="1">
<longdesc lang="en">
Name of the volume this brick belongs to
</longdesc>
<shortdesc lang="en">volume name</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="path" unique="0" required="1">
<longdesc lang="en">
Path to directory to be exported
</longdesc>
<shortdesc lang="en">Export Path</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="glusterfsd" unique="0" required="0">
<longdesc lang="en">
Name and optional path of the glusterfsd executable
</longdesc>
<shortdesc lang="en">glusterfsd executable name</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="pidfile" unique="0" required="0">
<longdesc lang="en">
Name and optional path of server pid file
</longdesc>
<shortdesc lang="en">pid file</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="logfile" unique="0" required="0">
<longdesc lang="en">
Name and optional path of server log file
</longdesc>
<shortdesc lang="en">log file</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="hostfile" unique="0" required="0">
<longdesc lang="en">
Name and optional path of file containing the server's
host name as used by glusterd
</longdesc>
<shortdesc lang="en">host file</shortdesc>
<content type="string" default="" />
</parameter>

</parameters>

<actions>
<action name="start" timeout="20" />
<action name="stop" timeout="20" />
<action name="status" timeout="30" />
<action name="monitor" depth="0" timeout="30" interval="120" />
<action name="validate-all" timeout="5" />
<action name="methods" timeout="5" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
END
}

gluster_methods() {
  cat <<-!
	start
	stop
	status
	monitor
	validate-all
	methods
	meta-data
	usage
	!
}

setup=gluster_setup
gluster_setup() {
	g_status=gluster_test_status
	glusterfsd=${OCF_RESKEY_glusterfsd:="/usr/sbin/glusterfsd"}

	check_binary $glusterfsd
	HOST_FILE=${OCF_RESKEY_hostfile:="/etc/glusterfs/gluster.host"}
	if [ -f ${HOST_FILE} ]; then
	  THIS_HOST=$(cat ${HOST_FILE});
	else
	  ocf_log err "Current Host File missing: ${HOST_FILE}";
	  return OCF_ERR_CONFIGURED;
	fi
	VOLUME=${OCF_RESKEY_volume}
	BRICK_PATH=${OCF_RESKEY_path}
	TEMP=${BRICK_PATH:1}
	BRICK_ID=${TEMP//\//\-}
	PIDFILE=${OCF_RESKEY_pidfile:="/var/lib/glusterd/vols/${VOLUME}/run/${THIS_HOST}-${BRICK_ID}.pid"}
	LOGFILE=${OCF_RESKEY_logfile:="/var/log/glusterfs/bricks/${BRICK_ID}.log"}
}

get_current_host() {
   return $(glsuter volume info | grep ${BRICK_PATH} | sed -e 's/\:\/.*$//' \
   		-e 's/^.*\: //')
}

gluster_test_status() {
	if [ -f ${PIDFILE} ]; then
	  kill -s 0 `cat ${PIDFILE}` &>/dev/null
	  rc=$?
	else
	  rc=1
	fi
	return $rc
}

gluster_status() {
	if $g_status $OCF_RESKEY_volfile; then
		return $OCF_SUCCESS
	else
		return $OCF_NOT_RUNNING
	fi
}

gluster_start() {
	if $g_status ; then
		ocf_log info "Volume:${VOLUME}, Host: ${BRICK_HOST}, Brick:${PATH} already running"
		return $OCF_SUCCESS
	else
		# see where currently located
		LOC=get_current_host
		# if need to move then
		if [ "${LOC}" != "${THIS_HOST}" ]; then
		   # Get Lock
		   # set to release lock on exit
		   # remove-brick
		   # add-brick
		# else
		else
		   # restart glusterd
		#
		fi
		while ! $g_status; do
			ocf_log debug "Resource has not stated yet, waiting"
			sleep 1
		done
	fi
	exit $OCF_SUCCESS
}

gluster_stop() {
	if ! $g_status ; then
		ocf_log info "Volume:${VOLUME}, HOST: ${BRICK_HOST}, Brick:${PATH} already stopped"
		return $OCF_SUCCESS
	else
		kill $(cat ${PIDFILE}) ||
			return $OCF_ERR_GENERIC
		while $g_status; do
			ocf_log debug "Resource has not stopped yet, waiting"
			sleep 1
		done
	fi
	exit $OCF_SUCCESS
}

#
#	'main' starts here...
#

if [ $# -ne 1 ]; then
	usage
	exit $OCF_ERR_ARGS
fi

# These operations don't require OCF instance parameters to be set
case "$1" in
	meta-data)	meta_data
		exit $OCF_SUCCESS;;
	usage) usage
		exit $OCF_SUCCESS;;
	methods) gluster_methods
		exit $OCF_SUCCESS;;
esac

if [ x = "x$OCF_RESKEY_volume" ]; then
	ocf_log err "no volume attribute"
	exit $OCF_ERR_ARGS
fi

if [ x = "x$OCF_RESKEY_port" ]; then
	ocf_log err "no port attribute"
	exit $OCF_ERR_ARGS
fi

if [ x = "x$OCF_RESKEY_config_host" ]; then
	ocf_log err "no config_host attribute"
	exit $OCF_ERR_ARGS
fi

if [ x = "x$OCF_RESKEY_brick_host" ]; then
	ocf_log err "no brick_host attribute"
	exit $OCF_ERR_ARGS
fi

if [ x = "x$OCF_RESKEY_path" ]; then
	ocf_log err "no path attribute"
	exit $OCF_ERR_ARGS
fi

$setup
rc=$?
if [ $rc -ne 0 ]; then
	ocf_log info "glusterfsd not installed or not setup"
	case "$1" in
		stop) exit $OCF_SUCCESS;;
		monitor) exit $OCF_NOT_RUNNING;;
		status) exit $LSB_STATUS_STOPPED;;
		*) exit $rc;;
	esac
fi

if [ `id -u` != 0 ]; then
	ocf_log err "$0 must be run as root"
	exit $OCF_ERR_PERM
fi

# which method was invoked?
case "$1" in
	start)	gluster_start
	;;
	stop)	gluster_stop
	;;
	status)	if gluster_status
		then
		  ocf_log debug "Volume:${VOLUME}, HOST: ${BRICK_HOST}, Brick:${PATH} already started"
		  exit $OCF_SUCCESS
		else
		  ocf_log debug "Volume:${VOLUME}, HOST: ${BRICK_HOST}, Brick:${PATH} already stopped"
		  ocf_log info glusterfsd using volfile $OCF_RESKEY_volfile stopped
		  exit $OCF_NOT_RUNNING
		fi
		;;
	monitor)	gluster_status
	;;
	validate-all)	# everything already validated
		# just exit successfully here.
		exit $OCF_SUCCESS;;
	*)		gluster_methods
		exit $OCF_ERR_UNIMPLEMENTED;;
esac

#
# vim:tabstop=4:shiftwidth=4:textwidth=0:wrapmargin=0
