#!/bin/bash -e

. $(dirname $0)/mbd-common.sh
. "${MBD_BLDCONFIGFILE}"

mbd_opt_init "Mini-buildd: Auto-setup lvm w/ loop device (root only)."
mbd_opt_add "f" "Force fresh setup (i.e., delete existing setup first)."
mbd_opt_add "d" "Delete existing setup."
mbd_opt_add "a" "Only (re-)attach loop device (needed on system startup before lvm)."
mbd_opt_parse "$@"

mbdCheckUser root

if ${mbd_defer}; then
	${MBD_LOG} -s "W: Configuration deferred, skipping."
	exit 0
fi

if [ "${mbd_lvm_vg}" != "auto" ]; then
	${MBD_LOG} -s "I: Skipping: Using custom lvm volume group \"$(mbdLvmVgName)\"."
	exit 0
fi

MBD_SETUPLVM_VGNAME=$(mbdLvmVgName)
MBD_SETUPLVM_IMGFILE="${MBD_HOME}/bld/chroots/lvm.image"
MBD_SETUPLVM_IMGDEVICEFILE="${MBD_HOME}/bld/chroots/lvm.device"
MBD_SETUPLVM_GIGS="100"

mbdGetLoopdev()
{
	# @hack: This just works as long as losetup's output does not change.
	MBD_SETUPLVM_LOOPDEV=$(cat ${MBD_SETUPLVM_IMGDEVICEFILE} 2>/dev/null | rev | cut -f1 -d" " | rev)

	if losetup "${MBD_SETUPLVM_LOOPDEV}" 2>/dev/null | grep -q "${MBD_SETUPLVM_IMGFILE}"; then
		${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: \"${MBD_SETUPLVM_LOOPDEV}\" attached to \"${MBD_SETUPLVM_IMGFILE}\"."
		return 0
	else
		${MBD_LOG} -s "W: VG ${MBD_SETUPLVM_VGNAME}: \"${MBD_SETUPLVM_LOOPDEV}\" not attached to ${MBD_SETUPLVM_IMGFILE}"
		MBD_SETUPLVM_LOOPDEV=""
		return 1
	fi
}

if mbd_opt_given a; then
	if ! mbdGetLoopdev; then
		${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Reattaching image: $(losetup -v -f ${MBD_SETUPLVM_IMGFILE} | tee "${MBD_SETUPLVM_IMGDEVICEFILE}" 2>&1)"
		${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Updating lvm2: $(vgchange --available y ${MBD_SETUPLVM_VGNAME} 2>&1)"
	fi
	exit 0
fi

mbdGetLoopdev || true

if mbd_opt_given f || mbd_opt_given d; then
	${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Forcing lv removal: $(lvremove --force "${MBD_SETUPLVM_VGNAME}" 2>&1)"
	${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Forcing vg removal: $(vgremove "${MBD_SETUPLVM_VGNAME}" 2>&1)"
	[ -z "${MBD_SETUPLVM_LOOPDEV}" ] || ${MBD_LOG} -s "I: PV ${MBD_SETUPLVM_LOOPDEV}: Forcing pv removal: $(pvremove "${MBD_SETUPLVM_VGNAME}" 2>&1)"
	[ -z "${MBD_SETUPLVM_LOOPDEV}" ] || ${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Forcing ${MBD_SETUPLVM_LOOPDEV} unattach: $(losetup -d "${MBD_SETUPLVM_LOOPDEV}" 2>&1)"
	${MBD_LOG} -s "I: VG ${MBD_SETUPLVM_VGNAME}: Forcing image removal: $(rm -f -v "${MBD_SETUPLVM_IMGFILE}" "${MBD_SETUPLVM_IMGDEVICEFILE}" 2>&1)"
	if mbd_opt_given d; then
		exit 0
	fi
fi

if [ -e "${MBD_SETUPLVM_IMGFILE}" ]; then
	${MBD_LOG} -s "I: Not touching existing \"${MBD_SETUPLVM_IMGFILE}\"."
else
	# On initial installs, we may be called before mbd-update-rep
	# I.e., we need to make sure the chroots directory exists, although it mbd-u-r's job
	su mini-buildd -c "mkdir -p ${MBD_HOME}/bld/chroots"

	(
		echo "I: Setting up lvm ${MBD_SETUPLVM_VGNAME} on ${MBD_SETUPLVM_LOOPDEV}..."
		if (dd if=/dev/zero of="${MBD_SETUPLVM_IMGFILE}" bs=${MBD_SETUPLVM_GIGS}M seek=1024 count=0 &&
				losetup -v -f ${MBD_SETUPLVM_IMGFILE} >"${MBD_SETUPLVM_IMGDEVICEFILE}" &&
				mbdGetLoopdev &&
				pvcreate -v ${MBD_SETUPLVM_LOOPDEV} &&
				vgcreate -v ${MBD_SETUPLVM_VGNAME} ${MBD_SETUPLVM_LOOPDEV}); then
			echo "I: VG ${MBD_SETUPLVM_VGNAME} created successfully on ${MBD_SETUPLVM_LOOPDEV}."
		else
			echo "E: FAILED to create VG ${MBD_SETUPLVM_VGNAME}; rerun \"${0} -f\" as root any time to retry."
		fi
	) 2>&1 | ${MBD_LOG} -s
fi
