158 lines
6.3 KiB
Bash
158 lines
6.3 KiB
Bash
#!/usr/bin/env bash
|
|
# ─────────────────────────────────────────────────────────────
|
|
# Cezen AI Suite — Custom ISO Builder
|
|
# Runs directly on Ubuntu 22.04 (run on the server)
|
|
#
|
|
# Usage:
|
|
# cd ~/aipackage
|
|
# bash autoinstall/build-iso.sh
|
|
#
|
|
# Output: ~/aipackage/autoinstall/cezen-ai-ubuntu2204.iso
|
|
# Then copy the ISO to a USB stick or burn it.
|
|
# ─────────────────────────────────────────────────────────────
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PACKAGE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
WORK_DIR="/tmp/cezen-iso-work"
|
|
ORIGINAL_ISO="/tmp/ubuntu-22.04.5-live-server-amd64.iso"
|
|
OUTPUT_ISO="$SCRIPT_DIR/cezen-ai-ubuntu2204.iso"
|
|
UBUNTU_URL="https://releases.ubuntu.com/22.04.5/ubuntu-22.04.5-live-server-amd64.iso"
|
|
|
|
echo "╔══════════════════════════════════════════╗"
|
|
echo "║ Cezen AI — ISO Builder ║"
|
|
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 autoinstall files ───────────────────
|
|
echo "→ Injecting autoinstall config..."
|
|
mkdir -p "$WORK_DIR/nocloud"
|
|
cp "$SCRIPT_DIR/user-data" "$WORK_DIR/nocloud/user-data"
|
|
cp "$SCRIPT_DIR/meta-data" "$WORK_DIR/nocloud/meta-data"
|
|
echo "✓ user-data and meta-data injected"
|
|
|
|
# Keep the installer payload on the ISO so first boot does not depend on a
|
|
# private Git server being reachable before the setup UI can start.
|
|
echo "→ Bundling Cezen AI installer payload..."
|
|
mkdir -p "$WORK_DIR/cezen-aipackage"
|
|
rsync -a --delete \
|
|
--exclude 'autoinstall/cezen-ai-ubuntu2204.iso' \
|
|
--exclude '*.iso' \
|
|
"$PACKAGE_DIR/" "$WORK_DIR/cezen-aipackage/"
|
|
echo "✓ Installer payload bundled"
|
|
|
|
# ── Refresh installer checksum manifest ─────────────────
|
|
echo "→ Refreshing md5sum.txt..."
|
|
(
|
|
cd "$WORK_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"
|
|
|
|
# ── Patch GRUB ────────────────────────────────
|
|
echo "→ Patching GRUB config..."
|
|
GRUB_CFG="$WORK_DIR/boot/grub/grub.cfg"
|
|
cp "$GRUB_CFG" "$GRUB_CFG.orig"
|
|
|
|
# Set 5 second countdown then auto-install
|
|
sed -i "s/set timeout=.*/set timeout=5/" "$GRUB_CFG"
|
|
sed -i "s/set timeout_style=.*/set timeout_style=countdown/" "$GRUB_CFG"
|
|
|
|
# Add autoinstall params BEFORE the '---' separator on the kernel line.
|
|
# Anything after '---' in a GRUB linux line goes to init, not the kernel.
|
|
# So 'autoinstall' and 'ds=' must be inserted BEFORE '---'.
|
|
# Semicolon is backslash-escaped so GRUB doesn't treat it as a command separator.
|
|
sed -i '/^\s*linux.*vmlinuz/s|---|autoinstall ds=nocloud\\;s=/cdrom/nocloud/ ---|' "$GRUB_CFG"
|
|
echo "✓ GRUB patched"
|
|
|
|
# ── Extract MBR and EFI partition from original ISO ────
|
|
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
|
|
|
|
# Find EFI partition (partition 2) start and size in 512-byte sectors
|
|
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 ─────────────────────────────────
|
|
echo "→ Repacking ISO (this takes ~2 minutes)..."
|
|
xorriso -as mkisofs \
|
|
-r \
|
|
-V "Cezen_AI_Ubuntu2204" \
|
|
-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"
|
|
|
|
echo ""
|
|
echo "╔══════════════════════════════════════════════════════╗"
|
|
echo "║ Done! ║"
|
|
echo "╚══════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
ls -lh "$OUTPUT_ISO"
|
|
echo ""
|
|
echo "→ Copy to your MacBook:"
|
|
echo " scp user@172.16.10.180:~/aipackage/autoinstall/cezen-ai-ubuntu2204.iso ."
|
|
echo ""
|
|
echo "→ Flash to USB on MacBook:"
|
|
echo " diskutil list # find USB e.g. /dev/disk4"
|
|
echo " diskutil unmountDisk /dev/disk4"
|
|
echo " sudo dd if=cezen-ai-ubuntu2204.iso of=/dev/disk4 bs=4m status=progress"
|