#!/bin/sh
# Wait until services in a runsvdir tier are up (or timeout).
# Usage: wait-tier <tier-name> [timeout_seconds]

set -e

tier=${1:?tier name required}
timeout=${2:-120}
dir=/etc/runit/runsvdir/$tier
needs=$dir/.needs
# Also accept non-dot name before postinst rename
[ -r "$needs" ] || needs=$dir/needs
start=$(date +%s)

[ -d "$dir" ] || exit 0

wait_for() {
	svc=$1
	# Skip if not installed or not linked into this wave / merged yet
	if [ ! -d "/etc/sv/$svc" ]; then
		echo "wait-tier: skip $svc (no /etc/sv/$svc)" >&2
		return 0
	fi
	if [ ! -e "$dir/$svc" ] && [ ! -e "/etc/runit/runsvdir/merged/$svc" ] \
		&& [ ! -e "/etc/service/$svc" ]; then
		echo "wait-tier: skip $svc (not in tier/merged/service)" >&2
		return 0
	fi
	while ! sv check "$svc" >/dev/null 2>&1; do
		[ $(($(date +%s) - start)) -ge "$timeout" ] && {
			echo "wait-tier: timeout waiting for $svc in tier $tier" >&2
			return 1
		}
		sleep 0.2
	done
	return 0
}

if [ -r "$needs" ]; then
	while read -r svc _rest; do
		case "$svc" in
		''|'#'*) continue ;;
		esac
		wait_for "$svc" || return 1
	done < "$needs"
else
	# Without .needs, do not block boot on every symlink in the tier
	# (cups, mdadm, haveged, …). List hard deps in .needs instead.
	return 0
fi

return 0
