#!/bin/sh
### BEGIN INIT INFO
# Provides:            netboot
# Required-Start:      cmdline mountfs modules udev
# Should-Start:        $syslog
# Required-Stop:
# Should-Stop:
# Default-Start:       3 4 5
# Default-Stop:
# X-Start-Before:      ueventd
# Short-Description:   Process netboot parameters.
# Description:         Processing netboot parameters.
### END INIT INFO

. shell-error
. /etc/init.d/template
. /.initrd/initenv

start() {
	[ -d /dev/fd ] || ln -snf /proc/self/fd /dev/fd
	[ -e /dev/stdin ] || ln -snf /proc/self/fd/0 /dev/stdin
	[ -e /dev/stdout ] || ln -snf /proc/self/fd/1 /dev/stdout
	[ -e /dev/stderr ] || ln -snf /proc/self/fd/2 /dev/stderr

	[ -n "$netboot_fs_size" ] || netboot_fs_size=1G

	message "netboot: netboot_url=$netboot_url, netboot_fs_size=$netboot_fs_size, netboot_log=$netboot_log"
	[ -n "$netboot_url" ] ||
		fatal '$netboot_url is empty'

	ip addr list

	mount -t tmpfs -o mode=0755,size="$netboot_fs_size" tmpfs /root

	fetch_rootfs()
	{
		local file url
		file="$1"; shift
		url="$netboot_url/$file"
		message "netboot: fetching $url"
		curl -sS -P- "$url" | tar -x --zstd -C /root || {
			message "netboot: failed to fetch $url"
			return 1
		}
	}

	mkdir -p /var/lib/dhcpcd
	try=0
	a=
	while :; do
		try=$(($try+1))
		message "netboot: trying to get host info by DHCP, attempt #$try"
		for i in $(ls /sys/class/net/); do
			case "$i" in
				lo*) continue ;;
			esac

			message "netboot: probing interface $i"
			ip link set "$i" up

			ip addr list dev "$i" | grep -Fq 'NO-CARRIER' ||
			dhcpcd -4 -p -w -t 1 -e force_hostname=YES "$i" ||
				continue

			for a in $(ip addr list dev "$i" |
				   sed -n 's,^[[:space:]]\+inet[[:space:]]\+\([.:[:xdigit:]]\+/[[:digit:]]\+\)[[:space:]].*,\1,p'); do
				case "$a" in
					127.*) continue ;;
				esac
				fetch_rootfs "rootfs-common-${a%/*}.tar.zst" &&
				fetch_rootfs "rootfs-addon-${a%/*}.tar.zst" &&
					break 3 ||:
			done
		done
		sleep 1
	done

	message "netboot: configuring address $a on interface $i"
	mkdir -p /root/etc/net/ifaces/"$i"
	cat > /root/etc/net/ifaces/"$i"/options <<'EOF'
TYPE=eth
BOOTPROTO=static
ONBOOT=yes
EOF

	echo "$a" > /root/etc/net/ifaces/"$i"/ipv4address
	ip route list dev "$i" |
	sed -n 's/^\(default via [^[:space:]]\+\)[[:space:]].*/\1/p' \
		> /root/etc/net/ifaces/"$i"/ipv4route

	dhcpcd -4 -U "$i" |
		sed -E "s/^([^='\"]*=)([^'\"].*)/\1'\2'/" > /root/etc/net/ifaces/"$i"/lease ||:

	(
		host_name=
		domain_name=
		domain_name_servers=
		domain_search=
		ntp_servers=

		. /root/etc/net/ifaces/"$i"/lease

		[ -z "$host_name" ] ||
			sed -i "s/^\\(HOSTNAME\\)=.*/\\1=$host_name/" \
				/root/etc/sysconfig/network

		if [ -n "$ntp_servers" ]; then
			printf 'server %s iburst\n' $ntp_servers > /root/etc/chrony.conf

			chronyd -q -f /root/etc/chrony.conf
			hwclock --systohc
		fi

		{
			[ -z "$domain_name" ] ||
				echo "domain $domain_name"
			[ -z "$domain_search" ] ||
				echo "search $domain_search"
			for dns in $domain_name_servers; do
				echo "nameserver $dns"
			done
		} > /root/etc/resolv.conf
	)

	for i in $(ls /sys/class/net/); do
		case "$i" in
			lo*) continue ;;
		esac
		ip link set "$i" down
	done

	if [ -n "$netboot_log" ]; then
		echo "*.*      $netboot_log" > /root/etc/syslog.conf
	fi

	size=$( df -B1048576 /root |sed -n 's/^tmpfs \+[1-9][0-9]* \+\([1-9][0-9]*\) .*/\1/p')
	size=$(($size*2))
	message "netboot: remounting root to size ${size}M"
	mount -oremount,size=${size}M /root
}

stop() {
	return 0
}

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	*)
		msg_usage "${0##*/} {start|stop}"
		RETVAL=1
esac
