Files
kubesolo-os/build/scripts/create-disk-image.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

111 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# create-disk-image.sh — Create a raw disk image with boot + data partitions
# Phase 1: simple layout (boot + data). Phase 3 adds A/B system partitions.
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"
IMG_OUTPUT="$OUTPUT_DIR/${OS_NAME}-${VERSION}.img"
IMG_SIZE_MB="${IMG_SIZE_MB:-2048}" # 2 GB default
VMLINUZ="$ROOTFS_DIR/vmlinuz"
INITRAMFS="$ROOTFS_DIR/kubesolo-os.gz"
for f in "$VMLINUZ" "$INITRAMFS"; do
[ -f "$f" ] || { echo "ERROR: Missing $f — run 'make initramfs'"; exit 1; }
done
echo "==> Creating ${IMG_SIZE_MB}MB disk image..."
mkdir -p "$OUTPUT_DIR"
# Create sparse image
dd if=/dev/zero of="$IMG_OUTPUT" bs=1M count=0 seek="$IMG_SIZE_MB" 2>/dev/null
# Partition: 256MB boot (ext4) + rest data (ext4)
# Using sfdisk for scriptability
sfdisk "$IMG_OUTPUT" << EOF
label: dos
unit: sectors
# Boot partition: 256 MB, bootable
start=2048, size=524288, type=83, bootable
# Data partition: remaining space
start=526336, type=83
EOF
# Set up loop device
LOOP=$(losetup --show -fP "$IMG_OUTPUT")
echo "==> Loop device: $LOOP"
cleanup() {
umount "${LOOP}p1" 2>/dev/null || true
umount "${LOOP}p2" 2>/dev/null || true
losetup -d "$LOOP" 2>/dev/null || true
rm -rf "$MNT_BOOT" "$MNT_DATA" 2>/dev/null || true
}
trap cleanup EXIT
# Format partitions
mkfs.ext4 -q -L KSOLOBOOT "${LOOP}p1"
mkfs.ext4 -q -L KSOLODATA "${LOOP}p2"
# Mount and populate boot partition
MNT_BOOT=$(mktemp -d)
MNT_DATA=$(mktemp -d)
mount "${LOOP}p1" "$MNT_BOOT"
mount "${LOOP}p2" "$MNT_DATA"
# Install syslinux + kernel + initramfs to boot partition
mkdir -p "$MNT_BOOT/boot/syslinux"
cp "$VMLINUZ" "$MNT_BOOT/boot/vmlinuz"
cp "$INITRAMFS" "$MNT_BOOT/boot/kubesolo-os.gz"
# Syslinux config for disk boot (extlinux)
cat > "$MNT_BOOT/boot/syslinux/syslinux.cfg" << 'EOF'
DEFAULT kubesolo
TIMEOUT 30
PROMPT 0
LABEL kubesolo
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND quiet kubesolo.data=LABEL=KSOLODATA
LABEL kubesolo-debug
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND kubesolo.data=LABEL=KSOLODATA kubesolo.debug console=ttyS0,115200n8
LABEL kubesolo-shell
KERNEL /boot/vmlinuz
INITRD /boot/kubesolo-os.gz
APPEND kubesolo.shell console=ttyS0,115200n8
EOF
# Install extlinux bootloader
if command -v extlinux >/dev/null 2>&1; then
extlinux --install "$MNT_BOOT/boot/syslinux" 2>/dev/null || {
echo "WARN: extlinux install failed — image may not be directly bootable"
echo " Use with QEMU -kernel/-initrd flags instead"
}
fi
# Prepare data partition structure
for dir in kubesolo containerd etc-kubesolo log usr-local network; do
mkdir -p "$MNT_DATA/$dir"
done
sync
echo ""
echo "==> Disk image created: $IMG_OUTPUT"
echo " Size: $(du -h "$IMG_OUTPUT" | cut -f1)"
echo " Boot partition (KSOLOBOOT): kernel + initramfs"
echo " Data partition (KSOLODATA): persistent K8s state"