Files
kubesolo-os/Makefile
Adolfo Delorenzo d51618badb build: separate generic ARM64 from Raspberry Pi kernel builds
Splits the ARM64 build into two tracks per docs/arm64-architecture.md:

Generic ARM64 (mainline kernel.org, UEFI, virtio, GRUB):
- New build/scripts/build-kernel-arm64.sh builds mainline LTS (6.12.x by default)
  from arm64 defconfig + shared container fragment + arm64-virt enables
  (VIRTIO_*, EFI_STUB, NVMe). Output: build/cache/kernel-arm64-generic/.
- New Makefile targets: kernel-arm64, rootfs-arm64 (now consumes the mainline
  kernel modules via TARGET_VARIANT=generic).
- versions.env: pin MAINLINE_KERNEL_VERSION=6.12.10, declare cdn.kernel.org URL
  and SHA256 placeholder.

Raspberry Pi (raspberrypi/linux fork, custom DTBs, autoboot.txt):
- build-kernel-arm64.sh (RPi-flavoured) renamed to build-kernel-rpi.sh; cache
  dir renamed from custom-kernel-arm64 to custom-kernel-rpi.
- New Makefile targets: kernel-rpi, rootfs-arm64-rpi (uses TARGET_VARIANT=rpi).
- rpi-image now depends on rootfs-arm64-rpi + kernel-rpi instead of the generic
  rootfs-arm64.
- create-rpi-image.sh + inject-kubesolo.sh updated to reference the new cache
  path. inject-kubesolo.sh now takes a TARGET_VARIANT env var (rpi|generic) to
  select which ARM64 kernel modules to consume.

Shared substrate:
- rpi-kernel-config.fragment renamed to kernel-container.fragment. The contents
  were never RPi-specific (cgroup, namespaces, AppArmor, netfilter) — just
  misnamed. Extended with extra subsystem disables (KVM, WLAN, CFG80211,
  INFINIBAND, PCMCIA, HAMRADIO, ISDN, ATM, INPUT_JOYSTICK, INPUT_TABLET, FPGA)
  and CONFIG_LSM=lockdown,yama,apparmor.
- build-kernel.sh (x86) refactored to apply the shared fragment via a generic
  apply_fragment function (two-pass for the TC stock config security dance),
  killing ~50 lines of inline config duplication.

Note: rename detection shows build-kernel-arm64.sh as 'modified' because the
new file at that path is the mainline build, while the old RPi-flavoured
content lives in build-kernel-rpi.sh (which appears as a new file). The git
log for build-kernel-rpi.sh is empty; the RPi history is preserved at the
original path until this commit.

No actual kernel build runs in this commit — that's Phase 3 work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 10:30:11 -06:00

303 lines
12 KiB
Makefile

