#!/usr/bin/env bash # ───────────────────────────────────────────────────────────── # Nexus One AI — Starter Tier ISO Builder # Hardware target: compact workstation (1× RTX 5090, 64 GB RAM, 2 TB NVMe) # # Usage: # cd ~/aipackage # bash autoinstall/build-iso-starter.sh # # Output: autoinstall/cezen-ai-starter-ubuntu2204.iso # Flash to USB: # diskutil unmountDisk /dev/diskN # sudo dd if=cezen-ai-starter-ubuntu2204.iso of=/dev/diskN bs=4m status=progress # ───────────────────────────────────────────────────────────── set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PACKAGE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" WORK_DIR="/tmp/cezen-iso-starter-work" ORIGINAL_ISO="/tmp/ubuntu-22.04.5-live-server-amd64.iso" OUTPUT_ISO="$SCRIPT_DIR/cezen-ai-starter-ubuntu2204.iso" UBUNTU_URL="https://releases.ubuntu.com/22.04.5/ubuntu-22.04.5-live-server-amd64.iso" TIER="starter" echo "╔══════════════════════════════════════════════════════╗" echo "║ Nexus One AI — ISO Builder [STARTER TIER] ║" echo "║ RTX 5090 · 64 GB RAM · 2 TB NVMe · 1–5 users ║" echo "╚══════════════════════════════════════════════════════╝" echo "" # ── Install build tools ──────────────────────── echo "→ Installing build tools..." apt-get update -qq apt-get install -y -qq xorriso wget isolinux rsync echo "✓ Tools ready" # ── Download Ubuntu ISO ──────────────────────── if [ -f "$ORIGINAL_ISO" ]; then echo "✓ Ubuntu ISO already downloaded" else echo "→ Downloading Ubuntu 22.04.5 Server ISO (~1.8 GB)..." wget --show-progress -O "$ORIGINAL_ISO" "$UBUNTU_URL" echo "✓ Downloaded" fi # ── Extract ISO ──────────────────────────────── echo "→ Extracting ISO..." rm -rf "$WORK_DIR" mkdir -p "$WORK_DIR" xorriso -osirrox on \ -indev "$ORIGINAL_ISO" \ -extract / "$WORK_DIR" 2>/dev/null chmod -R u+w "$WORK_DIR" echo "✓ Extracted" # ── Inject Starter autoinstall files ────────── echo "→ Injecting Starter autoinstall config..." mkdir -p "$WORK_DIR/nocloud" cp "$SCRIPT_DIR/user-data-starter" "$WORK_DIR/nocloud/user-data" cp "$SCRIPT_DIR/meta-data" "$WORK_DIR/nocloud/meta-data" echo "✓ user-data-starter and meta-data injected" # ── Online installer mode ────────────────────── # The installed system pulls the current package from cgit on first boot. This # keeps the ISO small and avoids shipping stale backend/portal code. echo "✓ Online installer mode: package will be pulled from cgit on first boot" # ── Patch GRUB ──────────────────────────────── echo "→ Patching GRUB config..." GRUB_CFG="$WORK_DIR/boot/grub/grub.cfg" cp "$GRUB_CFG" "$GRUB_CFG.orig" sed -i "s/set timeout=.*/set timeout=5/" "$GRUB_CFG" sed -i "s/set timeout_style=.*/set timeout_style=countdown/" "$GRUB_CFG" sed -i '/^\s*linux.*vmlinuz/s|---|autoinstall ds=nocloud\\;s=/cdrom/nocloud/ ---|' "$GRUB_CFG" # Update GRUB title to reflect Starter tier sed -i 's/Install Ubuntu Server/Install Nexus One AI — Starter Tier/' "$GRUB_CFG" || true echo "✓ GRUB patched" # ── Extract MBR and EFI boot data ───────────── echo "→ Extracting boot data from original ISO..." MBR_TEMPLATE=$(mktemp) EFI_IMG=$(mktemp) dd if="$ORIGINAL_ISO" bs=1 count=432 of="$MBR_TEMPLATE" 2>/dev/null EFI_LINE=$(fdisk -l "$ORIGINAL_ISO" 2>/dev/null | grep "EFI") echo " EFI partition info: $EFI_LINE" EFI_START=$(echo "$EFI_LINE" | awk '{print $2}') EFI_SIZE=$(echo "$EFI_LINE" | awk '{print $4}') if [ -z "$EFI_START" ] || [ -z "$EFI_SIZE" ]; then echo "ERROR: Could not detect EFI partition in ISO." echo "Run: fdisk -l $ORIGINAL_ISO" exit 1 fi dd if="$ORIGINAL_ISO" bs=512 skip="$EFI_START" count="$EFI_SIZE" \ of="$EFI_IMG" 2>/dev/null echo "✓ EFI partition extracted (start=$EFI_START, size=$EFI_SIZE)" # ── Repack ISO (pass 1) ──────────────────────── echo "→ Repacking ISO (pass 1)..." xorriso -as mkisofs \ -r \ -V "CezenAI_Starter_2204" \ -o "$OUTPUT_ISO" \ --grub2-mbr "$MBR_TEMPLATE" \ -partition_offset 16 \ --mbr-force-bootable \ -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b "$EFI_IMG" \ -appended_part_as_gpt \ -iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7 \ -c "/boot.catalog" \ -b "/boot/grub/i386-pc/eltorito.img" \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ --grub2-boot-info \ -eltorito-alt-boot \ -e "--interval:appended_partition_2:::" \ -no-emul-boot \ "$WORK_DIR" # ── Refresh md5sum.txt and repack (pass 2) ──── echo "→ Refreshing md5sum.txt..." FINAL_DIR=$(mktemp -d) VERIFY_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR" "$MBR_TEMPLATE" "$EFI_IMG" "$FINAL_DIR" "$VERIFY_DIR"' EXIT xorriso -osirrox on -indev "$OUTPUT_ISO" -extract / "$FINAL_DIR" >/dev/null 2>&1 chmod -R u+w "$FINAL_DIR" ( cd "$FINAL_DIR" rm -f md5sum.txt find . -type f \ ! -path './md5sum.txt' \ ! -path './boot.catalog' \ -print0 \ | sort -z \ | xargs -0 md5sum > md5sum.txt ) echo "✓ md5sum.txt refreshed" echo "→ Repacking ISO (pass 2)..." xorriso -as mkisofs \ -r \ -V "CezenAI_Starter_2204" \ -o "$OUTPUT_ISO" \ --grub2-mbr "$MBR_TEMPLATE" \ -partition_offset 16 \ --mbr-force-bootable \ -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b "$EFI_IMG" \ -appended_part_as_gpt \ -iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7 \ -c "/boot.catalog" \ -b "/boot/grub/i386-pc/eltorito.img" \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ --grub2-boot-info \ -eltorito-alt-boot \ -e "--interval:appended_partition_2:::" \ -no-emul-boot \ "$FINAL_DIR" # ── Verify output ISO ────────────────────────── echo "→ Verifying rebuilt ISO manifest..." xorriso -osirrox on -indev "$OUTPUT_ISO" -extract / "$VERIFY_DIR" >/dev/null 2>&1 chmod -R u+w "$VERIFY_DIR" ( cd "$VERIFY_DIR" md5sum -c md5sum.txt >/tmp/cezen-iso-md5check-starter.log 2>&1 || { echo "ERROR: Rebuilt ISO failed its own md5sum.txt verification." sed -n '1,40p' /tmp/cezen-iso-md5check-starter.log exit 1 } ) echo "✓ Output ISO manifest verified" echo "" echo "╔══════════════════════════════════════════════════════╗" echo "║ Done! Starter Tier ISO ready. ║" echo "╚══════════════════════════════════════════════════════╝" echo "" ls -lh "$OUTPUT_ISO" echo "" echo "→ Transfer to MacBook:" echo " scp user@server:~/aipackage/autoinstall/cezen-ai-starter-ubuntu2204.iso ." echo "" echo "→ Flash to USB (macOS):" echo " diskutil list # find USB e.g. /dev/disk4" echo " diskutil unmountDisk /dev/disk4" echo " sudo dd if=cezen-ai-starter-ubuntu2204.iso of=/dev/disk4 bs=4m status=progress" echo "" echo "→ Post-flash: boot the workstation from USB." echo " Unattended install completes in ~10 min." echo " First-boot wizard runs on tty1 — set IP, org name, admin password." echo " Then run: sudo bash /opt/aipackage/install.sh --tier starter"