#!/bin/sh -e
#
#  $Header: svn+ssh://arcadia.yandex.ru/arc/trunk/arcadia/yweb/webscripts/admscripts/scripts/startup/Linux/etc/init.d/mapreduce 1127308 2013-12-07 09:02:40Z stunder $
#

### BEGIN INIT INFO
# Provides:             mapreduce
# Required-Start:       $all
# Required-Stop:        reboot
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Mapreduce
### END INIT INFO

checkproc=0;
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:"
bin_name="mapreduce"


. /lib/lsb/init-functions

name=$(basename $(realpath $0))
type="${name%_*}"
role="${name#*_}"

mapreduce_cfg_file="/etc/default/${name}"
if [ -f "${mapreduce_cfg_file}" ]; then
	. ${mapreduce_cfg_file}
else
        log_failure_msg "${mapreduce_cfg_file} not found, exiting..."
        exit 1
fi
: ${SKLAD_DEBUG_PORT:="6555"}

user="${mapreduce_user}"
export SKLAD_DEBUG_PORT="${SKLAD_DEBUG_PORT}"

case ${role} in
	server)
		work_dir="${server_work_dir}"
		DARGS="-runserver ${mapreduce_port} -backupserver ${backup_server}:${backup_server_port} -http ${mapreduce_http_port} -log ${work_dir}/log/${role}.log -err ${work_dir}/${role}.stderr.log"
		;;
	backupserver)
		work_dir="${server_work_dir}"
		DARGS="-runserver ${mapreduce_port} -http ${mapreduce_http_port} -log ${work_dir}/log/${role}.log -err ${work_dir}/${role}.stderr.log"
		;;
	fileserver)
		work_dir="${fileserver_work_dir}"
		DARGS="-runfileservcompat ${mapreduce_server}:${mapreduce_port} -port ${fileserver_port} -log ${work_dir}/log/${role}.log -err ${work_dir}/${role}.stderr.log"
		;;
	mrproxy)
		work_dir="${mrproxy_work_dir}"
		DARGS="-runmrproxy ${mapreduce_server}:${mapreduce_port} -port ${mrproxy_port} -log ${work_dir}/log/${role}.log -err ${work_dir}/${role}.stderr.log"
		;;
	http_proxy)
		work_dir="${http_proxy_work_dir}"
		DARGS="-runproxy ${mapreduce_server}:${mapreduce_port} -http ${http_proxy_port} -log ${work_dir}/log/${role}.log -err ${work_dir}/${role}.stderr.log"
		;;
	*)
		work_dir="${host_work_dir}"
		DARGS=" -runhost ${mapreduce_server}:${mapreduce_port} -http ${mapreduce_http_port} -log ${work_dir}/log/host.log -err ${work_dir}/${role}.stderr.log"
		;;
esac	

check_directory_exists () {
	if [ -z "`/bin/mount | grep /place`" ]; then
		log_begin_msg "/place not mounted"
		log_end_msg 1
		exit 1
	fi
	if ! [ -d ${work_dir} ] ; then
		mkdir -p ${work_dir}/log 
		chown -R ${user} ${work_dir} 
	fi;
}


check_configs() {
	if ([ "${role}" = "mapreduce" ] &&  [ -f /etc/${type}/host.cfg ]); then
		ln -sf /etc/${type}/host.cfg ${work_dir}/host.cfg
	fi;
	if ([ "${role}" = "server" ] || [ "${role}" = "backupserver" ] && [ -f /etc/${type}/server.cfg ]); then
		ln -sf /etc/${type}/server.cfg ${work_dir}/server.cfg
	fi;
	if ([ "${role}" = "server" ] || [ "${role}" = "backupserver" ] && [ -f /etc/${type}/quota.cfg ]); then
		ln -sf /etc/${type}/quota.cfg ${work_dir}/quota.cfg
	fi;
	if ([ "${role}" = "server" ] || [ "${role}" = "backupserver" ] && [ -f /etc/${type}/nettable.cfg ]); then
		ln -sf /etc/${type}/nettable.cfg ${work_dir}/nettable.cfg
	fi;
	if ([ "${role}" = "server" ] || [ "${role}" = "backupserver" ] && [ -f /etc/${type}/scheduler.cfg ]); then
		ln -sf /etc/${type}/scheduler.cfg ${work_dir}/scheduler.cfg
	fi;
	if ([ "${role}" = "fileserver" ] && [ -f /etc/${type}/fileserv.cfg ]); then
		ln -sf /etc/${type}/fileserv.cfg ${work_dir}/fileserv.cfg
	fi;
}

