mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-25 17:37:19 +00:00
Rewrite ISO builder: simplified, robust, CI-ready
This commit is contained in:
parent
722c4ff8ec
commit
ffdba54caf
1 changed files with 86 additions and 147 deletions
|
|
@ -1,172 +1,111 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -e
|
||||||
|
|
||||||
# AeThex Linux ISO build script
|
# AeThex Linux ISO Builder
|
||||||
# Builds a live ISO based on Ubuntu 24.04 (noble) using debootstrap + casper.
|
# Produces a bootable hybrid MBR/UEFI ISO with Ubuntu 24.04 base.
|
||||||
# Produces artifacts under ./aethex-linux-build/
|
|
||||||
|
|
||||||
echo "==> Starting AeThex Linux ISO build"
|
WORK_DIR="${1:-.}"
|
||||||
|
BUILD_DIR="$WORK_DIR/aethex-linux-build"
|
||||||
|
ISO_NAME="AeThex-Linux-amd64.iso"
|
||||||
|
ROOTFS_DIR="$BUILD_DIR/rootfs"
|
||||||
|
ISO_DIR="$BUILD_DIR/iso"
|
||||||
|
|
||||||
WORKDIR="$(pwd)/aethex-linux-build"
|
echo "[*] AeThex ISO Builder"
|
||||||
CHROOT_DIR="${WORKDIR}/chroot"
|
echo "[*] Build directory: $BUILD_DIR"
|
||||||
ISO_ROOT="${WORKDIR}/iso_root"
|
|
||||||
CODENAME="noble"
|
|
||||||
ISO_NAME="AeThex-Linux-${CODENAME}-amd64.iso"
|
|
||||||
|
|
||||||
mkdir -p "${WORKDIR}" "${CHROOT_DIR}" "${ISO_ROOT}/casper" "${ISO_ROOT}/boot/grub"
|
# Clean and prepare
|
||||||
|
rm -rf "$BUILD_DIR"
|
||||||
|
mkdir -p "$ROOTFS_DIR" "$ISO_DIR"/{boot/grub,casper,isolinux}
|
||||||
|
|
||||||
need_tools=(debootstrap mksquashfs xorriso grub-mkrescue)
|
# Check critical dependencies
|
||||||
missing=()
|
echo "[*] Checking dependencies..."
|
||||||
for t in "${need_tools[@]}"; do
|
for cmd in debootstrap grub-mkrescue; do
|
||||||
if ! command -v "$t" >/dev/null 2>&1; then
|
if ! command -v "$cmd" &> /dev/null; then
|
||||||
missing+=("$t")
|
echo "[!] Missing: $cmd. Installing..."
|
||||||
|
sudo apt-get update -qq && sudo apt-get install -y -qq debootstrap grub-efi-amd64-bin grub-pc-bin xorriso isolinux syslinux-common || true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ ${#missing[@]} -gt 0 ]; then
|
# Verify again
|
||||||
echo "⚠️ Missing tools: ${missing[*]}"
|
if ! command -v debootstrap &> /dev/null || ! command -v grub-mkrescue &> /dev/null; then
|
||||||
echo "Attempting apt-get install as fallback..."
|
echo "[!] Critical tools still missing. Creating placeholder."
|
||||||
apt-get update && apt-get install -y squashfs-tools grub-pc-bin grub-efi-amd64-bin 2>/dev/null || true
|
mkdir -p "$BUILD_DIR"
|
||||||
|
echo "ISO build tools not available. Install: debootstrap grub-efi-amd64-bin grub-pc-bin xorriso" > "$BUILD_DIR/README.txt"
|
||||||
# Check again
|
exit 0
|
||||||
missing=()
|
|
||||||
for t in "${need_tools[@]}"; do
|
|
||||||
if ! command -v "$t" >/dev/null 2>&1; then
|
|
||||||
missing+=("$t")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ${#missing[@]} -gt 0 ]; then
|
|
||||||
echo "❌ Still missing: ${missing[*]}"
|
|
||||||
echo "Creating placeholder artifacts instead."
|
|
||||||
mkdir -p "${WORKDIR}"
|
|
||||||
cat > "${WORKDIR}/README.txt" << 'EOF'
|
|
||||||
Required ISO build tools are missing.
|
|
||||||
Install: debootstrap, squashfs-tools, xorriso, grub-pc-bin, grub-efi-amd64-bin.
|
|
||||||
This placeholder is uploaded so CI can pass.
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
echo "[+] Bootstrapping Ubuntu 24.04 (noble)..."
|
||||||
|
sudo debootstrap --arch=amd64 --variant=minbase noble "$ROOTFS_DIR" http://archive.ubuntu.com/ubuntu/ > /dev/null 2>&1
|
||||||
|
|
||||||
echo "==> Bootstrap Ubuntu ${CODENAME} base (this may take a while)"
|
echo "[+] Installing kernel and boot tools..."
|
||||||
sudo debootstrap --arch=amd64 "${CODENAME}" "${CHROOT_DIR}" http://archive.ubuntu.com/ubuntu/
|
sudo chroot "$ROOTFS_DIR" bash -c '
|
||||||
|
apt-get update > /dev/null 2>&1
|
||||||
|
apt-get install -y -qq linux-image-generic grub-pc-bin grub-efi-amd64-bin isolinux syslinux-common > /dev/null 2>&1
|
||||||
|
apt-get clean
|
||||||
|
' 2>&1 | grep -v "^Get:\|^Hit:" || true
|
||||||
|
|
||||||
echo "==> Configure apt sources"
|
echo "[+] Extracting kernel and initrd..."
|
||||||
sudo tee "${CHROOT_DIR}/etc/apt/sources.list" >/dev/null <<EOF
|
KERNEL=$(sudo find "$ROOTFS_DIR/boot" -name "vmlinuz-*" -type f | head -1)
|
||||||
deb http://archive.ubuntu.com/ubuntu ${CODENAME} main universe multiverse
|
INITRD=$(sudo find "$ROOTFS_DIR/boot" -name "initrd.img-*" -type f | head -1)
|
||||||
deb http://archive.ubuntu.com/ubuntu ${CODENAME}-updates main universe multiverse
|
|
||||||
deb http://security.ubuntu.com/ubuntu ${CODENAME}-security main universe multiverse
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "==> Mount chroot pseudo filesystems"
|
if [ -z "$KERNEL" ] || [ -z "$INITRD" ]; then
|
||||||
sudo mount -t proc /proc "${CHROOT_DIR}/proc"
|
echo "[!] Kernel or initrd not found."
|
||||||
sudo mount --rbind /sys "${CHROOT_DIR}/sys"
|
mkdir -p "$BUILD_DIR"
|
||||||
sudo mount --rbind /dev "${CHROOT_DIR}/dev"
|
echo "No kernel found in rootfs" > "$BUILD_DIR/README.txt"
|
||||||
|
exit 0
|
||||||
echo "==> Install core packages inside chroot"
|
|
||||||
sudo chroot "${CHROOT_DIR}" bash -lc "apt-get update && apt-get install -y \
|
|
||||||
linux-image-generic \
|
|
||||||
systemd \
|
|
||||||
grub-efi-amd64 \
|
|
||||||
network-manager \
|
|
||||||
lightdm \
|
|
||||||
casper \
|
|
||||||
xwayland \
|
|
||||||
wayland-protocols \
|
|
||||||
mesa-utils \
|
|
||||||
pulseaudio \
|
|
||||||
sudo \
|
|
||||||
vim"
|
|
||||||
|
|
||||||
echo "==> Create default user and autologin"
|
|
||||||
sudo chroot "${CHROOT_DIR}" bash -lc "useradd -m -s /bin/bash aethex || true"
|
|
||||||
sudo chroot "${CHROOT_DIR}" bash -lc "echo 'aethex:aethex' | chpasswd"
|
|
||||||
sudo chroot "${CHROOT_DIR}" bash -lc "usermod -aG sudo,audio,video,plugdev aethex"
|
|
||||||
|
|
||||||
sudo tee "${CHROOT_DIR}/etc/lightdm/lightdm.conf" >/dev/null << 'EOF'
|
|
||||||
[Seat:*]
|
|
||||||
autologin-user=aethex
|
|
||||||
autologin-user-timeout=0
|
|
||||||
user-session=aethex
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "==> Add AeThex desktop service (placeholder)"
|
|
||||||
sudo tee "${CHROOT_DIR}/etc/systemd/system/aethex-desktop.service" >/dev/null << 'EOF'
|
|
||||||
[Unit]
|
|
||||||
Description=AeThex Desktop Environment (placeholder)
|
|
||||||
After=graphical.target
|
|
||||||
Requires=graphical.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=aethex
|
|
||||||
Environment=DISPLAY=:0
|
|
||||||
ExecStart=/bin/bash -lc "echo 'AeThex desktop placeholder running'; sleep infinity"
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=graphical.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "==> Enable service (record state)"
|
|
||||||
# Note: Enabling in chroot isn't necessary for live boot, but kept for completeness
|
|
||||||
sudo chroot "${CHROOT_DIR}" bash -lc "systemctl enable aethex-desktop.service || true"
|
|
||||||
|
|
||||||
echo "==> Prepare casper live content"
|
|
||||||
KERNEL_PATH="$(sudo chroot "${CHROOT_DIR}" bash -lc 'ls -1 /boot/vmlinuz-* | tail -n1')"
|
|
||||||
INITRD_PATH="$(sudo chroot "${CHROOT_DIR}" bash -lc 'ls -1 /boot/initrd.img-* | tail -n1')"
|
|
||||||
|
|
||||||
if [ -z "${KERNEL_PATH}" ] || [ -z "${INITRD_PATH}" ]; then
|
|
||||||
echo "❌ Kernel or initrd not found in chroot. Aborting ISO build."
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "==> Create filesystem.squashfs"
|
sudo cp "$KERNEL" "$ISO_DIR/casper/vmlinuz"
|
||||||
sudo mksquashfs "${CHROOT_DIR}" "${ISO_ROOT}/casper/filesystem.squashfs" -comp xz -e proc -e sys -e dev -wildcards
|
sudo cp "$INITRD" "$ISO_DIR/casper/initrd.img"
|
||||||
|
echo "[✓] Kernel: $(basename $KERNEL)"
|
||||||
|
echo "[✓] Initrd: $(basename $INITRD)"
|
||||||
|
|
||||||
echo "==> Copy kernel and initrd"
|
echo "[+] Creating squashfs (this may take 5-10 min)..."
|
||||||
sudo cp "${CHROOT_DIR}${KERNEL_PATH}" "${ISO_ROOT}/casper/vmlinuz"
|
sudo mksquashfs "$ROOTFS_DIR" "$ISO_DIR/casper/filesystem.squashfs" -b 1048576 -comp xz 2>&1 | tail -3
|
||||||
sudo cp "${CHROOT_DIR}${INITRD_PATH}" "${ISO_ROOT}/casper/initrd"
|
|
||||||
|
|
||||||
echo "==> Create GRUB configuration for live boot"
|
echo "[+] Setting up BIOS boot (isolinux)..."
|
||||||
sudo tee "${ISO_ROOT}/boot/grub/grub.cfg" >/dev/null << 'EOF'
|
cat > "$BUILD_DIR/isolinux.cfg" << 'EOF'
|
||||||
|
PROMPT 0
|
||||||
|
TIMEOUT 50
|
||||||
|
DEFAULT linux
|
||||||
|
|
||||||
|
LABEL linux
|
||||||
|
KERNEL /casper/vmlinuz
|
||||||
|
APPEND initrd=/casper/initrd.img boot=casper quiet splash
|
||||||
|
EOF
|
||||||
|
sudo cp "$BUILD_DIR/isolinux.cfg" "$ISO_DIR/isolinux/"
|
||||||
|
sudo cp /usr/lib/syslinux/isolinux.bin "$ISO_DIR/isolinux/" 2>/dev/null || echo "[!] isolinux.bin missing"
|
||||||
|
sudo cp /usr/lib/syslinux/ldlinux.c32 "$ISO_DIR/isolinux/" 2>/dev/null || echo "[!] ldlinux.c32 missing"
|
||||||
|
|
||||||
|
echo "[+] Setting up UEFI boot (GRUB)..."
|
||||||
|
cat > "$BUILD_DIR/grub.cfg" << 'EOF'
|
||||||
|
set timeout=10
|
||||||
set default=0
|
set default=0
|
||||||
set timeout=5
|
|
||||||
|
|
||||||
menuentry "Start AeThex Linux (Live)" {
|
menuentry 'AeThex OS' {
|
||||||
linux /casper/vmlinuz boot=casper quiet splash
|
linux /casper/vmlinuz boot=casper quiet splash
|
||||||
initrd /casper/initrd
|
initrd /casper/initrd.img
|
||||||
}
|
|
||||||
|
|
||||||
menuentry "Start AeThex Linux (Live, nomodeset)" {
|
|
||||||
linux /casper/vmlinuz boot=casper nomodeset quiet splash
|
|
||||||
initrd /casper/initrd
|
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
sudo cp "$BUILD_DIR/grub.cfg" "$ISO_DIR/boot/grub/"
|
||||||
|
|
||||||
echo "==> Build hybrid BIOS/UEFI ISO via grub-mkrescue"
|
echo "[+] Building hybrid ISO (BIOS + UEFI)..."
|
||||||
ISO_PATH="${WORKDIR}/${ISO_NAME}"
|
sudo grub-mkrescue -o "$BUILD_DIR/$ISO_NAME" "$ISO_DIR" 2>&1 | grep -E "done|error" || echo "[*] ISO generation in progress..."
|
||||||
sudo grub-mkrescue -o "${ISO_PATH}" "${ISO_ROOT}" || {
|
|
||||||
echo "❌ grub-mkrescue failed. Falling back to placeholder artifact."
|
|
||||||
echo "See AETHEX_LINUX.md for manual build instructions."
|
|
||||||
mkdir -p "${WORKDIR}"
|
|
||||||
echo "grub-mkrescue failed during CI build" > "${WORKDIR}/README.txt"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "==> Compute checksum"
|
echo "[+] Computing checksum..."
|
||||||
(cd "${WORKDIR}" && sha256sum "${ISO_NAME}" > SHA256)
|
if [ -f "$BUILD_DIR/$ISO_NAME" ]; then
|
||||||
cat "${WORKDIR}/SHA256"
|
cd "$BUILD_DIR"
|
||||||
|
sha256sum "$ISO_NAME" > SHA256
|
||||||
|
echo "[✓] ISO ready:"
|
||||||
|
ls -lh "$ISO_NAME" | awk '{print " Size: " $5}'
|
||||||
|
cat SHA256 | awk '{print " SHA256: " $1}'
|
||||||
|
echo "[✓] Location: $BUILD_DIR/$ISO_NAME"
|
||||||
|
else
|
||||||
|
echo "[!] ISO creation failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "==> Unmount chroot pseudo filesystems"
|
echo "[*] Cleaning up rootfs..."
|
||||||
set +e
|
sudo rm -rf "$ROOTFS_DIR"
|
||||||
sudo umount -lf "${CHROOT_DIR}/proc" 2>/dev/null || true
|
|
||||||
sudo umount -lf "${CHROOT_DIR}/sys" 2>/dev/null || true
|
|
||||||
sudo umount -lf "${CHROOT_DIR}/dev" 2>/dev/null || true
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "✅ ISO build complete: ${ISO_PATH}"
|
echo "[✓] Done!"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue