+# generate initrd/initramfs {{{
+initrd() {
+ # assume the first available kernel as our main kernel
+ # shellcheck disable=SC2012
+ KERNELIMG=$(ls -1 /boot/vmlinuz-* 2>/dev/null | head -1)
+ if [ -z "$KERNELIMG" ] ; then
+ echo 'No kernel image found, skipping initrd stuff.'>&2
+ return
+ fi
+
+ KERNELVER=${KERNELIMG#/boot/vmlinuz-}
+
+ # generate initrd
+ if [ -n "$INITRD" ] ; then
+ echo "Generating initrd."
+ if [ "$INITRD_GENERATOR" = 'dracut' ] ; then
+ DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL dracut
+ dracut --no-hostonly --kver "$KERNELVER" --fstab --add-fstab /etc/fstab --force --reproducible $INITRD_GENERATOR_OPTS
+ else
+ update-initramfs -c -t -k "$KERNELVER" $INITRD_GENERATOR_OPTS
+ fi
+ fi
+}
+# }}}
+
+efi_setup() {
+ if [ -z "$EFI" ] ; then
+ return 0
+ fi
+
+ if ! dpkg --list efibootmgr 2>/dev/null | grep -q '^ii' ; then
+ echo "Notice: efi option set but no efibootmgr package, installing it therefore."
+ DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL efibootmgr
+ fi
+
+ mkdir -p /boot/efi
+ echo "Mounting $EFI on /boot/efi"
+ mount "$EFI" /boot/efi || return 1
+
+ # if efivarfs kernel module is loaded, but efivars isn't,
+ # then we need to mount efivarfs for efibootmgr usage
+ if ! ls /sys/firmware/efi/efivars/* &>/dev/null ; then
+ echo "Mounting efivarfs on /sys/firmware/efi/efivars"
+ mount -t efivarfs efivarfs /sys/firmware/efi/efivars
+ fi
+
+ echo "Invoking efibootmgr"
+ efibootmgr || return 1
+}
+
+# grub configuration/installation {{{
+
+# helper function to get relevant /dev/disk/by-id/* entries,
+# based on GRUB's postinst script
+available_ids() {
+ local path ids
+
+ [ -d /dev/disk/by-id ] || return
+ ids="$(
+ for path in /dev/disk/by-id/*; do
+ [ -e "${path}" ] || continue
+ printf '%s %s\n' "${path}" "$(readlink -f "${path}")"
+ done | sort -k2 -s -u | cut -d' ' -f1
+ )"
+ echo "${ids}"
+}
+
+# helper function to report corresponding /dev/disk/by-id/ for a given device name,
+# based on GRUB's postinst script
+device_to_id() {
+ local id
+
+ for id in $(available_ids); do
+ if [ "$(readlink -f "${id}")" = "$(readlink -f "$1")" ]; then
+ echo "${id}"
+ return 0
+ fi
+ done
+
+ # Fall back to the plain device name if there's no by-id link for it.
+ if [ -e "$1" ]; then
+ echo "$1"
+ return 0
+ fi
+ return 1
+}
+
+grub_install() {
+
+ if [ -z "$GRUB" ] ; then
+ echo "Notice: \$GRUB not defined, will not install grub inside chroot at this stage."
+ return 0
+ fi
+
+ efi_setup || return 1
+
+ if [ -n "$EFI" ] ; then
+ GRUB_PACKAGE=grub-efi-amd64
+ else
+ GRUB_PACKAGE=grub-pc
+ fi
+
+ # make sure this is pre-defined so we have sane settings for automated
+ # upgrades, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=711019
+ local grub_device
+ grub_device=$(device_to_id "${GRUB}")
+ if [ -z "${grub_device:-}" ] ; then
+ echo "Warning: Could not identify /dev/disk/by-id/... for '${GRUB}', falling back to '${GRUB}'"
+ grub_device="${GRUB}"
+ fi
+
+ echo "Setting ${GRUB_PACKAGE} debconf configuration for install device to $GRUB"
+ echo "${GRUB_PACKAGE} ${GRUB_PACKAGE}/install_devices multiselect ${grub_device}" | debconf-set-selections
+
+ if ! dpkg --list ${GRUB_PACKAGE} 2>/dev/null | grep -q '^ii' ; then
+ echo "Notice: grub option set but no ${GRUB_PACKAGE} package, installing it therefore."
+ DEBIAN_FRONTEND=$DEBIAN_FRONTEND $APTINSTALL ${GRUB_PACKAGE}
+ fi
+
+ if ! [ -x "$(command -v grub-install)" ] ; then
+ echo "Error: grub-install not available. (Error while installing grub package?)" >&2
+ return 1
+ fi
+ if ! [ -x "$(command -v update-grub)" ] ; then
+ echo "Error: update-grub not available. (Error while installing grub package?)" >&2
+ return 1
+ fi
+
+ if [ -n "$SELECTED_PARTITIONS" ] ; then # using sw-raid
+ for device in $SELECTED_PARTITIONS ; do
+ GRUB="${device%%[0-9]}"
+ echo "Installing grub on ${GRUB}:"
+ if ! grub-install --no-floppy "$GRUB" ; then
+ echo "Error: failed to execute 'grub-install --no-floppy $GRUB'." >&2
+ exit 1
+ fi
+
+ done
+ rm -f /boot/grub/device.map
+ else
+ echo "Installing grub on ${GRUB}:"
+ echo "(hd0) ${GRUB}" > /boot/grub/device.map
+ if ! grub-install "(hd0)" ; then
+ echo "Error: failed to execute 'grub-install (hd0)'." >&2
+ exit 1
+ fi
+ rm /boot/grub/device.map
+ fi
+
+ echo "Adjusting grub configuration for use on ${GRUB}."
+
+ if [ -n "${BOOT_APPEND}" ] ; then
+ echo "Adding BOOT_APPEND configuration ['${BOOT_APPEND}'] to /etc/default/grub."
+ sed -i "/GRUB_CMDLINE_LINUX_DEFAULT/ s#\"\$# ${BOOT_APPEND}\"#" /etc/default/grub
+ fi
+
+ mountpoint /boot/efi &>/dev/null && umount /boot/efi
+
+ # finally install grub. Existence of update-grub is checked above.
+ update-grub
+}
+# }}}
+
+# execute all scripts present in /etc/debootstrap/chroot-scripts/ {{{
+custom_scripts() {
+ [ -d /etc/debootstrap/chroot-scripts/ ] || return 0
+
+ for script in /etc/debootstrap/chroot-scripts/* ; do
+ echo "Executing script $script"
+ $script && echo "done" || echo "failed"
+ done
+}
+# }}}
+
+# make sure we don't have any running processes left {{{
+services() {
+ for service in ssh mdadm mdadm-raid ; do
+ if [ -x /etc/init.d/"$service" ] ; then
+ /etc/init.d/"$service" stop || true
+ fi
+ done
+}
+# }}}
+
+# unmount /proc and make sure nothing is left {{{
+finalize() {
+ # make sure we don't leave any sensible data
+ rm -f /etc/debootstrap/variables
+
+ [ -n "$POLICYRCD" ] && rm -f /usr/sbin/policy-rc.d
+
+ umount /sys/firmware/efi/efivars &>/dev/null || true
+
+ umount /sys >/dev/null 2>/dev/null || true
+ umount /proc >/dev/null 2>/dev/null || true
+}
+# }}}
+
+# signal handler {{{
+signal_handler() {
+ finalize
+ [ -n "$1" ] && EXIT="$1" || EXIT="1"
+ exit "$EXIT"
+}
+# }}}
+
+# set signal handler {{{
+trap signal_handler HUP INT QUIT TERM
+# }}}
+
+# execute the functions {{{