Files
kubesolo-os/build/scripts/create-iso.sh
Adolfo Delorenzo e372df578b feat: initial Phase 1 PoC scaffolding for KubeSolo OS
Complete Phase 1 implementation of KubeSolo OS — an immutable, bootable
Linux distribution built on Tiny Core Linux for running KubeSolo
single-node Kubernetes.

Build system:
- Makefile with fetch, rootfs, initramfs, iso, disk-image targets
- Dockerfile.builder for reproducible builds
- Scripts to download Tiny Core, extract rootfs, inject KubeSolo,
  pack initramfs, and create bootable ISO/disk images

Init system (10 POSIX sh stages):
- Early mount (proc/sys/dev/cgroup2), cmdline parsing, persistent
  mount with bind-mounts, kernel module loading, sysctl, DHCP
  networking, hostname, clock sync, containerd prep, KubeSolo exec

Shared libraries:
- functions.sh (device wait, IP lookup, config helpers)
- network.sh (static IP, config persistence, interface detection)
- health.sh (containerd, API server, node readiness checks)
- Emergency shell for boot failure debugging

Testing:
- QEMU boot test with serial log marker detection
- K8s readiness test with kubectl verification
- Persistence test (reboot + verify state survives)
- Workload deployment test (nginx pod)
- Local storage test (PVC + local-path provisioner)
- Network policy test
- Reusable run-vm.sh launcher

Developer tools:
- dev-vm.sh (interactive QEMU with port forwarding)
- rebuild-initramfs.sh (fast iteration)
- inject-ssh.sh (dropbear SSH for debugging)
- extract-kernel-config.sh + kernel-audit.sh

Documentation:
- Full design document with architecture research
- Boot flow documentation covering all 10 init stages
- Cloud-init examples (DHCP, static IP, Portainer Edge, air-gapped)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 10:18:42 -06:00

141 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
# create-iso.sh — Create a bootable ISO from kernel + initramfs
# Uses isolinux (syslinux) for Phase 1 simplicity (GRUB in Phase 3)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
ROOTFS_DIR="${ROOTFS_DIR:-$PROJECT_ROOT/build/rootfs-work}"
OUTPUT_DIR="${OUTPUT_DIR:-$PROJECT_ROOT/output}"
VERSION="$(cat "$PROJECT_ROOT/VERSION")"
OS_NAME="kubesolo-os"
ISO_STAGING="$ROOTFS_DIR/iso-staging"
ISO_OUTPUT="$OUTPUT_DIR/${OS_NAME}-${VERSION}.iso"
VMLINUZ="$ROOTFS_DIR/vmlinuz"
INITRAMFS="$ROOTFS_DIR/kubesolo-os.gz"
# Validate inputs
for f in "$VMLINUZ" "$INITRAMFS"; do
if [ ! -f "$f" ]; then
echo "ERROR: Missing required file: $f"
echo "Run 'make initramfs' first."
exit 1
fi
done
# Check for required tools
for cmd in mkisofs xorriso genisoimage; do
if command -v "$cmd" >/dev/null 2>&1; then
MKISO_CMD="$cmd"
break
fi
done
if [ -z "${MKISO_CMD:-}" ]; then
echo "ERROR: Need mkisofs, genisoimage, or xorriso to create ISO"
exit 1
fi
# --- Stage ISO contents ---
rm -rf "$ISO_STAGING"
mkdir -p "$ISO_STAGING/boot/isolinux"
cp "$VMLINUZ" "$ISO_STAGING/boot/vmlinuz"
cp "$INITRAMFS" "$ISO_STAGING/boot/kubesolo-os.gz"
# Find isolinux.bin
ISOLINUX_BIN=""
for path in /usr/lib/ISOLINUX/isolinux.bin /usr/lib/syslinux/isolinux.bin \
/usr/share/syslinux/isolinux.bin /usr/lib/syslinux/bios/isolinux.bin; do
[ -f "$path" ] && ISOLINUX_BIN="$path" && break
done
if [ -z "$ISOLINUX_BIN" ]; then
echo "ERROR: Cannot find isolinux.bin. Install syslinux/isolinux package."
exit 1
fi
cp "$ISOLINUX_BIN" "$ISO_STAGING/boot/isolinux/"
# Copy ldlinux.c32 if it exists (needed by syslinux 6+)
LDLINUX_DIR="$(dirname "$ISOLINUX_BIN")"
for mod in ldlinux.c32 libcom32.c32 libutil.c32 mboot.c32; do
[ -f "$LDLINUX_DIR/$mod" ] && cp "$LDLINUX_DIR/$mod" "$ISO_STAGING/boot/isolinux/"
done
# Isolinux config
cat > "$ISO_STAGING/boot/isolinux/isolinux.cfg" << 'EOF'
DEFAULT kubesolo
TIMEOUT 30
PROMPT 0
LABEL kubesolo
MENU LABEL KubeSolo OS
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND quiet kubesolo.data=LABEL=KSOLODATA
LABEL kubesolo-debug
MENU LABEL KubeSolo OS (debug)
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND kubesolo.data=LABEL=KSOLODATA kubesolo.debug console=ttyS0,115200n8
LABEL kubesolo-shell
MENU LABEL KubeSolo OS (emergency shell)
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND kubesolo.shell console=ttyS0,115200n8
LABEL kubesolo-nopersist
MENU LABEL KubeSolo OS (RAM only, no persistence)
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND kubesolo.nopersist
EOF
# --- Create ISO ---
mkdir -p "$OUTPUT_DIR"
case "$MKISO_CMD" in
xorriso)
xorriso -as mkisofs \
-o "$ISO_OUTPUT" \
-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin 2>/dev/null || true \
-c boot/isolinux/boot.cat \
-b boot/isolinux/isolinux.bin \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
"$ISO_STAGING"
;;
*)
"$MKISO_CMD" \
-o "$ISO_OUTPUT" \
-b boot/isolinux/isolinux.bin \
-c boot/isolinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-J -R -V "KUBESOLOOS" \
"$ISO_STAGING"
;;
esac
# Make ISO hybrid-bootable (USB stick)
if command -v isohybrid >/dev/null 2>&1; then
isohybrid "$ISO_OUTPUT" 2>/dev/null || true
fi
# Clean staging
rm -rf "$ISO_STAGING"
echo ""
echo "==> ISO created: $ISO_OUTPUT"
echo " Size: $(du -h "$ISO_OUTPUT" | cut -f1)"
echo ""
echo " Boot in QEMU: make dev-vm"
echo " Write to USB: dd if=$ISO_OUTPUT of=/dev/sdX bs=4M status=progress"