Add autoinstall ISO builder for Cezen AI Suite
This commit is contained in:
parent
e472a83901
commit
5d9cec4fe8
144
autoinstall/build-iso.sh
Normal file
144
autoinstall/build-iso.sh
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ─────────────────────────────────────────────────────────────
|
||||||
|
# Cezen AI Suite — Custom ISO Builder
|
||||||
|
# Runs on macOS using Docker. Produces a bootable USB image.
|
||||||
|
#
|
||||||
|
# Usage: bash autoinstall/build-iso.sh
|
||||||
|
# Output: autoinstall/cezen-ai-ubuntu2204.iso
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - Docker Desktop running on your MacBook
|
||||||
|
# - ~6 GB free disk space (ISO download + work)
|
||||||
|
# ─────────────────────────────────────────────────────────────
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
OUTPUT_ISO="$SCRIPT_DIR/cezen-ai-ubuntu2204.iso"
|
||||||
|
UBUNTU_ISO_URL="https://releases.ubuntu.com/22.04.5/ubuntu-22.04.5-live-server-amd64.iso"
|
||||||
|
|
||||||
|
echo "╔══════════════════════════════════════════╗"
|
||||||
|
echo "║ Cezen AI — ISO Builder ║"
|
||||||
|
echo "╚══════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check Docker is running
|
||||||
|
if ! docker info &>/dev/null; then
|
||||||
|
echo "ERROR: Docker is not running. Start Docker Desktop and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✓ Docker is running"
|
||||||
|
|
||||||
|
# Check autoinstall files exist
|
||||||
|
if [ ! -f "$SCRIPT_DIR/user-data" ] || [ ! -f "$SCRIPT_DIR/meta-data" ]; then
|
||||||
|
echo "ERROR: user-data or meta-data not found in $SCRIPT_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✓ Autoinstall files found"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "→ Building ISO inside Docker container (Ubuntu 22.04)..."
|
||||||
|
echo " This will take 5–15 minutes depending on internet speed."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
-v "$SCRIPT_DIR:/autoinstall" \
|
||||||
|
-v "$REPO_ROOT:/repo" \
|
||||||
|
ubuntu:22.04 \
|
||||||
|
bash -c '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Install tools
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq xorriso wget isolinux rsync
|
||||||
|
|
||||||
|
WORK_DIR="/tmp/iso-work"
|
||||||
|
ORIGINAL_ISO="/tmp/ubuntu-22.04.5-live-server-amd64.iso"
|
||||||
|
UBUNTU_URL="https://releases.ubuntu.com/22.04.5/ubuntu-22.04.5-live-server-amd64.iso"
|
||||||
|
|
||||||
|
# Download Ubuntu ISO if not already cached
|
||||||
|
if [ ! -f "$ORIGINAL_ISO" ]; then
|
||||||
|
echo "→ Downloading Ubuntu 22.04.5 Server ISO (~1.8 GB)..."
|
||||||
|
wget -q --show-progress -O "$ORIGINAL_ISO" "$UBUNTU_URL"
|
||||||
|
fi
|
||||||
|
echo "✓ Ubuntu ISO ready"
|
||||||
|
|
||||||
|
# Extract ISO contents
|
||||||
|
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 "✓ ISO extracted"
|
||||||
|
|
||||||
|
# Inject autoinstall files
|
||||||
|
echo "→ Injecting autoinstall config..."
|
||||||
|
mkdir -p "$WORK_DIR/nocloud"
|
||||||
|
cp /autoinstall/user-data "$WORK_DIR/nocloud/user-data"
|
||||||
|
cp /autoinstall/meta-data "$WORK_DIR/nocloud/meta-data"
|
||||||
|
|
||||||
|
# Modify GRUB to auto-select install with autoinstall
|
||||||
|
GRUB_CFG="$WORK_DIR/boot/grub/grub.cfg"
|
||||||
|
|
||||||
|
# Backup original
|
||||||
|
cp "$GRUB_CFG" "$GRUB_CFG.orig"
|
||||||
|
|
||||||
|
# Set default to first entry and zero timeout
|
||||||
|
sed -i "s/set timeout=.*/set timeout=5/" "$GRUB_CFG"
|
||||||
|
sed -i "s/set timeout_style=.*/set timeout_style=countdown/" "$GRUB_CFG"
|
||||||
|
|
||||||
|
# Add autoinstall + nocloud parameters to the first linux line
|
||||||
|
# This patches the "Install Ubuntu Server" entry
|
||||||
|
sed -i "/^\s*linux.*vmlinuz/s/$/ autoinstall quiet ds=nocloud;s=\/cdrom\/nocloud\//" "$GRUB_CFG"
|
||||||
|
|
||||||
|
echo "✓ GRUB config patched"
|
||||||
|
|
||||||
|
# Get original ISO metadata for repacking
|
||||||
|
MBR_TEMPLATE=$(mktemp)
|
||||||
|
dd if="$ORIGINAL_ISO" bs=1 count=432 of="$MBR_TEMPLATE" 2>/dev/null
|
||||||
|
|
||||||
|
# Get EFI partition info
|
||||||
|
EFI_START=$(fdisk -l "$ORIGINAL_ISO" 2>/dev/null | grep "EFI" | awk "{print \$2}")
|
||||||
|
EFI_SIZE=$(fdisk -l "$ORIGINAL_ISO" 2>/dev/null | grep "EFI" | awk "{print \$4}")
|
||||||
|
|
||||||
|
echo "→ Repacking ISO..."
|
||||||
|
xorriso -as mkisofs \
|
||||||
|
-r \
|
||||||
|
-V "Cezen_AI_Ubuntu2204" \
|
||||||
|
-o /autoinstall/cezen-ai-ubuntu2204.iso \
|
||||||
|
--grub2-mbr "$MBR_TEMPLATE" \
|
||||||
|
-partition_offset 16 \
|
||||||
|
--mbr-force-bootable \
|
||||||
|
-append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b "$WORK_DIR/boot/grub/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_start_${EFI_START}s_size_${EFI_SIZE}s:all::" \
|
||||||
|
-no-emul-boot \
|
||||||
|
-boot-load-size 4 \
|
||||||
|
"$WORK_DIR" 2>/dev/null
|
||||||
|
|
||||||
|
echo "✓ ISO built successfully"
|
||||||
|
ls -lh /autoinstall/cezen-ai-ubuntu2204.iso
|
||||||
|
'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔══════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ ISO built: autoinstall/cezen-ai-ubuntu2204.iso ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ Flash to USB: ║"
|
||||||
|
echo "║ sudo dd if=autoinstall/cezen-ai-ubuntu2204.iso \ ║"
|
||||||
|
echo "║ of=/dev/diskX bs=4m status=progress ║"
|
||||||
|
echo "║ (replace /dev/diskX with your USB drive) ║"
|
||||||
|
echo "╚══════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "→ To find your USB drive: diskutil list"
|
||||||
2
autoinstall/meta-data
Normal file
2
autoinstall/meta-data
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
instance-id: cezen-aiserver
|
||||||
|
local-hostname: aiserver
|
||||||
91
autoinstall/user-data
Normal file
91
autoinstall/user-data
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#cloud-config
|
||||||
|
autoinstall:
|
||||||
|
version: 1
|
||||||
|
|
||||||
|
# ── Locale & keyboard ──────────────────────────
|
||||||
|
locale: en_IN.UTF-8
|
||||||
|
keyboard:
|
||||||
|
layout: us
|
||||||
|
|
||||||
|
# ── Network: DHCP on first ethernet ───────────
|
||||||
|
network:
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
any-en:
|
||||||
|
dhcp4: true
|
||||||
|
match:
|
||||||
|
name: "en*"
|
||||||
|
any-eth:
|
||||||
|
dhcp4: true
|
||||||
|
match:
|
||||||
|
name: "eth*"
|
||||||
|
|
||||||
|
# ── Storage: LVM on largest disk ──────────────
|
||||||
|
storage:
|
||||||
|
layout:
|
||||||
|
name: lvm
|
||||||
|
match:
|
||||||
|
size: largest
|
||||||
|
|
||||||
|
# ── Identity: cezen user ──────────────────────
|
||||||
|
identity:
|
||||||
|
hostname: aiserver
|
||||||
|
username: cezen
|
||||||
|
# Password: Cezen@2024! (SHA-512 hash below)
|
||||||
|
password: "$6$rounds=4096$cezentech$9pHVUFCvB7mHrblqn0qXJaFWxMkmepNM4T8Q5Fx8piVXuGDq.MLk/RH4nRMWtluLMpPXaZQAGFOD4xtjW1wC1"
|
||||||
|
|
||||||
|
# ── SSH ───────────────────────────────────────
|
||||||
|
ssh:
|
||||||
|
install-server: true
|
||||||
|
allow-pw: true
|
||||||
|
|
||||||
|
# ── Packages installed during setup ───────────
|
||||||
|
packages:
|
||||||
|
- git
|
||||||
|
- curl
|
||||||
|
- wget
|
||||||
|
|
||||||
|
# ── Late commands: run after OS install ───────
|
||||||
|
# These run with target mounted at /target
|
||||||
|
late-commands:
|
||||||
|
# Clone the Cezen AI installer
|
||||||
|
- git clone https://cgit.cezentech.com/jinojose/aipackage.git /target/opt/aipackage
|
||||||
|
|
||||||
|
# Set ownership
|
||||||
|
- curtin in-target -- chown -R cezen:cezen /opt/aipackage
|
||||||
|
|
||||||
|
# Create a firstboot systemd service that runs install.sh on first boot
|
||||||
|
- |
|
||||||
|
cat > /target/etc/systemd/system/cezen-firstboot.service << 'SVCEOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Cezen AI Suite First Boot Installer
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
ConditionPathExists=!/opt/cezen/.installed
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash /opt/aipackage/install.sh
|
||||||
|
ExecStartPost=/bin/touch /opt/cezen/.installed
|
||||||
|
RemainAfterExit=yes
|
||||||
|
StandardOutput=journal+console
|
||||||
|
StandardError=journal+console
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SVCEOF
|
||||||
|
|
||||||
|
# Enable the firstboot service
|
||||||
|
- curtin in-target -- systemctl enable cezen-firstboot.service
|
||||||
|
|
||||||
|
# Allow cezen user to run sudo without password (needed for install.sh)
|
||||||
|
- echo "cezen ALL=(ALL) NOPASSWD:ALL" > /target/etc/sudoers.d/cezen
|
||||||
|
- chmod 440 /target/etc/sudoers.d/cezen
|
||||||
|
|
||||||
|
# ── Skip confirmations ────────────────────────
|
||||||
|
user-data:
|
||||||
|
disable_root: false
|
||||||
|
|
||||||
|
# Confirm destructive action without prompting
|
||||||
|
confirm-bugs: false
|
||||||
Loading…
Reference in New Issue
Block a user