Two complementary fixes after end-to-end local installer build: 1. New talos/0001 patch — Replace hack/modules-arm64.txt with the intersection of upstream's initramfs list and our RPi 6.12.47 build's actual modules (155 entries, down from upstream's 241). Initramfs target was failing with exit 123 in xargs install -D because upstream lists modules our kernel doesn't build (SATA, HID device drivers, some upstream-only crypto helpers). 2. Makefile: add --network=host to the metal docker run. The installer step already had it, but the metal step did not. For local-registry builds (REGISTRY=127.0.0.1:5001), the imager container needs --network=host to reach the host's registry to pull the overlay image when generating the raw disk image. Harmless on CI (no behavioural change against docker.io). Validated locally end-to-end: - kernel image: 234MB (RPi 6.12.47 with RP1 driver support) - overlay image: 9.7MB (U-Boot + firmware + DTBs) - imager image: 346MB - installer-base: 105MB - installer: ~100MB - metal-arm64.raw.zst: 94MB (final flashable disk image)
218 lines
7.9 KiB
Makefile
218 lines
7.9 KiB
Makefile
# Talos CM5 Builder — Custom Talos Linux images for Raspberry Pi CM5
|
|
#
|
|
# Forked from https://github.com/talos-rpi5/talos-builder
|
|
# Builds Talos with the RPi downstream kernel (CM5/RP1 support)
|
|
#
|
|
# Usage:
|
|
# make checkouts patches # Clone and patch upstream sources
|
|
# make kernel # Build RPi kernel (~15-30 min on ARM64)
|
|
# make overlay # Build U-Boot + firmware + DTBs
|
|
# make installer # Build installer image + raw disk image
|
|
# make release # Tag and push release images
|
|
# make clean # Remove checkouts and build artifacts
|
|
|
|
PKG_VERSION = v1.13.0
|
|
TALOS_VERSION = v1.13.2
|
|
SBCOVERLAY_VERSION = main
|
|
|
|
# Prefer GNU coreutils (macOS: brew install gnu-sed coreutils)
|
|
export PATH := /opt/homebrew/opt/gnu-sed/libexec/gnubin:$(PATH)
|
|
|
|
REGISTRY ?= docker.io
|
|
REGISTRY_USERNAME ?= svrnty
|
|
|
|
TAG ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev)
|
|
|
|
# Docker Hub image names (project-specific)
|
|
KERNEL_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-kernel
|
|
OVERLAY_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-overlay
|
|
IMAGER_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-imager
|
|
INSTALLER_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-installer
|
|
|
|
# Public image name on Docker Hub (used by talosctl upgrade)
|
|
IMAGE_NAME ?= talos-rpi5
|
|
|
|
# System extensions baked into the image
|
|
EXTENSIONS ?= ghcr.io/siderolabs/iscsi-tools:v0.1.6 ghcr.io/siderolabs/util-linux-tools:2.40.4
|
|
|
|
# Upstream repositories
|
|
PKG_REPOSITORY = https://github.com/siderolabs/pkgs.git
|
|
TALOS_REPOSITORY = https://github.com/siderolabs/talos.git
|
|
SBCOVERLAY_REPOSITORY = https://github.com/talos-rpi5/sbc-raspberrypi5.git
|
|
|
|
CHECKOUTS_DIRECTORY := $(PWD)/checkouts
|
|
PATCHES_DIRECTORY := $(PWD)/patches
|
|
|
|
PKGS_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/pkgs && git describe --tag --always --dirty --match v[0-9]\*)
|
|
TALOS_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/talos && git describe --tag --always --dirty --match v[0-9]\*)
|
|
SBCOVERLAY_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5 && git describe --tag --always)-$(PKGS_TAG)
|
|
|
|
# Build the --system-extension-image flags from the EXTENSIONS list
|
|
EXTENSION_FLAGS = $(foreach ext,$(EXTENSIONS),--system-extension-image=$(ext))
|
|
|
|
# Supply chain attestation flags (overrides upstream --provenance=false)
|
|
ATTESTATION_ARGS = --provenance=mode=max --sbom=true
|
|
|
|
# Common imager flags for overlay and extensions
|
|
IMAGER_COMMON_FLAGS = \
|
|
--overlay-name="rpi5" \
|
|
--overlay-image="$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG)" \
|
|
--overlay-option="configTxtAppend=$$(cat $(PWD)/config/config.txt.append)" \
|
|
$(EXTENSION_FLAGS)
|
|
|
|
#
|
|
# Help
|
|
#
|
|
.PHONY: help
|
|
help:
|
|
@echo "Talos CM5 Builder"
|
|
@echo ""
|
|
@echo "Targets:"
|
|
@echo " checkouts — Clone upstream repositories"
|
|
@echo " patches — Apply RPi kernel + CM5 patches"
|
|
@echo " kernel — Build RPi downstream kernel"
|
|
@echo " overlay — Build SBC overlay (U-Boot, firmware, DTBs)"
|
|
@echo " installer — Build Talos installer image + raw disk image"
|
|
@echo " release — Tag and push release images"
|
|
@echo " clean — Remove checkouts and build artifacts"
|
|
@echo ""
|
|
@echo "Variables:"
|
|
@echo " TALOS_VERSION = $(TALOS_VERSION)"
|
|
@echo " PKG_VERSION = $(PKG_VERSION)"
|
|
@echo " REGISTRY = $(REGISTRY)"
|
|
@echo " REGISTRY_USERNAME = $(REGISTRY_USERNAME)"
|
|
@echo ""
|
|
@echo "Images:"
|
|
@echo " KERNEL_IMAGE = $(KERNEL_IMAGE)"
|
|
@echo " OVERLAY_IMAGE = $(OVERLAY_IMAGE)"
|
|
@echo " IMAGER_IMAGE = $(IMAGER_IMAGE)"
|
|
@echo " INSTALLER_IMAGE = $(INSTALLER_IMAGE)"
|
|
|
|
#
|
|
# Checkouts
|
|
#
|
|
.PHONY: checkouts checkouts-clean
|
|
checkouts:
|
|
git clone -c advice.detachedHead=false --branch "$(PKG_VERSION)" "$(PKG_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/pkgs"
|
|
git clone -c advice.detachedHead=false --branch "$(TALOS_VERSION)" "$(TALOS_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/talos"
|
|
git clone -c advice.detachedHead=false --branch "$(SBCOVERLAY_VERSION)" "$(SBCOVERLAY_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5"
|
|
|
|
checkouts-clean:
|
|
rm -rf "$(CHECKOUTS_DIRECTORY)/pkgs"
|
|
rm -rf "$(CHECKOUTS_DIRECTORY)/talos"
|
|
rm -rf "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5"
|
|
|
|
#
|
|
# Patches
|
|
#
|
|
.PHONY: patches-pkgs patches-talos patches-overlay patches
|
|
patches-pkgs:
|
|
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
|
|
git am "$(PATCHES_DIRECTORY)/siderolabs/pkgs/"*.patch
|
|
|
|
patches-talos:
|
|
cd "$(CHECKOUTS_DIRECTORY)/talos" && \
|
|
git am "$(PATCHES_DIRECTORY)/siderolabs/talos/"*.patch
|
|
|
|
patches-overlay:
|
|
@cd "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5" && \
|
|
GO_VER=$$(sed -n 's/^go //p' go.work | head -1) && \
|
|
GO_MINOR=$$(echo "$$GO_VER" | cut -d. -f1,2) && \
|
|
if [ "$$GO_MINOR" = "1.24" ]; then \
|
|
echo "Overlay Go $$GO_VER — applying Go toolchain patch (CVE fix)"; \
|
|
git am "$(PATCHES_DIRECTORY)/talos-rpi5/sbc-raspberrypi5/0001-"*.patch; \
|
|
else \
|
|
echo "Overlay Go $$GO_VER — skipping Go toolchain patch (CVEs fixed upstream)"; \
|
|
fi && \
|
|
git am "$(PATCHES_DIRECTORY)/talos-rpi5/sbc-raspberrypi5/0002-"*.patch
|
|
|
|
patches: patches-pkgs patches-talos patches-overlay
|
|
|
|
#
|
|
# Kernel — build and push the RPi downstream kernel
|
|
#
|
|
.PHONY: kernel
|
|
kernel:
|
|
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
|
|
$(MAKE) docker-kernel \
|
|
TARGET_ARGS="--tag=$(KERNEL_IMAGE):$(PKGS_TAG) --push=true $(ATTESTATION_ARGS)" \
|
|
PLATFORM=linux/arm64
|
|
|
|
#
|
|
# Overlay — build U-Boot + firmware + DTBs
|
|
#
|
|
# The overlay's pkg.yaml references the kernel as PKGS_PREFIX/kernel:PKGS.
|
|
# We rewrite it to point to our project-specific kernel image name.
|
|
#
|
|
.PHONY: overlay
|
|
overlay:
|
|
@echo "SBCOVERLAY_TAG = $(SBCOVERLAY_TAG)"
|
|
@sed -i.bak 's|{{ .BUILD_ARG_PKGS_PREFIX }}/kernel:{{ .BUILD_ARG_PKGS }}|$(KERNEL_IMAGE):$(PKGS_TAG)|' \
|
|
"$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5/internal/base/pkg.yaml" && \
|
|
rm -f "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5/internal/base/pkg.yaml.bak"
|
|
cd "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5" && \
|
|
$(MAKE) docker-sbc-raspberrypi5 \
|
|
TARGET_ARGS="--tag=$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG) --push=true $(ATTESTATION_ARGS)" \
|
|
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64
|
|
|
|
#
|
|
# Installer / Disk Image
|
|
#
|
|
# Builds the imager, installer-base, and installer images step by step,
|
|
# pushing each to our project-specific Docker Hub repos.
|
|
#
|
|
.PHONY: installer
|
|
installer:
|
|
cd "$(CHECKOUTS_DIRECTORY)/talos" && \
|
|
$(MAKE) \
|
|
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
|
|
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
|
|
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
|
|
kernel initramfs && \
|
|
$(MAKE) \
|
|
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
|
|
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
|
|
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
|
|
target-imager \
|
|
TARGET_ARGS="--output type=image,name=$(IMAGER_IMAGE):$(TALOS_TAG),push=true $(ATTESTATION_ARGS)" && \
|
|
$(MAKE) \
|
|
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
|
|
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
|
|
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
|
|
target-installer-base \
|
|
TARGET_ARGS="--output type=image,name=$(INSTALLER_IMAGE):base-$(TALOS_TAG),push=true $(ATTESTATION_ARGS)" && \
|
|
docker pull $(IMAGER_IMAGE):$(TALOS_TAG) && \
|
|
docker run --rm -t -v ./_out:/out --privileged --network=host \
|
|
$(IMAGER_IMAGE):$(TALOS_TAG) \
|
|
installer --arch arm64 \
|
|
--base-installer-image="$(INSTALLER_IMAGE):base-$(TALOS_TAG)" \
|
|
$(IMAGER_COMMON_FLAGS) && \
|
|
crane push ./_out/installer-arm64.tar $(INSTALLER_IMAGE):$(TALOS_TAG) && \
|
|
printf "FROM $(INSTALLER_IMAGE):$(TALOS_TAG)\n" | docker buildx build \
|
|
--platform linux/arm64 \
|
|
$(ATTESTATION_ARGS) \
|
|
-t $(INSTALLER_IMAGE):$(TALOS_TAG) --push - && \
|
|
docker \
|
|
run --rm -t -v ./_out:/out -v /dev:/dev --privileged --network=host \
|
|
$(IMAGER_IMAGE):$(TALOS_TAG) \
|
|
metal --arch arm64 \
|
|
--base-installer-image="$(INSTALLER_IMAGE):$(TALOS_TAG)" \
|
|
$(IMAGER_COMMON_FLAGS)
|
|
|
|
#
|
|
# Release — tag images with the Git tag for stable references
|
|
#
|
|
.PHONY: release
|
|
release:
|
|
docker buildx imagetools create \
|
|
-t $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) \
|
|
$(INSTALLER_IMAGE):$(TALOS_TAG)
|
|
|
|
#
|
|
# Clean
|
|
#
|
|
.PHONY: clean
|
|
clean: checkouts-clean
|
|
rm -rf _out
|
|
rm -rf checkouts/_out
|