#!/usr/bin/openrc-run

. /opt/etc/functions.openrc

# This service has to be added to the _sysinit_ level.
depend()
{
	after udev
	provide localmount root ${SVCNAME}
}

# Directory on NFS server with all overlays
OVERLAYS=${OVERLAYS-"../nodes"}
# Mount point for overlay for this node
OVERMOUNT=${OVERMOUNT-"/node"}
# Mount point for all overlays (not always used)
OVERSMOUNT=${OVERSMOUNT-"/nodes"}

kernelcmd_hostname()
{
	local _parm _hn
	for _parm in $(cat /proc/cmdline | grep "hostname="); do
		_hn=$(echo ${_parm} | grep "hostname=" | sed 's/hostname=//')
		[ -n "${_hn}" ] && break
	done
	echo ${_hn}
}

auto_hostname()
{
	local _id=$(ip addr | \
		grep 'inet ' | grep -v 127 | uniq | head -n 1 | \
		awk '{print $2;}' | sed -e 's/\./\-/g' -e 's/\/.*//')
	update_me
	if [ -n "${_id}" ]; then
		einfo "${ME}: using IP ${_id} as host fingerprint"
		hostname "host-${_id}"
		return
	fi
	_id=$(ip link | grep link/ether | uniq | head -n 1 | awk '{print $2;}' | sed 's/\://g')
	if [ -z "${_id}" ]; then
		ewarn "${ME}: no ethernet adapters found, this is weird!"
		hostname "weird"
	else
		einfo "${ME}: using ethernet MAC ${_id} as host fingerprint"
		hostname "host-${_id}"
	fi
}

set_hostname()
{
	local _hn=$(hostname)
	local _khn=$(kernelcmd_hostname)
	[ "${_hn}" = "localhost" -o "${_hn}" = "amnesiac" ] && _hn=""
	update_me
	if [ -n "${_khn}" ]; then
		if [ -n "${_hn}" ]; then
			einfo "${ME}: Valid hostname \"${_hn}\" was already set."
			einfo "${ME}: It will be overrided by \"${_khn}\" from kernel command line."
		fi
		hostname "${_khn}"
	else
		if [ -n "${_hn}" ]; then
			einfo "${ME}: hostname \"${_hn}\" is already set."
		else
			auto_hostname
		fi
	fi
	eend 0
}

ensure_clean_mountpoint()
{
	local _d=$1 _suffix=$2 _rd
	if ! [ -e ${_d} ]; then
		mkdir -p ${_d}
		return
	fi
	[ -d ${_d} -a $(find ${_d} | wc -l) -eq 1 ] && return 0
	_rd="${_d}.${_suffix}"
	update_me
	ewarn "${ME}: object \"${_d}\" is already exists and is not an empty directory; renaming to \"${_rd}\""
	mv "${_d}" "${_rd}" && mkdir -p ${_d}
}

VARDIRS=" \
	tmp games empty opt db \
	lib/dhcpcd lib/xkb lib/nfs lib/nfs/rpc_pipefs lib/alsa lib/rpcbind \
	lib/dbus lib/syslog-ng lib/colord/icc \
	lib/pacemaker/blackbox lib/pacemaker/pengine lib/pacemaker/cores \
	lib/pacemaker/cib lib/misc lib/corosync \
	lib/dhclient lib/ceph lib/ceph/tmp \
	lib/gssproxy/clients \
	lib/samba/private \
	lib/ntp \
	cache/fontconfig cache/openafs cache/ldconfig \
	cache/libvirt/qemu \
	cache/opensm cache/pkgfile cache/man cache/pacman/pkg \
	cache/cups/rss cache/samba cache/xdg-menu \
	log \
	"

mount_overlay()
{
	local _r=$(mount | grep ' / ' | awk '{print $1;}')
	local _srv=$(echo ${_r} | sed 's/\:.*//')
	local _rootpath=$(echo ${_r} | sed 's/.*\://')
	set_hostname
	local _hostname=$(hostname)
	local _overpath=$(follow_path "${_rootpath}" $OVERLAYS)
	local _myover="${_overpath}/${_hostname}"
	local _random_suffix=$(uuidgen)
	# The code always works correctly only with writeable root.
	# If the prerequisites are met, than the root can also be RO.
	# ${OVERSMOUNT} always should be RW.
	ensure_clean_mountpoint "${OVERMOUNT}" "${_random_suffix}" || return 1
	ensure_clean_mountpoint "${OVERSMOUNT}" "${_random_suffix}" || return 1
	ensure_clean_mountpoint "/var" "${_random_suffix}" || return 1
	if showmount -e ${_srv} | grep "^${_myover}" > /dev/null 2>&1; then
		update_me
		einfo "${ME}: overlay for this node \"${_hostname}\" is exported explicitly"
		${MOUNT_NFS} "${_srv}:${_myover}" "${OVERMOUNT}" || return 1
		einfo "${ME}: mounted overlay \"${_srv}:${_myover}\" at \"${OVERMOUNT}\""
		mount --bind "${OVERMOUNT}/var" /var || return 1
		einfo "${ME}: \"/var\" is in place."
		return 0
	else
		if ! showmount -e ${_srv} | grep "^${overpath}" > /dev/null 2>&1; then
			update_me
			eerror "${ME}: overlay root \"${_overpath}\" is not exported from \"${_srv}\""
			return 1
		fi
		${MOUNT_NFS} "${_srv}:${_overpath}" "${OVERSMOUNT}" || return 1
		update_me
		_myover="${OVERSMOUNT}/${_hostname}"
		if ! [ -d ${_myover} ]; then
			ewarn "${ME}: directory \"${_myover}\" is not found on server \"${_srv}\", creating new overlay \"${_myover}\""
			mkdir "${_myover}" || return 1
			tar zxvf "${OVERSMOUNT}/etc.tar.gz" -C "${_myover}"
			for _dir in ${VARDIRS}; do
				mkdir -p "${_myover}/var/${_dir}"
			done
			ln -s /run/lock "${_myover}/var/lock"
			ln -s /run "${_myover}/var/run"
			ln -s /opt/glswitch/altroot-nvidia "${_myover}/var/altroot"
			tar zxvf "${OVERSMOUNT}/guest.tar.gz" -C "${_myover}/var"
		else
			einfo "${ME}: found overlay \"${_myover}\" on server \"${_srv}\""
		fi
		mount --bind "${_myover}" "${OVERMOUNT}" || return 1
		einfo "${ME}: \"${OVERMOUNT}\" is in place."
		mount --bind "${OVERMOUNT}/var" /var || return 1
		einfo "${ME}: \"/var\" is in place."
	fi
	return 0
}

start()
{
	local _rc=1
	ebegin "Starting service \"${SVCNAME}\""
	mount_overlay
	eend $?
}

stop()
{
	eend 0
}