binary_check() {
	local _local_md5 _remote _remote_md5 _tmp_md5 _tmpdir
	export TMPDIR="${work_dir}"
	_tmpdir="`mktemp -d -t ${name}.XXXXX`"
	[ -z "${_tmpdir}" ] && tmpdir="${work_dir}/tmp"
	mkdir -p ${_tmpdir} && chown -R ${user} ${_tmpdir}

	if [ -x ${work_dir}/${bin_name} ]; then
	_local_md5="`/usr/bin/md5sum ${work_dir}/${bin_name}`"
	_local_md5="${_local_md5%% *}"
	fi

	#Fetch small size file contail md5 binary checksum 
	_remote="`wget --timeout=20 -w 5 --tries=3 -q -O /dev/stdout ${mapreduce_servurl}/md5 || return 0`"
	if [ "${_remote}" ]; then
		_remote_md5="${_remote%% *}"
		# Update binary
		if ! [ "${_local_md5}" = "${_remote_md5}" ]; then
			printf "Updating ${bin_name} binary from ${mapreduce_servurl} \n"
			wget -q -O ${_tmpdir}/${bin_name} ${mapreduce_servurl}/${bin_name}
			_tmp_md5="`md5sum ${_tmpdir}/${bin_name}`"
			_tmp_md5="${_tmp_md5%% *}"
			if ! [ "${_tmp_md5}" = "${_remote_md5}" ]; then
				wget -q -O ${_tmpdir}/${bin_name} ${mapreduce_servurl}/${bin_name}
				if ! [ ${_tmp_md5} = ${_remote_md5} ]; then
					log_failure_msg "Can't fetch ${bin_name} binary\n"
					rm -Rf ${_tmpdir} > /dev/null 2>&1
					exit 1
				fi
			fi
			install -o ${user} -m 755 ${_tmpdir}/${bin_name} ${work_dir}/${bin_name}
			rm -Rf ${_tmpdir} > /dev/null 2>&1

		else
			log_success_msg "binary version matches "
		fi
	else
			log_failure_msg "Can't get remote md5 from ${mapreduce_servurl}\n"
			log_warning_msg "Starting with old binary"
	fi
	rm -Rf ${_tmpdir} > /dev/null 2>&1
}

start () {
	local _retv
	log_begin_msg "Starting ${name}..."
	check_directory_exists;
	check_configs;
	if [ ! -d /var/run/${name} ]; then
		mkdir -p /var/run/${name}
	fi;
	chown -R ${user}:${user} /var/run/${name}

	if start-stop-daemon --quiet --stop --signal 0 --pidfile /var/run/${name}/${name}.pid 2>/dev/null 1>/dev/null ; then
		log_warning_msg "${name} already running\n"
	else
		binary_check
		#Set capabilities for realtime priority
		setcap 'CAP_FOWNER=ep cap_sys_nice=ep' ${work_dir}/${bin_name}
		su ${user} -c "/sbin/start-stop-daemon --start --chdir ${work_dir} --exec ${work_dir}/${bin_name} --make-pidfile --pidfile /var/run/${name}/${name}.pid --background --exec ${work_dir}/${bin_name} -- ${DARGS} 2>>${work_dir}/${role}.stderr.log 1>>${work_dir}/${role}.stderr.log"
		_retv="$?"
		if [ "${_retv}" -ne 0 ]; then
			log_end_msg "${_retv}"
			exit "${_retv}"
		fi
	fi;
##	log_end_msg ${_retv}
	return ${_retv}
}

stop () {
	local _retv
	log_begin_msg "Stopping ${name}..."
	start-stop-daemon --quiet --retry 10 --stop --pidfile /var/run/${name}/${name}.pid 1>/dev/null 2>&1
	_retv="$?"
	log_end_msg "${_retv}"
	if [ "${_retv}" -eq 0 ]; then
		rm -f /var/run/${name}/${name}.pid 2>/dev/null
	fi
}

check_process_by_pidfile () {
	local _retv
	start-stop-daemon --quiet --stop --signal 0 --pidfile /var/run/${name}/${name}.pid 2>/dev/null 1>/dev/null;
	_retv="$?"
	return ${_retv}
}

check_process () {
	local _mr_pattern _mr_pid
	_mr_pattern="\-runhost|\-runserver|\-runproxy\-runfileserv"
	if check_process_by_pidfile ; then
		log_warning_msg "${name} is running ";
		return 0;
	else
		_mr_pid=`ps ax|grep ${work_dir}/${bin_name}|grep -E ${_mr_pattern} 2>/dev/null`
		_mr_pid="${_mr_pid%% *}"
		if [ -z ${_mr_pid} ]; then
			log_warning_msg "${name} not running ";
			return 1;
		else
			echo ${_mr_pid} > /var/run/${name}/${name}.pid
			log_warning_msg "${name} already running "
			return 0;
		fi;
		chown -R ${user}:${user} /var/run/${name}/${name}.pid
	fi;
}

start_mr_process () {
	local _retv
	if ! check_process; then
		if ([ -e /tmp/${name}-stopped ] && [ ${checkproc} -eq 1 ]); then
			log_begin_msg "${name} was stopped manualy, exiting..."
			log_end_msg 1 
		else
			rm -f /tmp/${name}-stopped
			start && sleep 4 && check_process
			_retv="$?"
			if [ "${_retv}" -eq 0 ]; then
				log_end_msg "${_retv}"
				log_success_msg "${name} started"
			else
				log_end_msg "${_retv}"
				log_failure_msg "${name} failed to start! "
			fi
		fi
	fi
	return ${_retv}
}

stop_mr_process () {
	touch /tmp/${name}-stopped
	stop;
}

restart_mr_process () {
	stop_mr_process;
	sleep 3;
#	killall -u ${user}
#	sleep 3;
	start_mr_process;
}

case "$1" in
	start)
		start_mr_process;
		;;
	stop)
		stop_mr_process;
		;;
	restart)
		restart_mr_process;
		;;
	checkproc )
		checkproc=1;
		start_mr_process;
		;;
	status)
		check_process;
		;;
	*)
		log_action_msg "Usage: $0 {start|stop|restart|status}";
		return 1
		;;
esac;

exit 0;
