#!/bin/bash # bee-install — install the live system to a local disk. # # Usage: bee-install [logfile] # device — target block device, e.g. /dev/sda (will be WIPED) # logfile — optional path to write progress log (default: /tmp/bee-install.log) # # Layout (UEFI): GPT, /dev/sdX1=EFI 512MB vfat, /dev/sdX2=root ext4 # Layout (BIOS): MBR, /dev/sdX1=root ext4 # # Squashfs source: /run/live/medium/live/filesystem.squashfs set -euo pipefail DEVICE="${1:-}" LOGFILE="${2:-/tmp/bee-install.log}" if [ -z "$DEVICE" ]; then echo "Usage: bee-install [logfile]" >&2 exit 1 fi if [ ! -b "$DEVICE" ]; then echo "ERROR: $DEVICE is not a block device" >&2 exit 1 fi SQUASHFS="/run/live/medium/live/filesystem.squashfs" if [ ! -f "$SQUASHFS" ]; then echo "ERROR: squashfs not found at $SQUASHFS" >&2 exit 1 fi MOUNT_ROOT="/mnt/bee-install-root" # ------------------------------------------------------------------ log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOGFILE"; } die() { log "ERROR: $*"; exit 1; } # ------------------------------------------------------------------ # Detect UEFI if [ -d /sys/firmware/efi ]; then UEFI=1 log "Boot mode: UEFI" else UEFI=0 log "Boot mode: BIOS/legacy" fi # Determine partition names (nvme uses p-suffix: nvme0n1p1) if echo "$DEVICE" | grep -qE 'nvme|mmcblk'; then PART_PREFIX="${DEVICE}p" else PART_PREFIX="${DEVICE}" fi if [ "$UEFI" = "1" ]; then PART_EFI="${PART_PREFIX}1" PART_ROOT="${PART_PREFIX}2" else PART_ROOT="${PART_PREFIX}1" fi # ------------------------------------------------------------------ log "=== BEE DISK INSTALLER ===" log "Target device : $DEVICE" log "Root partition: $PART_ROOT" [ "$UEFI" = "1" ] && log "EFI partition : $PART_EFI" log "Squashfs : $SQUASHFS ($(du -sh "$SQUASHFS" | cut -f1))" log "Log : $LOGFILE" log "" # ------------------------------------------------------------------ log "--- Step 1/7: Unmounting target device ---" # Unmount any partitions on target device for part in "${DEVICE}"* ; do if [ "$part" = "$DEVICE" ]; then continue; fi if mountpoint -q "$part" 2>/dev/null; then log " umount $part" umount "$part" || true fi done # Also unmount our mount point if leftover umount "${MOUNT_ROOT}" 2>/dev/null || true umount "${MOUNT_ROOT}/boot/efi" 2>/dev/null || true # ------------------------------------------------------------------ log "--- Step 2/7: Partitioning $DEVICE ---" if [ "$UEFI" = "1" ]; then parted -s "$DEVICE" mklabel gpt parted -s "$DEVICE" mkpart EFI fat32 1MiB 513MiB parted -s "$DEVICE" set 1 esp on parted -s "$DEVICE" mkpart root ext4 513MiB 100% else parted -s "$DEVICE" mklabel msdos parted -s "$DEVICE" mkpart primary ext4 1MiB 100% parted -s "$DEVICE" set 1 boot on fi # Wait for kernel to see new partitions sleep 1 partprobe "$DEVICE" 2>/dev/null || true sleep 1 log " Partitioning done." # ------------------------------------------------------------------ log "--- Step 3/7: Formatting ---" if [ "$UEFI" = "1" ]; then mkfs.vfat -F32 -n EFI "$PART_EFI" log " $PART_EFI formatted as vfat (EFI)" fi mkfs.ext4 -F -L bee-root "$PART_ROOT" log " $PART_ROOT formatted as ext4" # ------------------------------------------------------------------ log "--- Step 4/7: Mounting target ---" mkdir -p "$MOUNT_ROOT" mount "$PART_ROOT" "$MOUNT_ROOT" if [ "$UEFI" = "1" ]; then mkdir -p "${MOUNT_ROOT}/boot/efi" mount "$PART_EFI" "${MOUNT_ROOT}/boot/efi" fi log " Mounted." # ------------------------------------------------------------------ log "--- Step 5/7: Unpacking filesystem (this takes 10-20 minutes) ---" log " Source: $SQUASHFS" log " Target: $MOUNT_ROOT" unsquashfs -f -d "$MOUNT_ROOT" "$SQUASHFS" 2>&1 | \ grep -E '^\[|^inod|^created|^extract' | \ while read -r line; do log " $line"; done || true log " Unpack complete." # ------------------------------------------------------------------ log "--- Step 6/7: Configuring installed system ---" # Write /etc/fstab ROOT_UUID=$(blkid -s UUID -o value "$PART_ROOT") log " Root UUID: $ROOT_UUID" cat > "${MOUNT_ROOT}/etc/fstab" <> "${MOUNT_ROOT}/etc/fstab" fi log " fstab written." # Remove live-boot persistence markers so installed system boots normally rm -f "${MOUNT_ROOT}/etc/live/boot.conf" 2>/dev/null || true rm -f "${MOUNT_ROOT}/etc/live/live.conf" 2>/dev/null || true # Bind mount virtual filesystems for chroot mount --bind /dev "${MOUNT_ROOT}/dev" mount --bind /proc "${MOUNT_ROOT}/proc" mount --bind /sys "${MOUNT_ROOT}/sys" [ "$UEFI" = "1" ] && mount --bind /sys/firmware/efi/efivars "${MOUNT_ROOT}/sys/firmware/efi/efivars" 2>/dev/null || true # ------------------------------------------------------------------ log "--- Step 7/7: Installing GRUB bootloader ---" if [ "$UEFI" = "1" ]; then chroot "$MOUNT_ROOT" grub-install \ --target=x86_64-efi \ --efi-directory=/boot/efi \ --bootloader-id=bee \ --recheck 2>&1 | while read -r line; do log " $line"; done || true else chroot "$MOUNT_ROOT" grub-install \ --target=i386-pc \ --recheck \ "$DEVICE" 2>&1 | while read -r line; do log " $line"; done || true fi chroot "$MOUNT_ROOT" update-grub 2>&1 | while read -r line; do log " $line"; done || true log " GRUB installed." # ------------------------------------------------------------------ # Cleanup log "--- Cleanup ---" umount "${MOUNT_ROOT}/sys/firmware/efi/efivars" 2>/dev/null || true umount "${MOUNT_ROOT}/sys" 2>/dev/null || true umount "${MOUNT_ROOT}/proc" 2>/dev/null || true umount "${MOUNT_ROOT}/dev" 2>/dev/null || true [ "$UEFI" = "1" ] && umount "${MOUNT_ROOT}/boot/efi" 2>/dev/null || true umount "$MOUNT_ROOT" 2>/dev/null || true rmdir "$MOUNT_ROOT" 2>/dev/null || true log "" log "=== INSTALLATION COMPLETE ===" log "Remove the ISO and reboot to start the installed system."