#!/bin/bash

### Maintain compatibility with chkconfig
# chkconfig: 2345 83 17
# description: buildbot-worker

### BEGIN INIT INFO
# Provides:          buildbot-worker
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Buildbot worker init script
# Description:       This file allows running buildbot worker instances at
#                    startup
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
WORKER_RUNNER=/usr/bin/buildbot-worker

. /lib/lsb/init-functions

# Source buildbot-worker configuration
if [[ -r /etc/default/buildbot-worker ]]; then
	. /etc/default/buildbot-worker
elif [[ -r /etc/default/buildslave ]]; then
	log_warning_msg "Copying legacy /etc/default/buildslave to /etc/default/buildbot-worker"
	cp -f /etc/default/buildslave /etc/default/buildbot-worker
	. /etc/default/buildbot-worker
fi

# Or define/override the configuration here
#WORKER_ENABLED[1]=0                    # 0-enabled, other-disabled
#WORKER_NAME[1]="default"               # short name printed on start/stop
#WORKER_USER[1]="buildbot"              # user to run worker as
#WORKER_BASEDIR[1]="/var/lib/buildbot/workers/default"  # basedir to worker (absolute path)
#WORKER_OPTIONS[1]=""                   # buildbot options
#WORKER_PREFIXCMD[1]=""                 # prefix command, i.e. nice, linux32, dchroot

if [[ ! -x ${WORKER_RUNNER} ]]; then
	log_failure_msg "does not exist or not an executable file: ${WORKER_RUNNER}"
	exit 1
fi

function is_enabled() {
	ANSWER=`echo $1|tr "[:upper:]" "[:lower:]"`
	[[ "$ANSWER" == "yes" ]] || [[ "$ANSWER" == "true" ]] || [[ "$ANSWER" ==  "1" ]]
	return $?
}

function is_disabled() {
	ANSWER=`echo $1|tr "[:upper:]" "[:lower:]"`
	[[ "$ANSWER" == "no" ]] || [[ "$ANSWER" == "false" ]] || [[ "$ANSWER" ==  "0" ]]
	return $?
}

function worker_config_valid() {
	# Function validates buildbot worker instance startup variables based on
	# array index
	local errors=0
	local index=$1

	if ! is_enabled "${WORKER_ENABLED[$index]}" && ! is_disabled "${WORKER_ENABLED[$index]}" ; then
		log_warning_msg "buildbot-worker #${index}: invalid enabled status"
		errors=$(($errors+1))
	fi

	if [[ -z ${WORKER_NAME[$index]} ]]; then
		log_failure_msg "buildbot-worker #${index}: no name"
		errors=$(($errors+1))
	fi

	if [[ -z ${WORKER_USER[$index]} ]]; then
		log_failure_msg "buildbot-worker #${index}: no run user specified"
		errors=$( ($errors+1) )
	elif ! getent passwd ${WORKER_USER[$index]} >/dev/null; then
		log_failure_msg "buildbot-worker #${index}: unknown user ${WORKER_USER[$index]}"
		errors=$(($errors+1))
	fi

	if [[ ! -d "${WORKER_BASEDIR[$index]}" ]]; then
		log_failure_msg "buildbot-worker ${index}: basedir does not exist ${WORKER_BASEDIR[$index]}"
		errors=$(($errors+1))
	fi

	return $errors
}

function check_config() {
	itemcount="${#WORKER_ENABLED[@]}
	${#WORKER_NAME[@]}
	${#WORKER_USER[@]}
	${#WORKER_BASEDIR[@]}
	${#WORKER_OPTIONS[@]}
	${#WORKER_PREFIXCMD[@]}"

	if [[ $(echo "$itemcount" | grep -oE '[0-9]+' | sort -u | wc -l) -ne 1 ]]; then
		log_failure_msg "WORKER_* arrays must have an equal number of elements!"
		return 1
	fi

	errors=0
	for i in $( seq ${#WORKER_ENABLED[@]} ); do
		if is_disabled "${WORKER_ENABLED[$i]}" ; then
			log_warning_msg "buildbot-worker #${i}: disabled"
			continue
		fi
		worker_config_valid $i
		errors=$(($errors+$?))
	done

	[[ $errors == 0 ]]; return $?
}

check_config || exit $?

function worker_op () {
	op=$1 ; mi=$2

	if [ `uname` = SunOS ]; then
		suopt=""
	else
		suopt="-s /bin/sh"
	fi
	${WORKER_PREFIXCMD[$mi]} \
		su $suopt - ${WORKER_USER[$mi]} \
		-c "$WORKER_RUNNER $op ${WORKER_OPTIONS[$mi]} ${WORKER_BASEDIR[$mi]} > /dev/null"
	return $?
}

function do_op () {
	errors=0
	for i in $( seq ${#WORKER_ENABLED[@]} ); do
		if [ -n "$4" ] && [ "$4" != "${WORKER_NAME[$i]}" ] ; then
			continue
		elif is_disabled "${WORKER_ENABLED[$i]}" && [ -z "$4" ] ; then
			continue
		fi

		log_daemon_msg "$3 #$i: ${WORKER_NAME[$i]}"
		if eval $1 $2 $i; then
			log_end_msg 0
		else
			log_end_msg 1
			errors=$(($errors+1))
		fi
	done
	return $errors
}

function worker_status () {
	local errors=0
	local name="$1"
	for i in $( seq ${#WORKER_ENABLED[@]} ); do
		if [ -n "$name" ] && [ "$name" != "${WORKER_NAME[$i]}" ] ; then
			continue
		elif is_disabled "${WORKER_ENABLED[$i]}" && [ -z "$name" ] ; then
			continue
		elif [ -z "${WORKER_BASEDIR[$i]}" ]; then
			continue
		fi

		if kill -0 "$(cat ${WORKER_BASEDIR[$i]}/twistd.pid)" >/dev/null 2>&1; then
			log_success_msg "buildbot-worker #$i: $name is running"
		else
			log_failure_msg "buildbot-worker #$i: $name is not running"
			errors=$(($errors+1))
		fi
	done
	return $errors
}

case "$1" in
start)
	do_op "worker_op" "start" "Starting buildbot-worker" "$2"
	exit $?
	;;
stop)
	do_op "worker_op" "stop" "Stopping buildbot-worker" "$2"
	exit $?
	;;
reload)
	do_op "worker_op" "reload" "Reloading buildbot-worker" "$2"
	exit $?
	;;
restart|force-reload)
	do_op "worker_op" "restart" "Restarting buildbot-worker" "$2"
	exit $?
	;;
status)
	worker_status "$2"
	exit $?
	;;
*)
	echo "Usage: $0 {start|stop|restart|reload|force-reload|status}"
	exit 1
	;;
esac

exit 0
