#!/bin/sh
# Copyright (c) 2000-2015 Synology Inc. All rights reserved.
. /var/packages/Docker/scripts/pkg_utils
## Get modules list
source /usr/syno/etc.defaults/iptables_modules_list
DockerModules="xt_addrtype.ko xt_conntrack.ko veth.ko macvlan.ko aufs.ko"
DockerBridgeModules="llc.ko stp.ko bridge.ko macvlan.ko"
DockerPIDFile="/var/run/docker.pid"
TermdPIDFile="/var/run/termd.pid"

WebapiLibLink="/usr/syno/synoman/webapi/SYNO.Docker.lib"
DockerBinLink="/usr/local/bin/docker"
ModProxyWstunnelLink="/lib/httpd/modules/mod_proxy_wstunnel.so"
HttpSysLink="/etc/httpd/sites-enabled/Docker.legacy.conf"
InsertModules="${KERNEL_MODULES_CORE} ${KERNEL_MODULES_COMMON} ${KERNEL_MODULES_NAT} ${IPV6_MODULES} ${DockerModules} ${DockerBridgeModules}"
DockerServName="docker"
RunningContainerList="/var/packages/Docker/etc/LastRunningContainer"
TargetPath="/var/packages/Docker/target"
DockerBin="$TargetPath/usr/bin/docker"
ContainerDepBin="$TargetPath/tool/container_sort"
ModProxyWstunnelBin="$TargetPath/lib/httpd/modules/mod_proxy_wstunnel.so"
HttpSysConf="$TargetPath/config/Docker.legacy.conf"
TermdBin="$TargetPath/termd/termd"

wait_for_condition()
{
	local maxTryCount=60
	local timeGap=1
	while eval "$@" >&/dev/null; do
		if [ "${maxTryCount}" -le 0 ]; then
			break
		fi
		maxTryCount="$((maxTryCount-1))"
		sleep "${timeGap}"
	done
}

argument_reverse() {
	local args="$1"
	local arg
	local ret=""

	for arg in ${args}; do
		ret="${arg} ${ret}"
	done

	echo "${ret}"
}

running_container_record() {
	"${DockerBin}" ps --no-trunc=true | awk '{print $1}' | sed '1 d' > ${RunningContainerList}
}

running_container_restore() {
	if [ -f ${RunningContainerList} ]; then
		list="$(cat "${RunningContainerList}")"
		if [ "x" != "x${list}" ]; then
			"${DockerBin}" start $(${ContainerDepBin} ${list})
		fi
		rm -f "${RunningContainerList}"
	fi
}

iptables_clear()
{
	eval $(iptables-save -t nat | grep DOCKER | sed -e 1d -e  's/^-A/iptables -t nat -D/' -e 's/DEFAULT_//' -e 's/$/;/')
	eval $(iptables-save -t filter | grep DOCKER | sed -e 1d -e  's/^-A/iptables -t filter -D/' -e 's/DEFAULT_//' -e 's/$/;/')

	iptables -t nat -X DOCKER
	iptables -t filter -X DOCKER
}

clean_lock_files() {
	rm /var/lock/dockerImage.lock /var/lock/dockerMapping.lock /var/lock/dockerRemoteAPI.lock*
}

umount_aufs() {
	for i in $(grep aufs/mnt /proc/mounts | sed 's@.*aufs/mnt/\(\w*\)@\1@'); do
		umount "${TargetPath}"/docker/aufs/mnt/$i
	done

	if grep -q @docker/aufs /proc/mounts; then
		umount "${TargetPath}"/docker/aufs
	fi
}

case "$1" in
	start)
		[ -d /usr/local/bin ] || mkdir -p /usr/local/bin
		ln -sf "${TargetPath}"/webapi/SYNO.Docker.lib "${WebapiLibLink}"
		ln -sf "${DockerBin}" "${DockerBinLink}"
		ln -sf "${HttpSysConf}" "${HttpSysLink}"
		cp "${ModProxyWstunnelBin}" "${ModProxyWstunnelLink}"
		reload httpd-sys

		# install modules
		iptablestool --insmod "${DockerServName}" ${InsertModules}

		#start docker
		"${DockerBin}" -d &

		wait_for_condition [ ! -f "${DockerPIDFile}" ]
		wait_for_condition ! "${DockerBin}" version

		pid="$(cat "${DockerPIDFile}")"
		if kill -0 "${pid}"; then
			running_container_restore
		else
			rm "${DockerPIDFile}"
			exit 1
		fi

		#start termd
		"$TermdBin" -d

		CreateHelpAndString
		exit 0
		;;

	stop)
		local modules="$(argument_reverse "${InsertModules}")"

		rm "${WebapiLibLink}"
		rm "${DockerBinLink}"
		rm "${HttpSysLink}"
		rm "${ModProxyWstunnelLink}"
		reload httpd-sys

		## Kill termd
		if [ -f "$TermdPIDFile" ]; then
			local termdPID=$(cat "$TermdPIDFile")
			kill "$termdPID"
			wait_for_condition kill -0 "$termdPID"

			## Force kill
			if kill -0 "$termdPID"; then
				kill -9 "$termdPID"
				rm "$TermdPIDFile"
				logger -p 0 "Failed to stop termd so we kill"
			fi
		fi

		## Record running container
		running_container_record

		## Kill docker
		if [ -f "$DockerPIDFile" ]; then
			local dockerPID="$(cat "${DockerPIDFile}")"

			kill "${dockerPID}"
			wait_for_condition kill -0 "${dockerPID}"

			## Force kill
			if kill -0 "${dockerPID}"; then
				kill -9 "${dockerPID}"
				rm "${DockerPIDFile}"
				logger -p 0 "Failed to stop docker so we kill"
			fi
		fi

		umount_aufs
		clean_lock_files
		iptables_clear

		iptablestool --rmmod "${DockerServName}" ${modules}

		RemoveHelpAndString
		exit 0
		;;

	status)
		[ -f "$DockerPIDFile" ] && kill -0 "$(cat "$DockerPIDFile")"
		;;

	*)
		exit 1
		;;
esac
