#!/usr/bin/env bash
#
# bootc-install-external-disk.sh
#
# Partitioniert eine externe Platte und installiert anschließend ein
# bootc-Image via `bootc install to-filesystem`.
#
# Unterstuetzt zwei Boot-Modi:
#   - UEFI/GPT: EFI System Partition (vfat) + Boot-Partition (ext4) + LUKS2-Root (xfs)
#   - BIOS/MBR: Boot-Partition (ext4, bootable) + LUKS2-Root (xfs), GRUB im MBR-Gap
#
# Fedora/RHEL 10: verwendet sfdisk (util-linux, immer vorhanden) statt sgdisk.
# Die Zielplatte, der Boot-Modus und das bootc-Image werden beim Ausfuehren
# interaktiv abgefragt.
#
# WICHTIG - vorher lesen:
# - Das Zielgerät wird KOMPLETT gelöscht. Genau prüfen, bevor du bestätigst!
# - Muss als root laufen, podman muss installiert sein.
# - Das bootc-Image muss LUKS-Root beim Booten unterstuetzen: das initramfs im Image
#   braucht das dracut "crypt" Modul (bzw. bei Fedora/CentOS bootc ist das i.d.R. vorhanden).
# - BIOS/MBR-Modus: das Image braucht grub2-install (Paket grub2-pc) fuer Legacy-Boot;
#   bootc/bootupd installieren im Auto-Modus IMMER auch eine EFI-Komponente und
#   brechen ohne ESP hart ab, daher wird bootc dort per --bootloader none komplett
#   uebersprungen und GRUB fuer BIOS/MBR am Ende per chroot manuell installiert.
#
set -euo pipefail

### ---- Aufraeum- und Fehlerbehandlung ------------------------------------
# Sorgt dafuer, dass bei JEDEM Abbruch (Fehler, Strg+C, belegtes Geraet, ...)
# offene Mounts und LUKS-Mappings sauber geschlossen werden, statt das
# System in einem halb-gemounteten Zustand zuruecklassen.
CLEANUP_DONE=0
LUKS_NAME=""   # wird spaeter gesetzt; leer = "noch nichts geoeffnet"
CHROOT_MOUNTS=()   # Stack zusaetzlicher Bind-Mounts (z.B. fuer den ostree-Chroot),
                   # wird von cleanup() in umgekehrter Reihenfolge ausgehaengt

# Bind-mountet $1 nach $2 und merkt sich das fuer die spaetere Bereinigung
bind_mount() {
  local src="$1" dst="$2"
  mkdir -p "$dst"
  mount --bind "$src" "$dst"
  CHROOT_MOUNTS+=("$dst")
}

