#!/bin/sh -efu

. pipeline-sh-functions

check_parameter STATELESS_IMAGES

parts=
name=
path=
parse_layer() {
	name="${parts%%[,|]*}"
	path="$(resolve_target "$name")"
	parts="${parts#"$name"}"
	parts="${parts#[,|]}"
}

mode="$(get_parameter STATELESS_MODE)"
parts="$(get_parameter STATELESS_IMAGES)"
init_size="$(get_parameter STATELESS_INIT_SIZE)"
size_mult="$(get_parameter STATELESS_SIZE_MULT)"

[ -n "$init_size" ] ||
	init_size=2G

if [ -n "$size_mult" ]; then
	if [ -z "${size_mult%%*%}" ]; then
		size_mult="${size_mult%[%]}"
	else
		size_mult="$(($size_mult*100))"
	fi
else
	# default to 30% of free space.
	size_mult=130
fi

[ "$size_mult" -gt 100 ] ||
	size_mult=0

rw_mount=
# In overlay mode first layer is a read-only filesystem image (e.g. squashfs).
if [ "$mode" = overlay ]; then
	[ "$size_mult" = 0 ] ||
		size_mult="$((size_mult - 100))"

	parse_layer

	mkdir -p "$datadir"/ro "$datadir"/rw

	if [ -s "$path" ]; then
		message "stateless: mounting $name image"
		run mount -o ro "$path" "$datadir"/ro
	else
		fatal "$path does not exist"
	fi

	mount -t tmpfs -o rw,mode=0755,size="$init_size" \
		tmpfs "$datadir"/rw
	rw_mount="$datadir"/rw

	mkdir -p "$datadir"/rw/fs "$datadir"/rw/work

	run mount -t overlay \
		-o "lowerdir=$datadir/ro,upperdir=$datadir/rw/fs,workdir=$datadir/rw/work" \
		overlay "$destdir"
else
	run mount -t tmpfs -o rw,mode=0755,size="$init_size" tmpfs "$destdir"
	rw_mount="$destdir"
fi

while [ -n "$parts" ]; do
	parse_layer

	if [ -s "$path" ]; then
		if [ -s "$destdir"/etc/passwd ]; then
			install -m644 -o0 -g0 "$destdir"/etc/passwd /etc/passwd
		fi
		if [ -s "$destdir"/etc/group ]; then
			install -m644 -o0 -g0 "$destdir"/etc/group /etc/group
		fi
		message "stateless: unpacking $name image"
		tar -x --preserve-permissions --xattrs --xattrs-include=*.* \
			-f "$path" -C "$destdir"
	else
		fatal "$path does not exist"
	fi
done

if [ "$size_mult" -gt 0 ]; then
	size="$(du -sm "$destdir")"
	size="${size%%[[:space:]]*}"
	size="$((size * size_mult / 100))"
	size="${size%.*}"
	message "stateless: remounting root to size ${size}M"
	mount -oremount,size="$size"M "$rw_mount"
fi

if [ "$mode" != overlay ]; then
	majmin="$(mountpoint -d "$prevdir")"
	message "stateless: unmounting host filesystem"
	umount "$prevdir"
	dev=/sys/dev/block/"$majmin"
	if [ -s "$dev"/dm/uuid ]; then
		uuid="$(cat "$dev"/dm/uuid)"
		name="$(cat "$dev"/dm/name)"
		case "$uuid" in
			CRYPT-LUKS*)
				message "stateless: stopping LUKS device $name"
				run cryptsetup close "$name"
				;;
		esac
	fi
fi

message "stateless: success"
