diff --git a/iso/builder/config/hooks/normal/9012-wipe.hook.chroot b/iso/builder/config/hooks/normal/9012-wipe.hook.chroot new file mode 100755 index 0000000..e96da18 --- /dev/null +++ b/iso/builder/config/hooks/normal/9012-wipe.hook.chroot @@ -0,0 +1,57 @@ +#!/bin/sh +# 9012-wipe.hook.chroot +# +# Adds bee-initramfs-wipe to the initramfs so that selecting the +# "WIPE ALL DISKS" boot menu entry runs the wipe tool before squashfs +# is mounted — i.e. it works even when live boot fails. +# +# Two files are installed inside the chroot: +# /etc/initramfs-tools/hooks/bee-wipe — copies binaries into initrd +# /etc/initramfs-tools/scripts/local-premount/bee-wipe — runs at boot + +set -e + +HOOK_DIR="/etc/initramfs-tools/hooks" +SCRIPT_DIR="/etc/initramfs-tools/scripts/local-premount" + +mkdir -p "${HOOK_DIR}" "${SCRIPT_DIR}" + +# ── initramfs hook: copy binaries ──────────────────────────────────────────── +cat > "${HOOK_DIR}/bee-wipe" << 'EOF' +#!/bin/sh +PREREQ="" +prereqs() { echo "$PREREQ"; } +case "$1" in prereqs) prereqs; exit 0 ;; esac + +. /usr/share/initramfs-tools/hook-functions + +for bin in lsblk blkid blkdiscard blockdev; do + b=$(command -v "$bin" 2>/dev/null) && copy_exec "$b" /bin +done + +[ -x /usr/sbin/nvme ] && copy_exec /usr/sbin/nvme /sbin + +copy_exec /usr/local/bin/bee-initramfs-wipe /bin/bee-wipe +EOF + +chmod +x "${HOOK_DIR}/bee-wipe" + +# ── initramfs premount script: trigger on bee.wipe=all ─────────────────────── +cat > "${SCRIPT_DIR}/bee-wipe" << 'EOF' +#!/bin/sh +PREREQ="" +prereqs() { echo "$PREREQ"; } +case "$1" in prereqs) prereqs; exit 0 ;; esac + +grep -qw 'bee.wipe=all' /proc/cmdline 2>/dev/null || exit 0 +exec /bin/bee-wipe +EOF + +chmod +x "${SCRIPT_DIR}/bee-wipe" + +echo "9012-wipe: installed initramfs hook and premount script" + +KVER=$(ls /lib/modules | sort -V | tail -1) +echo "9012-wipe: rebuilding initramfs for kernel ${KVER}" +update-initramfs -u -k "${KVER}" +echo "9012-wipe: done" diff --git a/iso/overlay/usr/local/bin/bee-initramfs-wipe b/iso/overlay/usr/local/bin/bee-initramfs-wipe new file mode 100755 index 0000000..c46c803 --- /dev/null +++ b/iso/overlay/usr/local/bin/bee-initramfs-wipe @@ -0,0 +1,166 @@ +#!/bin/sh +# bee-initramfs-wipe — interactive disk wipe running entirely in the initramfs. +# Triggered by bee.wipe=all on the kernel cmdline (via local-premount hook). +# Works before squashfs is mounted, so it runs even when live boot fails. + +RED='\033[1;31m' +YEL='\033[1;33m' +GRN='\033[1;32m' +CYN='\033[1;36m' +NC='\033[0m' + +p() { printf '%b\n' "$*"; } +pp() { printf '%b' "$*"; } + +banner() { + p "" + p "${RED}╔══════════════════════════════════════════════════════════╗${NC}" + p "${RED}║ BEE DRIVE WIPE — initramfs stage ║${NC}" + p "${RED}╚══════════════════════════════════════════════════════════╝${NC}" + p "" +} + +# ── find boot device ───────────────────────────────────────────────────────── +boot_dev() { + local label token + for token in $(cat /proc/cmdline 2>/dev/null); do + case "$token" in + live-media-label=*) label="${token#*=}" ;; + esac + done + [ -z "$label" ] && return + + local dev + dev=$(blkid -L "$label" 2>/dev/null) || return + # strip partition suffix: /dev/sdb1 → /dev/sdb, /dev/nvme0n1p1 → /dev/nvme0n1 + echo "$dev" | sed 's/p\?[0-9]\+$//' +} + +# ── enumerate candidate disks ───────────────────────────────────────────────── +list_disks() { + local boot + boot=$(boot_dev) + + lsblk -d -n -o NAME,TYPE,SIZE,MODEL 2>/dev/null | while read -r name type size model; do + [ "$type" = "disk" ] || continue + [ "$size" = "0B" ] && continue + local dev="/dev/$name" + [ "$dev" = "$boot" ] && continue + printf '%s\t%s\t%s\n' "$dev" "$size" "${model:-}" + done +} + +# ── wipe one disk ───────────────────────────────────────────────────────────── +wipe_one() { + local dev="$1" + p "" + p "=== ${YEL}${dev}${NC} ===" + + if echo "$dev" | grep -q '^/dev/nvme'; then + if nvme format --ses=1 "$dev" 2>&1; then + p " ${GRN}nvme format OK${NC}" + blockdev --flushbufs "$dev" 2>/dev/null || true + return + fi + p " nvme format failed — falling back to blkdiscard" + fi + + if blkdiscard -f "$dev" 2>&1; then + p " ${GRN}blkdiscard OK${NC}" + blockdev --flushbufs "$dev" 2>/dev/null || true + return + fi + + p " blkdiscard not supported — zeroing partition tables (HDD fallback)" + local size_bytes mb32 skip + size_bytes=$(blockdev --getsize64 "$dev" 2>/dev/null || echo 0) + mb32=$(( 32 * 1024 * 1024 )) + + dd if=/dev/zero of="$dev" bs=4M count=8 conv=fsync status=progress 2>&1 || true + + if [ "$size_bytes" -gt $(( mb32 * 2 )) ]; then + skip=$(( (size_bytes - mb32) / (4 * 1024 * 1024) )) + dd if=/dev/zero of="$dev" bs=4M count=8 seek="$skip" conv=fsync status=progress 2>&1 || true + fi + + blockdev --flushbufs "$dev" 2>/dev/null || true + p " ${GRN}done (partition tables zeroed)${NC}" +} + +# ── main ────────────────────────────────────────────────────────────────────── +banner + +BOOT=$(boot_dev) +[ -n "$BOOT" ] && p "Boot device (excluded): ${CYN}${BOOT}${NC}\n" + +# build indexed list +i=0 +DEVS="" +IFS=' +' +for line in $(list_disks); do + i=$(( i + 1 )) + dev=$(echo "$line" | cut -f1) + size=$(echo "$line" | cut -f2) + model=$(echo "$line" | cut -f3) + DEVS="${DEVS}${i}:${dev}:${size}:${model} +" + printf " ${CYN}[%d]${NC} %-16s %8s %s\n" "$i" "$dev" "$size" "$model" +done +IFS=' +' + +if [ "$i" -eq 0 ]; then + p "\nNo physical disks found (boot device excluded)." + p "Dropping to shell — type 'exit' to continue boot." + exec /bin/sh +fi + +p "" +pp "Enter numbers to wipe (space-separated), ${YEL}all${NC} for all, ${YEL}q${NC} to abort: " +read -r SELECTION + +case "$SELECTION" in + q|Q|'') p "\nAborted."; exec /bin/sh ;; +esac + +# resolve selection → list of devs +SELECTED="" +if [ "$SELECTION" = "all" ] || [ "$SELECTION" = "ALL" ]; then + SELECTED=$(echo "$DEVS" | grep -v '^$' | cut -d: -f2 | tr '\n' ' ') +else + for num in $SELECTION; do + match=$(echo "$DEVS" | grep "^${num}:" | cut -d: -f2) + if [ -z "$match" ]; then + p "${RED}Unknown index: ${num}${NC}"; exec /bin/sh + fi + SELECTED="${SELECTED}${match} " + done +fi + +SELECTED=$(echo "$SELECTED" | tr -s ' ' | sed 's/ $//') + +p "" +p "Selected for wipe: ${YEL}${SELECTED}${NC}" +p "${RED}WARNING: This is IRREVERSIBLE. All data on the selected disks will be lost.${NC}" +p "" +pp "Type YES to confirm, anything else to abort: " +read -r CONFIRM + +if [ "$CONFIRM" != "YES" ]; then + p "\nAborted — no disks were touched." + exec /bin/sh +fi + +p "\nStarting wipe..." +for dev in $SELECTED; do + wipe_one "$dev" +done + +sync +p "" +p "${GRN}=== All selected disks wiped and flushed. ===${NC}" +p "" +pp "Press Enter to reboot..." +read -r _ +reboot