rfs(firmware): pack full Alpine linux-firmware set from container and overmount /lib/firmware

Change pack source: install all linux-firmware* packages in container and pack from /lib/firmware via [bash.rfs_common_install_all_alpine_firmware_packages()](scripts/rfs/common.sh:290) used by [bash.pack-firmware.sh](scripts/rfs/pack-firmware.sh:21). At runtime, overmount firmware flist on /lib/firmware by updating [sh.firmware.sh](config/zinit/init/firmware.sh:10). Update docs to reflect /lib/firmware mount and new pack strategy.
This commit is contained in:
2025-09-19 08:27:10 +02:00
parent 79ed723303
commit 310e11d2bf
5 changed files with 100 additions and 13 deletions

View File

@@ -287,6 +287,92 @@ rfs_common_validate_modules_metadata() {
fi
}
# -----------------------------------------------------------------------------
# Alpine firmware installation in container (for flist packing)
# -----------------------------------------------------------------------------
# Install all available linux-firmware* packages into the build container root.
# This prepares a full /lib/firmware tree to be packed into an RFS flist.
# Notes:
# - Requires root inside the container (the builder image runs scripts as root).
# - Uses apk search to enumerate all linux-firmware packages; installs them all.
rfs_common_install_all_alpine_firmware_packages() {
log_info "Installing all Alpine linux-firmware* packages into container (/lib/firmware)"
# Ensure apk index is fresh
safe_execute apk update
# Enumerate firmware packages. Output of 'apk search' looks like:
# linux-firmware-rtl_nic-20231030-r0
# Strip version suffix to get the package names acceptable to apk add.
local pkgs_raw
pkgs_raw="$(apk search 'linux-firmware*' 2>/dev/null || true)"
if [[ -z "${pkgs_raw// }" ]]; then
log_warn "No linux-firmware* packages found via apk search"
fi
# Build unique package list without versions
# 1) take first column (package-with-version)
# 2) strip trailing '-<digits...>' (version/revision)
# 3) dedupe
local pkgs=()
while IFS= read -r line; do
[[ -z "${line// }" ]] && continue
local name="${line%% *}"
name="$(echo "$name" | sed -E 's/-[0-9].*$//')"
if [[ -n "$name" ]]; then
pkgs+=("$name")
fi
done <<< "$pkgs_raw"
if [[ ${#pkgs[@]} -eq 0 ]]; then
log_warn "Firmware package list is empty after parsing; attempting base meta-package 'linux-firmware'"
pkgs=("linux-firmware")
fi
# Deduplicate while preserving order
local seen="" final_pkgs=()
for p in "${pkgs[@]}"; do
if ! grep -qx "$p" <<< "$seen"; then
final_pkgs+=("$p")
seen+=$'\n'"$p"
fi
done
log_info "Installing ${#final_pkgs[@]} firmware packages:"
for p in "${final_pkgs[@]}"; do
log_info " - $p"
done
# Install all firmware packages; allow some failures (not all subpackages exist on all arches)
local failed=()
for p in "${final_pkgs[@]}"; do
if apk add --no-cache "$p" >/dev/null 2>&1; then
log_debug "Installed: $p"
else
log_warn "Failed to install: $p"
failed+=("$p")
fi
done
# Quick check that /lib/firmware exists and is populated
if [[ -d "/lib/firmware" ]]; then
local cnt
cnt=$(find /lib/firmware -type f | wc -l || echo 0)
log_info "/lib/firmware population: ${cnt} files"
if [[ "$cnt" -eq 0 ]]; then
log_warn "/lib/firmware exists but is empty after installation"
fi
else
log_error "/lib/firmware directory not found after firmware installation"
return 1
fi
if [[ ${#failed[@]} -gt 0 ]]; then
log_warn "Some firmware packages failed to install (${#failed[@]} failures); proceeding with available set"
fi
return 0
}
# -----------------------------------------------------------------------------
# Manifest patching (sqlite .fl)
# -----------------------------------------------------------------------------

View File

@@ -1,10 +1,8 @@
#!/bin/bash
# Pack firmware tree into an RFS flist and patch manifest stores for Garage web endpoint.
# - Computes FULL_KERNEL_VERSION from configs (not strictly needed for firmware, but kept uniform)
# - Selects firmware directory with priority:
# 1) $PROJECT_ROOT/firmware
# 2) $PROJECT_ROOT/initramfs/lib/firmware
# 3) /lib/firmware
# - Installs all Alpine linux-firmware* packages into the build container (/lib/firmware)
# - Packs from container's /lib/firmware into an RFS flist (reproducible, full set)
# - Manifest name: firmware-<FIRMWARE_TAG or YYYYMMDD>.fl
# - Uploads blobs to S3 (Garage) via rfs store URI
# - Patches .fl sqlite stores table to use WEB_ENDPOINT for read-only fetches
@@ -25,8 +23,10 @@ rfs_common_load_rfs_s3_config
rfs_common_build_s3_store_uri
rfs_common_locate_rfs
section "Locating firmware directory"
rfs_common_locate_firmware_dir
section "Installing full Alpine firmware set in container (source: /lib/firmware)"
rfs_common_install_all_alpine_firmware_packages
export FIRMWARE_DIR="/lib/firmware"
log_info "Using firmware source dir: ${FIRMWARE_DIR}"
TAG="$(rfs_common_firmware_tag)"
MANIFEST_NAME="firmware-${TAG}.fl"