#!/bin/bash
# skip crab_syntax
set -e

### BEGIN INIT INFO
# Provides:		uwsgi-emperor
# Required-Start:	$local_fs $remote_fs $network $time
# Required-Stop:	$local_fs $remote_fs $network $time
# Should-Start:		$syslog
# Should-Stop:		$syslog
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	Crm uwsgi server
### END INIT INFO

# systemctl может автоматический генерировать сервисы для SysVinit скриптов
# В современных Ubuntu, если /lib/lsb/init-functions увидит systemctl сервис,
# то передаст управление systectl и выйдет.
# Так получим неработающий сервис:
# - init-functions запускает systemctl
# - systemctl запускает SysVinit
# - а тело init скрипта фактический не выполняется.
# SYSTEMCTL_SKIP_REDIRECT пропустит редирект к systemctl и пойдёт дальше по скрипту.
SYSTEMCTL_SKIP_REDIRECT=true

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/uwsgi
DAEMON_ARGS='--ini /tmp/uwsgi-emperor.ini --daemonize /var/log/uwsgi-emperor.log --emperor-pidfile /var/run/uwsgi-emperor.pid'
NAME=uwsgi-emperor
DESC=uwsgi-emperor

PIDFILE=/var/run/uwsgi-emperor.pid

. /lib/lsb/init-functions


DEBUG=TRUE
DEBUG_PID=$$
DEBUG_SCRIPT=$0
DEBUG_ARGS=$*
DEBUG_LOG=/var/log/debug_init_d.log

export LANG=en_US.UTF-8
# export LANGUAGE=en_US:en
# export LC_ALL=en_US.UTF-8

set -e

debug() {
	if [ "${DEBUG:-}" = "TRUE" ]; then
		echo "$(date +'%Y-%m-%d %H:%M:%S') $DEBUG_SCRIPT:$DEBUG_ARGS:$DEBUG_PID $1" >>"$DEBUG_LOG"
	fi
	return 0
}

is_running() {
	debug "is_running pidfile $PIDFILE $([ ! -f $PIDFILE ] && echo "not ")exists,\
pid=$(cat $PIDFILE 2>/dev/null), \
proc $([ ! -s "$PIDFILE" ] || [ ! -d "/proc/$(cat $PIDFILE)" ] && echo "not ")exists"
	if [ ! -s "$PIDFILE" ] || [ ! -d "/proc/$(cat $PIDFILE)" ]; then
		return 1
	fi
	return 0
}

check_pid_process() {
	ps_axm="$(ps axm)"
	# Странная ситуация, иногда в pid попадал другой процесс
	if ! grep -q "$(cat $PIDFILE) .* $(echo "$DAEMON_ARGS" | sed 's/\-/\\-/g')$" <<<"$ps_axm"; then
		debug "check_pid_process pidfile $PIDFILE $(cat $PIDFILE) not this proccess: \
$(ps axm | grep "$(cat $PIDFILE)" | grep -v grep)"
		return 1
	fi
	return 0
}

kill_proc_by_daemon_args() {
	ps axm | grep "$(echo "$DAEMON_ARGS" | sed 's/\-/\\-/g')" | grep -v grep \
		| awk '{ print $1; }' > /tmp/init_d_procs_to_kill.$$
	if [ -s /tmp/init_d_procs_to_kill.$$ ]; then
		debug "kill_proc_by_daemon_args procs to kill $(cat /tmp/init_d_procs_to_kill.$$)"
		while read -r pid t; do
			[ -d /proc/$pid ] && kill -TERM $pid
		done < /tmp/init_d_procs_to_kill.$$
		sleep 1
		while read pid t; do
			[ -d /proc/$pid ] && kill -KILL $pid
		done < /tmp/init_d_procs_to_kill.$$
	fi
	rm -f /tmp/init_d_procs_to_kill.$$
	return 0
}

debug "Start $0 $*"

case "$1" in
	start)
	echo -n "Starting $DESC: "
	if is_running; then
		if ! check_pid_process; then
			echo "rm bad pidfile and start."
			rm -f $PIDFILE
			${0} start
		else
			echo "already started."
		fi
	else
		rm -f $PIDFILE
		touch $PIDFILE
	# start-stop-daemon --start -d /opt/account --quiet --oknodo --umask 007 --exec $DAEMON -- $DAEMON_ARGS
		ulimit -n 65536 || true
		if start-stop-daemon --start -n $NAME -d / --exec $DAEMON -- $DAEMON_ARGS; then
			echo "$NAME started."
		else
			echo "failed."
		fi
	fi
	;;

	stop)
	echo -n "Stopping $DESC: "
	if ! is_running; then
		echo "already stopped."
	else
		kill -INT `cat $PIDFILE`
		if start-stop-daemon --stop -n $NAME -d / --signal INT --retry forever/TERM/1 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
		then
			if is_running; then
				# По идее нам не обязательно ждать когда демон остановится, но в некоторых случаях может быть довольно долго
				# и падать зависимые от работоспособности демона вещи в скриптах. Например синхронизация пользователей.
				for i in $(seq 1 30); do
					! is_running && break
					sleep 1
				done
			fi
			if is_running; then
				echo "$NAME may still be stopping down or stopping may have failed."
			else
				echo "$NAME stopped."
			fi
		else
			echo "failed."
		fi
		rm -f $PIDFILE
		sleep 1
	fi
	kill_proc_by_daemon_args
	;;

	restart|force-reload)
	${0} stop
	${0} start
	;;

	status)
	status_of_proc -p ${PIDFILE} ${DAEMON} ${NAME}
	;;

	*)
	echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
	exit 1
	;;
esac

debug "End $0 $*"

exit 0
