#!/usr/bin/sh
set -eu

if [ $# -ne 2 ]
  then
    echo "Missing argument"
    echo "Usage: script.sh GRUB_HOME EFI_HOME"
    exit 1
fi

GRUB_HOME=$1
EFI_HOME=$2

# create a stub grub2 config in EFI
# Unlike the UUID below, this path has no fallback: every line of the stub is
# built from it, so a wrong value yields a stub that cannot boot on any EFI
# image, which is worse than leaving the previous one in place.  Bail out
# rather than guess.  An empty result is not a failure, it means GRUB_HOME is
# itself a mount point, in which case the paths below correctly become ($dev)
# and /grub.cfg.
GRUB_DIR=$(grub2-mkrelpath "${GRUB_HOME}") || {
    echo "grub2-mkrelpath failed for ${GRUB_HOME}, not guessing the stub path" >&2
    exit 1
}
case "${GRUB_DIR}" in
    "" | /*) ;;
    *)
	echo "grub2-mkrelpath returned '${GRUB_DIR}', which is not an absolute path" >&2
	exit 1
	;;
esac

# A failing probe must not abort the script: the stub below also searches by
# file name, so it stays usable without the UUID, whereas aborting would leave
# whatever the previous release wrote on the ESP in place -- including the
# search --root-dev-only stub that older EFI images cannot parse.  Discard
# anything that is not a bare UUID so that a diagnostic printed on stdout
# cannot end up as a command in the generated stub.
BOOT_UUID=$(grub2-probe --target=fs_uuid "${GRUB_HOME}" 2>/dev/null) || BOOT_UUID=
case "${BOOT_UUID}" in
    "" | *[!0-9A-Fa-f-]*) BOOT_UUID= ;;
esac

if [ -n "${BOOT_UUID}" ]; then
  UUID_SEARCH="search --no-floppy --set=dev --fs-uuid ${BOOT_UUID}"
else
  UUID_SEARCH="# no filesystem UUID was available when this stub was generated"
fi

echo "Generating grub stub config for drive " "${BOOT_UUID}"
echo "GRUB_DIR=" "${GRUB_DIR}"
echo "EFI_HOME=" "${EFI_HOME}"

trap 'rm -f "${EFI_HOME}"/grub.cfg.stb' EXIT

# This stub is read by whichever EFI image the firmware happens to load, which
# is not necessarily the one this package just installed: on several platforms
# the firmware boots \EFI\BOOT\BOOT<ARCH>.EFI, which is placed by the installer
# and never upgraded.  It must therefore stick to options that have always
# existed upstream, and must not rely on the recorded UUID still being correct,
# because an image rebuild gives the root filesystem a new one.
cat << EOF > "${EFI_HOME}"/grub.cfg.stb
# gen_grub_cfgstub v2 - generated file, do not edit
set dev=
${UUID_SEARCH}
if [ -z "\${dev}" ]; then
  search --no-floppy --set=dev --file ${GRUB_DIR}/grub.cfg
fi
set prefix=(\$dev)${GRUB_DIR}
export prefix
configfile \$prefix/grub.cfg
EOF

# Only replace a working stub once the new one is known to be complete, so a
# truncated write (full ESP, for one) cannot leave the machine unbootable.
if ! grep -q "^configfile " "${EFI_HOME}"/grub.cfg.stb; then
    echo "Refusing to install an incomplete grub stub config" >&2
    exit 1
fi

mv "${EFI_HOME}"/grub.cfg.stb "${EFI_HOME}"/grub.cfg
