#!/usr/bin/env /lib/init/init-d-script
# /etc/init.d/jenkins
# debian-compatible jenkins startup script.
# Amelia A Lewis <alewis@ibco.com>
#
### BEGIN INIT INFO
# Provides:          jenkins
# Required-Start:    $remote_fs $syslog $network
# Required-Stop:     $remote_fs $syslog $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start Jenkins at boot time
# Description:       Controls Jenkins Automation Server
### END INIT INFO

DAEMON=none
COMMAND_NAME=java
NAME="jenkins"
DESC="Jenkins Automation Server"

check_arguments() {
	# Exit if not supposed to run standalone
	if [ "${RUN_STANDALONE}" = "false" ]; then
		echo "ERROR: Not configured to run standalone" >&2
		return 2
	fi

	# Make sure there exists a java executable, it may not be always the case
	JAVA=$(command -v "${COMMAND_NAME}")
	if [ -z "${JAVA}" ]; then
		echo "ERROR: No Java executable found in current PATH: ${PATH}" >&2
		echo "If you actually have Java installed on the system make sure the executable is in the aforementioned path and that 'command -v ${COMMAND_NAME}' returns the Java executable path" >&2
		return 2
	fi

	# Make sure we run as root, since setting the max open files through
	# ulimit requires root access
	if [ "$(id -u)" -gt 0 ]; then
		echo "The ${NAME} init script can only be run as root" >&2
		return 2
	fi
}

check_tcp_port() {
	service=$1
	assigned=$2
	default=$3
	assigned_address=$4
	default_address=$5

	if [ -n "${assigned}" ]; then
		port=${assigned}
	else
		port=${default}
	fi

	if [ -n "${assigned_address}" ]; then
		address=${assigned_address}
	else
		address=${default_address}
	fi

	count=$(netstat --listen --numeric-ports | grep "${address}:${port}[[:space:]]" | grep -c .)

	if [ "${count}" -gt 0 ]; then
		echo "The selected ${service} port (${port}) on address ${address} seems to be in use by another program "
		echo "Please select another address/port combination to use for ${NAME}"
		return 2
	fi
}

do_start_cmd_override() {
	check_arguments || return "$?"

	# load environments
	if [ -r /etc/default/locale ]; then
		. /etc/default/locale
		export LANG LANGUAGE
	elif [ -r /etc/environment ]; then
		. /etc/environment
		export LANG LANGUAGE
	fi
	export JENKINS_HOME

	# the default location is /var/run/jenkins/jenkins.pid but the parent directory needs to be created
	mkdir -p "$(dirname "${PIDFILE}")" || return 2
	chown "${JENKINS_USER}" "$(dirname "${PIDFILE}")" || return 2

	# Verify that the jenkins port is not already in use, winstone does not exit
	# even for BindException
	check_tcp_port "http" "${HTTP_PORT}" "8080" "${HTTP_HOST}" "0.0.0.0" || return 2

	# If the var MAXOPENFILES is enabled in /etc/default/jenkins then set the max open files to the
	# proper value
	if [ -n "${MAXOPENFILES}" ]; then
		[ "${VERBOSE}" != no ] && echo "Setting up max open files limit to ${MAXOPENFILES}"
		ulimit -n "${MAXOPENFILES}" || return 2
	fi
	# notify of explicit umask
	if [ -n "${UMASK}" ]; then
		[ "${VERBOSE}" != no ] && echo "Setting umask to ${UMASK}"
	fi

	# enable access log
	if [ "${JENKINS_ENABLE_ACCESS_LOG}" = "yes" ]; then
		JENKINS_ARGS="${JENKINS_ARGS} --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/var/log/${NAME}/access_log"
	fi

	# start-stop-daemon --chuid/--group doesn't prepare environment variables
	# like HOME, USER, LOGNAME or USERNAME, so re-export these
	SHELL=$(awk -F: "\$1 == \"${JENKINS_USER}\" {print \$NF}" /etc/passwd)
	[ -n "${SHELL}" ] || SHELL=/bin/bash
	HOME="${JENKINS_HOME}" \
		SHELL="${SHELL}" \
		USER="${JENKINS_USER}" \
		LOGNAME="${JENKINS_USER}" \
		USERNAME="${JENKINS_USER}" \
		PWD="${JENKINS_HOME}" \
		eval \
		start-stop-daemon \
		--start \
		--quiet \
		--oknodo \
		--background \
		--no-close \
		--make-pidfile \
		--pidfile "${PIDFILE}" \
		--chdir "${JENKINS_HOME}" \
		--chuid "${JENKINS_USER}" \
		--user "${JENKINS_USER}" \
		--group "${JENKINS_GROUP}" \
		--name "${COMMAND_NAME}" \
		--exec "${JAVA}" \
		${UMASK:+--umask ${UMASK}} \
		-- ${JAVA_ARGS} -jar "${JENKINS_WAR}" ${JENKINS_ARGS} >>"${JENKINS_LOG}" 2>&1
	RETVAL="$?"
	[ "${RETVAL}" = 2 ] && return 2
	# Verify the process did in fact start successfully and didn't just bomb out
	sleep 1
	ATTEMPT=1
	while [ ${ATTEMPT} -le 30 ]; do
		pidofproc -p "${PIDFILE}" "${JAVA}" >/dev/null && break
		[ "${ATTEMPT}" = 30 ] && return 2
		sleep 1
		ATTEMPT=$((ATTEMPT + 1))
	done
	return "${RETVAL}"
}

do_stop_cmd_override() {
	check_arguments || return "$?"
	start-stop-daemon \
		--stop \
		--quiet \
		--oknodo \
		--pidfile "${PIDFILE}" \
		--chdir "${JENKINS_HOME}" \
		--chuid "${JENKINS_USER}" \
		--user "${JENKINS_USER}" \
		--group "${JENKINS_GROUP}" \
		--name "${COMMAND_NAME}" \
		--exec "${JAVA}" \
		--retry=TERM/30/KILL/5
	RETVAL="$?"
	[ "${RETVAL}" = 2 ] && return 2
	# Wait for children to finish too if this is a daemon that forks
	# and if the daemon is only ever run from this initscript.
	# If the above conditions are not satisfied then add some other code
	# that waits for the process to drop all resources that could be
	# needed by services started subsequently.  A last resort is to
	# sleep for some time.
	start-stop-daemon \
		--stop \
		--quiet \
		--oknodo \
		--pidfile "${PIDFILE}" \
		--chdir "${JENKINS_HOME}" \
		--chuid "${JENKINS_USER}" \
		--user "${JENKINS_USER}" \
		--group "${JENKINS_GROUP}" \
		--name "${COMMAND_NAME}" \
		--exec "${JAVA}" \
		--retry=0/30/KILL/5
	[ "$?" = 2 ] && return 2
	# Many daemons don't delete their pidfiles when they exit.
	rm -f "${PIDFILE}"
	return "${RETVAL}"
}

do_status_override() {
	check_arguments || return "$?"
	status_of_proc "${JAVA}" "${NAME}" -p "${PIDFILE}"
}