# Haengt alle per bind_mount gemerkten Mounts in umgekehrter Reihenfolge aus
unmount_chroot_binds() {
  local i m
  for (( i=${#CHROOT_MOUNTS[@]}-1; i>=0; i-- )); do
    m="${CHROOT_MOUNTS[i]}"
    if mountpoint -q "$m" 2>/dev/null; then
      umount "$m" 2>/dev/null || umount -lf "$m" 2>/dev/null
    fi
  done
  CHROOT_MOUNTS=()
}

cleanup() {
  [[ "$CLEANUP_DONE" -eq 1 ]] && return
  CLEANUP_DONE=1
  set +e

  # Erst pruefen, ob ueberhaupt noch etwas offen ist, bevor wir etwas ausgeben
  local something_open=0
  [[ ${#CHROOT_MOUNTS[@]} -gt 0 ]] && something_open=1
  for m in "${MOUNT_ROOT}/boot/efi" "${MOUNT_ROOT}/boot" "${MOUNT_ROOT}"; do
    mountpoint -q "$m" 2>/dev/null && something_open=1
  done
  [[ -n "$LUKS_NAME" && -e "/dev/mapper/${LUKS_NAME}" ]] && something_open=1
  [[ "$something_open" -eq 0 ]] && { set -e; return; }

  echo
  echo "### Raeume auf (Mounts/LUKS werden geschlossen)..."
  unmount_chroot_binds
  for m in "${MOUNT_ROOT}/boot/efi" "${MOUNT_ROOT}/boot" "${MOUNT_ROOT}"; do
    if mountpoint -q "$m" 2>/dev/null; then
      umount -R "$m" 2>/dev/null || umount -lf "$m" 2>/dev/null
    fi
  done
  if [[ -n "$LUKS_NAME" ]] && [[ -e "/dev/mapper/${LUKS_NAME}" ]]; then
    cryptsetup close "$LUKS_NAME" 2>/dev/null
  fi
  set -e
}

on_error() {
  local exit_code=$1 line=$2
  echo >&2
  echo "### FEHLER: Skript abgebrochen in Zeile $line (Exit-Code $exit_code)." >&2
  cleanup
  echo "### Aufraeumen abgeschlossen - Geraet und LUKS-Mapping sind wieder frei." >&2
  echo "### Ursache pruefen und Skript bei Bedarf erneut starten." >&2
}

trap 'on_error $? $LINENO' ERR
trap cleanup EXIT

### ---- Konfiguration: HIER ANPASSEN ----------------------------------
EFI_SIZE="629MiB"
BOOT_SIZE="2100MiB"             # ~2,1 GB
LUKS_NAME_BASE="croot"           # Basis-Name; bekommt unten eine zufaellige UUID angehaengt,
                                  # damit /dev/mapper/$LUKS_NAME garantiert eindeutig ist
MOUNT_ROOT="/mnt/bootc-target"
### ----------------------------------------------------------------------

# Automatisch mit root-Rechten neu starten, falls noetig
if [[ $EUID -ne 0 ]]; then
  if command -v sudo >/dev/null 2>&1; then
    echo "Nicht als root gestartet - starte neu mit sudo..."
    exec sudo -E -- "$0" "$@"
  else
    echo "Bitte als root ausfuehren (sudo wurde nicht gefunden)." >&2
    exit 1
  fi
fi

cat <<'BANNER'
╔══════════════════════════════════════════════════════════════════╗
║               bootc-installations-helfer.sh                     ║
║                                                                    ║
║  Installiert ein bootc-Image von Red Rat Linux auf eine       ║
║  externe Platte mit LUKS2-verschluesselter Root-Partition.        ║
║  Unterstuetzt UEFI/GPT- und BIOS/MBR-Boot.                        ║
║                                                                    ║
║  ACHTUNG: Die gewaehlte Zielplatte wird dabei komplett gelöscht!  ║
╚══════════════════════════════════════════════════════════════════╝
BANNER
echo

for cmd in sfdisk mkfs.vfat mkfs.ext4 mkfs.xfs cryptsetup podman blkid; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "Benoetigtes Programm '$cmd' wurde nicht gefunden. Bitte installieren." >&2
    exit 1
  fi
done

# --- 0a. Boot-Modus auswaehlen -------------------------------------------
echo "### Boot-Modus auswaehlen:"
echo "  1) UEFI / GPT (Standard)"
echo "  2) BIOS / MBR (Legacy)"
read -rp "Auswahl [1-2]: " boot_choice
case "$boot_choice" in
  1) BOOT_MODE="uefi" ;;
  2) BOOT_MODE="bios" ;;
  *) echo "Ungueltige Auswahl." >&2; exit 1 ;;
esac

# --- 0b. bootc-Image auswaehlen ------------------------------------------
echo
echo "### bootc-Image auswaehlen:"
echo "  1) quay.io/johnjaymckaye/red-rat-enterprise-linux:latest"
echo "  2) quay.io/johnjaymckaye/red-rat-linux:latest"
echo "  3) Eigenes Image angeben"
read -rp "Auswahl [1-3]: " image_choice
case "$image_choice" in
  1) IMAGE="quay.io/johnjaymckaye/red-rat-enterprise-linux:latest" ;;
  2) IMAGE="quay.io/johnjaymckaye/red-rat-linux:latest" ;;
  3) read -rp "Image-Referenz eingeben (z.B. quay.io/org/name:tag): " IMAGE
     [[ -n "$IMAGE" ]] || { echo "Keine Image-Referenz eingegeben." >&2; exit 1; } ;;
  *) echo "Ungueltige Auswahl." >&2; exit 1 ;;
esac

# --- 0c. Zielplatte interaktiv auswaehlen --------------------------------
echo
echo "### Verfuegbare Datentraeger:"
lsblk -d -o NAME,SIZE,MODEL,TRAN | grep -Ev '^(loop|sr)'
echo
read -rp "Geraetename der Zielplatte eingeben (z.B. sdb, ohne /dev/): " DISK_NAME
DISK="/dev/${DISK_NAME}"