.PHONY: all fetch kernel build-cloudinit build-update-agent build-cross rootfs initramfs \
iso disk-image oci-image rpi-image \
kernel-arm64 kernel-rpi rootfs-arm64 rootfs-arm64-rpi \
test-boot test-k8s test-persistence test-deploy test-storage test-security test-all \
test-boot-arm64 test-cloudinit test-update-agent \
bench-boot bench-resources \
dev-vm dev-vm-shell dev-vm-arm64 quick docker-build shellcheck \
kernel-audit clean distclean help
SHELL := /bin/bash
VERSION := $(shell cat VERSION)
BUILD_DIR := build
CACHE_DIR := $(BUILD_DIR)/cache
OUTPUT_DIR := output
ROOTFS_DIR := $(BUILD_DIR)/rootfs-work
# Load component versions
include $(BUILD_DIR)/config/versions.env
# Default target
all: iso
# =============================================================================
# Download external components
# =============================================================================
fetch:
@echo "==> Fetching components..."
@mkdir -p $(CACHE_DIR)
$(BUILD_DIR)/scripts/fetch-components.sh
# =============================================================================
# Build stages
# =============================================================================
kernel:
@echo "==> Building custom kernel (CONFIG_CGROUP_BPF=y)..."
$(BUILD_DIR)/scripts/build-kernel.sh
build-cloudinit:
@echo "==> Building cloud-init binary..."
$(BUILD_DIR)/scripts/build-cloudinit.sh
build-update-agent:
@echo "==> Building update agent..."
$(BUILD_DIR)/scripts/build-update-agent.sh
rootfs: fetch kernel build-cloudinit build-update-agent
@echo "==> Preparing rootfs..."
$(BUILD_DIR)/scripts/extract-core.sh
$(BUILD_DIR)/scripts/inject-kubesolo.sh
initramfs: rootfs
@echo "==> Packing initramfs..."
$(BUILD_DIR)/scripts/pack-initramfs.sh
iso: initramfs
@echo "==> Creating bootable ISO..."
$(BUILD_DIR)/scripts/create-iso.sh
@echo "==> Built: $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso"
disk-image: initramfs
@echo "==> Creating disk image..."
$(BUILD_DIR)/scripts/create-disk-image.sh
@echo "==> Built: $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).img"
oci-image: initramfs
@echo "==> Creating OCI container image..."
$(BUILD_DIR)/scripts/create-oci-image.sh
@echo "==> OCI image built"
# Cross-compile Go binaries for amd64 + arm64
build-cross:
@echo "==> Cross-compiling for amd64 + arm64..."
$(BUILD_DIR)/scripts/build-cross.sh
# =============================================================================
# ARM64 generic targets (mainline kernel, UEFI, virtio — for cloud / SBCs)
# =============================================================================
kernel-arm64:
@echo "==> Building generic ARM64 kernel (mainline LTS)..."
$(BUILD_DIR)/scripts/build-kernel-arm64.sh
# Generic ARM64 rootfs consumes the mainline kernel modules.
rootfs-arm64: build-cross
@echo "==> Preparing generic ARM64 rootfs..."
TARGET_ARCH=arm64 $(BUILD_DIR)/scripts/fetch-components.sh
TARGET_ARCH=arm64 $(BUILD_DIR)/scripts/extract-core.sh
TARGET_ARCH=arm64 TARGET_VARIANT=generic $(BUILD_DIR)/scripts/inject-kubesolo.sh
@echo "==> Packing generic ARM64 initramfs..."
$(BUILD_DIR)/scripts/pack-initramfs.sh
# =============================================================================
# ARM64 Raspberry Pi targets (RPi-patched kernel, firmware blobs, SD card)
# =============================================================================
kernel-rpi:
@echo "==> Building RPi kernel (raspberrypi/linux)..."
$(BUILD_DIR)/scripts/build-kernel-rpi.sh
# RPi-flavoured rootfs consumes the RPi kernel modules.
rootfs-arm64-rpi: build-cross
@echo "==> Preparing RPi ARM64 rootfs..."
TARGET_ARCH=arm64 $(BUILD_DIR)/scripts/fetch-components.sh
TARGET_ARCH=arm64 $(BUILD_DIR)/scripts/extract-core.sh
TARGET_ARCH=arm64 TARGET_VARIANT=rpi $(BUILD_DIR)/scripts/inject-kubesolo.sh
@echo "==> Packing RPi ARM64 initramfs..."
$(BUILD_DIR)/scripts/pack-initramfs.sh
rpi-image: rootfs-arm64-rpi kernel-rpi
@echo "==> Creating Raspberry Pi SD card image..."
$(BUILD_DIR)/scripts/create-rpi-image.sh
@echo "==> Built: $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).rpi.img"
# =============================================================================
# Kernel validation
# =============================================================================
kernel-audit:
@echo "==> Auditing kernel configuration..."
$(BUILD_DIR)/config/kernel-audit.sh
# =============================================================================
# Testing
# =============================================================================
test-boot: iso
@echo "==> Testing boot in QEMU..."
test/qemu/test-boot.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
test-k8s: iso
@echo "==> Testing K8s readiness..."
test/integration/test-k8s-ready.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
test-persistence: disk-image
@echo "==> Testing persistence across reboot..."
test/qemu/test-persistence.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).img
test-deploy: iso
@echo "==> Testing workload deployment..."
test/integration/test-deploy-workload.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
test-storage: iso
@echo "==> Testing local storage provisioning..."
test/integration/test-local-storage.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
test-security: iso
@echo "==> Testing security hardening..."
test/integration/test-security-hardening.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
test-boot-arm64:
@echo "==> Testing ARM64 boot in QEMU..."
test/qemu/test-boot-arm64.sh
test-all: test-boot test-k8s test-persistence
# Cloud-init Go tests
test-cloudinit:
@echo "==> Testing cloud-init parser..."
cd cloud-init && go test ./... -v -count=1
# Update agent Go tests
test-update-agent:
@echo "==> Testing update agent..."
cd update && go test ./... -v -count=1
# A/B update integration tests
test-update: disk-image
@echo "==> Testing A/B update cycle..."
test/qemu/test-update.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).img
test-rollback: disk-image
@echo "==> Testing rollback..."
test/qemu/test-rollback.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).img
# Full integration test suite (requires more time)
test-integration: test-k8s test-deploy test-storage
# Benchmarks
bench-boot: iso
@echo "==> Benchmarking boot performance..."
test/benchmark/bench-boot.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso --runs 3
bench-resources:
@echo "==> Benchmarking resource usage (requires running VM)..."
test/benchmark/bench-resources.sh
# =============================================================================
# Code quality
# =============================================================================
shellcheck:
@echo "==> Running shellcheck on init scripts..."
shellcheck -s sh init/init.sh init/lib/*.sh init/emergency-shell.sh
@echo "==> Running shellcheck on build scripts..."
shellcheck -s bash build/scripts/*.sh build/config/kernel-audit.sh
@echo "==> Running shellcheck on test scripts..."
shellcheck -s bash test/qemu/*.sh test/integration/*.sh test/kernel/*.sh
@echo "==> Running shellcheck on hack scripts..."
shellcheck -s bash hack/*.sh
@echo "==> All shellcheck checks passed"
# =============================================================================
# Development helpers
# =============================================================================
dev-vm: iso
@echo "==> Launching dev VM..."
hack/dev-vm.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso
dev-vm-shell: iso
@echo "==> Launching dev VM (emergency shell)..."
hack/dev-vm.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso --shell
dev-vm-debug: iso
@echo "==> Launching dev VM (debug mode)..."
hack/dev-vm.sh $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso --debug
dev-vm-arm64:
@echo "==> Launching ARM64 dev VM..."
hack/dev-vm-arm64.sh
# Fast rebuild: only repack initramfs + ISO (skip fetch/extract)
quick:
@echo "==> Quick rebuild (repack + ISO only)..."
$(BUILD_DIR)/scripts/inject-kubesolo.sh
$(BUILD_DIR)/scripts/pack-initramfs.sh
$(BUILD_DIR)/scripts/create-iso.sh
@echo "==> Quick rebuild complete: $(OUTPUT_DIR)/$(OS_NAME)-$(VERSION).iso"
# =============================================================================
# Docker-based reproducible build
# =============================================================================
docker-build:
@echo "==> Building in Docker..."
docker build -t kubesolo-os-builder -f $(BUILD_DIR)/Dockerfile.builder .
docker run --rm --privileged \
-v $(PWD)/$(OUTPUT_DIR):/output \
-v $(PWD)/$(CACHE_DIR):/cache \
kubesolo-os-builder iso OUTPUT_DIR=/output CACHE_DIR=/cache
# =============================================================================
# Cleanup
# =============================================================================
clean:
@echo "==> Cleaning build artifacts..."
rm -rf $(ROOTFS_DIR) $(OUTPUT_DIR)
@echo "==> Clean. (Cache preserved in $(CACHE_DIR); use 'make distclean' to remove)"
distclean: clean
rm -rf $(CACHE_DIR)
# =============================================================================
# Help
# =============================================================================
help:
@echo "KubeSolo OS Build System (v$(VERSION))"
@echo ""
@echo "Build targets (x86_64):"
@echo " make fetch Download Tiny Core ISO, KubeSolo, dependencies"
@echo " make kernel Build custom kernel with CONFIG_CGROUP_BPF=y"
@echo " make build-cloudinit Build cloud-init Go binary"
@echo " make build-update-agent Build update agent Go binary"
@echo " make rootfs Extract + prepare rootfs with KubeSolo"
@echo " make initramfs Repack rootfs into kubesolo-os.gz"
@echo " make iso Create bootable ISO (default target)"
@echo " make disk-image Create raw disk image with A/B partitions + GRUB"
@echo " make oci-image Create OCI container image for registry distribution"
@echo " make build-cross Cross-compile Go binaries for amd64 + arm64"
@echo " make quick Fast rebuild (re-inject + repack + ISO only)"
@echo " make docker-build Reproducible build inside Docker"
@echo ""
@echo "Build targets (ARM64 generic — UEFI / cloud / SBCs):"
@echo " make kernel-arm64 Build mainline ARM64 kernel from kernel.org LTS"
@echo " make rootfs-arm64 Prepare generic ARM64 rootfs (mainline kernel modules)"
@echo ""
@echo "Build targets (ARM64 Raspberry Pi):"
@echo " make kernel-rpi Build RPi kernel from raspberrypi/linux"
@echo " make rootfs-arm64-rpi Prepare RPi-flavoured rootfs (RPi kernel modules)"
@echo " make rpi-image Create Raspberry Pi SD card image with A/B autoboot"
@echo ""
@echo "Test targets:"
@echo " make test-boot Boot ISO in QEMU, verify boot success"
@echo " make test-k8s Boot + verify K8s node reaches Ready"
@echo " make test-persist Reboot disk image, verify state persists"
@echo " make test-deploy Deploy nginx pod, verify Running"
@echo " make test-storage Test PVC with local-path provisioner"
@echo " make test-security Verify security hardening (AppArmor, sysctl, mounts)"
@echo " make test-cloudinit Run cloud-init Go unit tests"
@echo " make test-update-agent Run update agent Go unit tests"
@echo " make test-update A/B update cycle integration test"
@echo " make test-rollback Forced rollback integration test"
@echo " make test-boot-arm64 ARM64 boot test in QEMU aarch64"
@echo " make test-all Run core tests (boot + k8s + persistence)"
@echo " make test-integ Run full integration suite"
@echo " make bench-boot Benchmark boot performance (3 runs)"
@echo " make bench-resources Benchmark resource usage (requires running VM)"
@echo ""
@echo "Dev targets:"
@echo " make dev-vm Launch interactive QEMU VM (x86_64)"
@echo " make dev-vm-shell Launch QEMU VM -> emergency shell"
@echo " make dev-vm-debug Launch QEMU VM with debug logging"
@echo " make dev-vm-arm64 Launch ARM64 QEMU VM"
@echo " make kernel-audit Check kernel config against requirements"
@echo " make shellcheck Lint all shell scripts"
@echo ""
@echo "Cleanup:"
@echo " make clean Remove build artifacts (preserve cache)"
@echo " make distclean Remove everything including cache"