if [[ ! -b "$DISK" ]]; then
  echo "Fehler: $DISK ist kein Blockgeraet." >&2
  exit 1
fi

if [[ "$DISK" == "/dev/sda" || "$DISK" == "/dev/nvme0n1" ]]; then
  echo "Achtung: $DISK sieht nach der System-/Hauptplatte aus."
  read -rp "Wirklich fortfahren? ('yes' zum Bestaetigen): " confirm_main
  [[ "$confirm_main" == "yes" ]] || exit 1
fi

# --- 0c-2. Pruefen ob die Zielplatte noch "belegt" ist -------------------
# Deckt die typischen Faelle ab, die sonst spaeter zu einem stillen Abbruch
# bei sfdisk/wipefs/cryptsetup fuehren: noch gemountete Partitionen, aktiver
# Swap auf der Platte, oder ein offenes LUKS-Mapping von einem frueheren
# (evtl. abgebrochenen) Lauf.

echo
echo "### Pruefe, ob $DISK oder ihre Partitionen noch in Benutzung sind..."

# a) Gemountete Partitionen aushaengen (nach Rueckfrage)
mapfile -t busy_mounts < <(lsblk -nrpo NAME,MOUNTPOINT "$DISK" 2>/dev/null | awk '$2!=""{print $0}')
if [[ ${#busy_mounts[@]} -gt 0 ]]; then
  echo "Folgende Partitionen von $DISK sind noch eingehaengt:"
  printf '  %s\n' "${busy_mounts[@]}"
  read -rp "Jetzt aushaengen und fortfahren? [y/N]: " unmount_confirm
  if [[ "$unmount_confirm" =~ ^[Yy]$ ]]; then
    for line in "${busy_mounts[@]}"; do
      part="${line%% *}"
      umount -f "$part" || { echo "Fehler: Konnte $part nicht aushaengen." >&2; exit 1; }
    done
  else
    echo "Abgebrochen: $DISK ist noch in Benutzung." >&2
    exit 1
  fi
fi

# b) Swap auf der Platte deaktivieren, falls vorhanden
for sw in $(lsblk -nrpo NAME,FSTYPE "$DISK" 2>/dev/null | awk '$2=="swap"{print $1}'); do
  echo "Deaktiviere Swap auf $sw..."
  swapoff "$sw" 2>/dev/null || true
done

# c) Offene LUKS-Mappings schliessen, die zu dieser Platte gehoeren
#    (z.B. Ueberbleibsel eines vorherigen, abgebrochenen Laufs)
for mapper_dev in /dev/mapper/*; do
  [[ -e "$mapper_dev" ]] || continue
  dm_name=$(basename "$mapper_dev")
  [[ "$dm_name" == "control" ]] && continue
  parent=$(lsblk -no PKNAME "$mapper_dev" 2>/dev/null | head -n1)
  if [[ -n "$parent" && "/dev/${parent}" == "$DISK" ]]; then
    echo "Schliesse noch offenes LUKS-Mapping '$dm_name' (gehoert zu $DISK)..."
    cryptsetup close "$dm_name" 2>/dev/null || {
      echo "Fehler: Konnte altes LUKS-Mapping '$dm_name' nicht schliessen." >&2
      echo "Bitte manuell pruefen (z.B. 'lsof /dev/mapper/$dm_name')." >&2
      exit 1
    }
  fi
done

echo "OK - $DISK ist frei."

# --- 0d. Eindeutigen LUKS-Namen erzeugen (UUID statt fixem "croot") -----
# Erzeugt z.B. "croot-a1b2c3d4" statt einfach nur "croot", damit es nicht
# mit bereits vorhandenen /dev/mapper/croot-Eintraegen (z.B. von der
# System-Platte) kollidiert. Falls der Name trotzdem schon existiert
# (Kollision, doppelter Lauf, etc.), wird einfach neu gewuerfelt.
gen_uuid_suffix() {
  if command -v uuidgen >/dev/null 2>&1; then
    uuidgen | cut -d- -f1
  else
    cat /proc/sys/kernel/random/uuid | cut -d- -f1
  fi
}

LUKS_NAME="${LUKS_NAME_BASE}-$(gen_uuid_suffix)"
while [[ -e "/dev/mapper/${LUKS_NAME}" ]]; do
  LUKS_NAME="${LUKS_NAME_BASE}-$(gen_uuid_suffix)"
done

echo
echo "### Zusammenfassung:"
echo "  Boot-Modus: $BOOT_MODE"
echo "  Image:      $IMAGE"
echo "  Zielplatte: $DISK"
echo "  LUKS-Name:  $LUKS_NAME  (/dev/mapper/${LUKS_NAME})"
echo
echo "### Achtung: ALLE Daten auf $DISK werden geloescht!"
lsblk "$DISK"
read -rp "Weiter mit 'yes': " confirm
[[ "$confirm" == "yes" ]] || exit 1

# --- 1. Partitionstabelle anlegen ------------------
wipefs -a "$DISK"

if [[ "$BOOT_MODE" == "uefi" ]]; then
  sfdisk "$DISK" <<EOF
label: gpt

size=${EFI_SIZE}, type=U, name="EFI"
size=${BOOT_SIZE}, type=L, name="boot"
type=L, name="luks"
EOF
else
  sfdisk "$DISK" <<EOF
label: dos

size=${BOOT_SIZE}, type=83, bootable
type=83
EOF
fi

# Kernel/udev ueber neue Partitionstabelle informieren
partprobe "$DISK" 2>/dev/null || partx -u "$DISK" 2>/dev/null || true
udevadm settle 2>/dev/null || true
sleep 2

# Partitionsnamen ermitteln (z.B. /dev/sdX oder /dev/nvme0nX)
if [[ "$DISK" =~ nvme|mmcblk ]]; then
  PARTPREFIX="${DISK}p"
else
  PARTPREFIX="${DISK}"
fi

if [[ "$BOOT_MODE" == "uefi" ]]; then
  P1="${PARTPREFIX}1"   # EFI
  P2="${PARTPREFIX}2"   # boot
  P3="${PARTPREFIX}3"   # luks
else
  P2="${PARTPREFIX}1"   # boot
  P3="${PARTPREFIX}2"   # luks
  # Boot-/Active-Flag explizit nachziehen: das "bootable"-Attribut im
  # sfdisk-Skript oben setzt es zwar schon, aber manche sfdisk-Versionen
  # setzen es je nach Syntax nicht zuverlaessig. Ohne aktives Flag
  # ignorieren viele Legacy-BIOS-Firmwares die Platte komplett
  # ("No bootable device"), obwohl GRUB korrekt installiert ist.
  sfdisk --activate "$DISK" 1
fi

# --- 2. Dateisysteme anlegen -------------------------------------------
if [[ "$BOOT_MODE" == "uefi" ]]; then
  mkfs.vfat -F32 -n EFI "$P1"
fi
mkfs.ext4 -L boot -F "$P2"

echo "### LUKS2-Verschluesselung fuer die Root-Partition einrichten"
cryptsetup luksFormat --type luks2 --force-password "$P3"
cryptsetup open "$P3" "$LUKS_NAME"

mkfs.xfs -L root -f "/dev/mapper/${LUKS_NAME}"

# --- 3. Mounten ----------------------------------------------------------
mkdir -p "$MOUNT_ROOT"
mount "/dev/mapper/${LUKS_NAME}" "$MOUNT_ROOT"
mkdir -p "$MOUNT_ROOT/boot"
mount "$P2" "$MOUNT_ROOT/boot"
if [[ "$BOOT_MODE" == "uefi" ]]; then
  mkdir -p "$MOUNT_ROOT/boot/efi"
  mount "$P1" "$MOUNT_ROOT/boot/efi"
fi

BOOT_UUID=$(blkid -s UUID -o value "$P2")
LUKS_UUID=$(blkid -s UUID -o value "$P3")

echo "Boot-UUID: $BOOT_UUID"
echo "LUKS-UUID: $LUKS_UUID"

# --- 4. bootc install to-filesystem ausfuehren ---------------------------
# Im BIOS/MBR-Modus gibt es keine ESP. bootc versucht trotzdem intern ueber
# bootupd IMMER auch eine EFI-Bootloader-Komponente zu installieren und
# bricht dabei hart ab ("No device specified and no mounted ESP found"),
# obwohl gar kein UEFI gewuenscht ist. --bootloader none ueberspringt die
# bootc-eigene Bootloader-Installation komplett; GRUB installieren wir im
# BIOS-Fall ohnehin selbst per chroot (Schritt 4b).
BOOTC_BOOTLOADER_ARGS=()
if [[ "$BOOT_MODE" == "bios" ]]; then
  BOOTC_BOOTLOADER_ARGS=(--bootloader none)
fi

podman run --rm --privileged --pid=host --ipc=host \
  -v /var/lib/containers:/var/lib/containers \
  -v /dev:/dev \
  -v "$MOUNT_ROOT:/target" \
  --security-opt label=type:unconfined_t \
  "$IMAGE" \
  bootc install to-filesystem \
    --boot-mount-spec "UUID=${BOOT_UUID}" \
    --karg "rd.luks.name=${LUKS_UUID}=${LUKS_NAME}" \
    --karg "root=/dev/mapper/${LUKS_NAME}" \
    "${BOOTC_BOOTLOADER_ARGS[@]}" \
    /target

# --- 4b. Bei BIOS/MBR: GRUB zusaetzlich per chroot ins MBR installieren --
if [[ "$BOOT_MODE" == "bios" ]]; then
  echo "### Installiere GRUB fuer Legacy BIOS/MBR-Boot"

  # bootc install to-filesystem "finalisiert" am Ende automatisch (fstrim +
  # read-only remount von Root und Boot - siehe "Finalizing filesystem
  # root/boot" oben). Fuer grub2-install/grub2-mkconfig brauchen wir dort
  # aber Schreibzugriff (z.B. um /boot/grub2 anzulegen), daher hier
  # explizit wieder read-write remounten.
  mount -o remount,rw "$MOUNT_ROOT"
  mount -o remount,rw "$MOUNT_ROOT/boot"

  # WICHTIG: $MOUNT_ROOT ist nur der physische ostree-"sysroot"
  # (enthaelt ostree/, boot/, ...), NICHT das eigentliche Betriebssystem -
  # /dev, /proc, /sys etc. existieren dort gar nicht als eigene
  # Verzeichnisse. Das echte, bootfaehige System liegt im ostree-
  # Deployment-Checkout unter ostree/deploy/<stateroot>/deploy/<hash>.0 -
  # dorthin muss gechroottet werden (analog zum bwrap-Aufruf, den bootc
  # selbst beim eigenen Bootloader-Setup verwendet).
  #
  # Explizit ueber <stateroot>/deploy/ suchen statt direkt nach "*.0" auf
  # allen drei Ebenen: bei composefs-Images gibt es zusaetzlich ein
  # <stateroot>/backing/<hash>.0-Verzeichnis (nur der read-only
  # Objekt-Store fuer die Container-Layer), das ebenfalls auf ".0" endet
  # und alphabetisch vor "deploy" sortiert - ein zu unspezifisches find
  # wuerde also faelschlicherweise dieses nur lesbare Verzeichnis treffen.
  STATEROOT_DIR=$(find "$MOUNT_ROOT/ostree/deploy" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | head -n1)
  if [[ -z "$STATEROOT_DIR" ]]; then
    echo "FEHLER: Kein stateroot-Verzeichnis unter ${MOUNT_ROOT}/ostree/deploy gefunden." >&2
    exit 1
  fi
  DEPLOY_DIR=$(find "$STATEROOT_DIR/deploy" -mindepth 1 -maxdepth 1 -type d -name '*.0' 2>/dev/null | head -n1)
  if [[ -z "$DEPLOY_DIR" ]]; then
    echo "FEHLER: Konnte kein ostree-Deployment-Verzeichnis unter" >&2
    echo "  ${STATEROOT_DIR}/deploy/<hash>.0 finden." >&2
    exit 1
  fi
  echo "Deployment-Verzeichnis: $DEPLOY_DIR"

  bind_mount "$MOUNT_ROOT/boot" "$DEPLOY_DIR/boot"
  bind_mount "$MOUNT_ROOT"      "$DEPLOY_DIR/sysroot"
  bind_mount "/dev"             "$DEPLOY_DIR/dev"
  bind_mount "/proc"            "$DEPLOY_DIR/proc"
  bind_mount "/sys"             "$DEPLOY_DIR/sys"
  bind_mount "/run"             "$DEPLOY_DIR/run"

  # --recheck: vorhandene Geraete-Erkennung verwerfen und neu pruefen
  # --force:   auch installieren, wenn grub2-install glaubt es sei schon
  #            aktuell (z.B. Ueberbleibsel von einem frueheren Testlauf
  #            auf derselben Platte)
  chroot "$DEPLOY_DIR" grub2-install --target=i386-pc --recheck --force "$DISK"

  # grub2-mkconfig scannt beim Erzeugen der Konfiguration auch /etc/fstab
  # und ruft fuer jeden dort eingetragenen Mountpoint grub2-probe auf - bei
  # generischen Fedora/RHEL-bootc-Images steht dort haeufig auch ein
  # /boot/efi-Eintrag drin, den es im BIOS/MBR-Modus gar nicht gibt.
  # grub2-probe scheitert dann schon am Kanonisieren des (nicht
  # existierenden) Pfades und bricht die komplette Konfigurationserstellung
  # ab. Ein leeres Platzhalterverzeichnis reicht, damit der Pfad aufgeloest
  # werden kann; ein echtes EFI-Bootziel wird dadurch nicht vorgetaeuscht.
  mkdir -p "$DEPLOY_DIR/boot/efi"

  chroot "$DEPLOY_DIR" grub2-mkconfig -o /boot/grub2/grub.cfg

  unmount_chroot_binds

  # Wichtig bei externen/USB-Platten: Schreib-Cache des Kernels UND des
  # Laufwerks selbst explizit durchspuelen. Sonst kann es passieren, dass
  # der MBR-Bootsektor im Cache haengt und nie wirklich auf die Platte
  # geschrieben wird, bevor man das Skript beendet und die Platte abzieht.
  sync
  blockdev --flushbufs "$DISK" 2>/dev/null || true
  hdparm -F "$DISK" 2>/dev/null || true

  # --- Verifikation: wurde wirklich ein gueltiger MBR-Bootsektor geschrieben? ---
  # Byte 510-511 muss die Boot-Signatur 0x55AA sein, UND der Bootcode-Bereich
  # (die ersten 440 Bytes) darf nicht komplett aus Nullen bestehen (das waere
  # der Fall, wenn grub2-install effektiv nichts geschrieben hat).
  mbr_sig=$(od -An -tx1 -j 510 -N 2 "$DISK" | tr -d ' \n')
  bootcode_nonzero=$(dd if="$DISK" bs=1 count=440 status=none | tr -d '\0' | wc -c)

  echo
  echo "### Verifikation MBR-Bootsektor auf $DISK:"
  echo "  Boot-Signatur (muss 55aa sein): $mbr_sig"
  echo "  Bootcode-Bytes ungleich Null:   $bootcode_nonzero (sollte > 0 sein)"

  if [[ "$mbr_sig" != "55aa" ]]; then
    echo "FEHLER: Boot-Signatur fehlt oder ist falsch (0x55AA erwartet)." >&2
    echo "Die Platte wird auf Legacy-BIOS-Geraeten vermutlich NICHT booten." >&2
    exit 1
  fi
  if [[ "$bootcode_nonzero" -eq 0 ]]; then
    echo "FEHLER: Bootcode-Bereich im MBR ist komplett leer - GRUB wurde" >&2
    echo "offenbar nicht wirklich in den MBR geschrieben." >&2
    exit 1
  fi
  echo "OK - MBR sieht bootfaehig aus."
  echo
  echo "Hinweis: Auf externen/USB-Platten benoetigt das Ziel-BIOS meist"
  echo "zusaetzlich 'CSM' bzw. 'Legacy USB Boot' aktiviert, sonst wird die"
  echo "Platte trotz korrektem MBR vom Legacy-BIOS-Scan ignoriert."
fi

# --- 5. Aufraeumen ---------------------------------------------------------
sync
if [[ "$BOOT_MODE" == "uefi" ]]; then
  umount "$MOUNT_ROOT/boot/efi"
fi
umount "$MOUNT_ROOT/boot"
umount "$MOUNT_ROOT"
cryptsetup close "$LUKS_NAME"

cat <<BANNER
╔══════════════════════════════════════════════════════════════════╗
║                        Installation fertig!                      ║
║                                                                    ║
║  Zielplatte:  ${DISK}
║  Boot-Modus:  ${BOOT_MODE}
║  Image:       ${IMAGE}
║  LUKS-Name:   ${LUKS_NAME}
║                                                                    ║
║  Die Platte kann jetzt gebootet werden.                    ║
╚══════════════════════════════════════════════════════════════════╝
BANNER
