diff --git a/diskless.pkr.hcl b/diskless.pkr.hcl index 2a02198..46d55ff 100644 --- a/diskless.pkr.hcl +++ b/diskless.pkr.hcl @@ -406,6 +406,32 @@ build { "install -D -m0755 /tmp/fleet-enrol /usr/sbin/fleet-enrol", "restorecon /usr/sbin/fleet-enrol 2>/dev/null || true", + # ---- Firmware slimming (BEFORE dracut so the initramfs shrinks too) --- + # linux-firmware ships ~678 MB of blobs for hardware this fixed fleet will + # never have. A live fleet audit (`modinfo -F firmware` over loaded modules + + # sysfs/`lspci` driver bindings on the real 820-class hosts AND the VMs, + # 2026-07-03) proved the ONLY loadable firmware any host requests is Intel + # i915 (GPU); every NIC is firmware-free (e1000e's ethtool "firmware-version" + # is on-chip NVM, not a /usr/lib/firmware file; virtio_net loads nothing), so + # NO NIC needs firmware. This runs PRE-dracut deliberately: --no-hostonly + + # plymouth's `drm` dep instmods a broad DRM set (i915/amdgpu/radeon/…) and + # dracut bundles each module's firmware into the initramfs (amdgpu fw is the + # classic UKI bloater), so trimming FIRST shrinks BOTH the rootfs erofs AND + # the UKI's initramfs. Keep i915 (all Intel gens) + intel/ (ice DDP for the + # ice/mlx5 server-NIC build variant + small Intel blobs) + mellanox + + # intel-ucode; strip the rest (~600 MB). Safe for the initramfs: the fleet + # splash GPU (i915) fw is kept and the build-VM splash uses virtio-gpu/bochs + # (no fw) — dracut just warns "firmware not found" for the removed drm modules + # and continues. Risk asymmetry: missing NIC fw would brick the fleet (none + # needed), missing GPU fw only degrades a display. BENCH-VERIFY the kiosk + # renders on the 820. Strip-in-place (rm, not rpm -e): linux-firmware can't be + # dropped as a package without also losing i915. See docs/TODO #18. + "if [ -d /usr/lib/firmware ]; then find /usr/lib/firmware -mindepth 1 -maxdepth 1 ! -name i915 ! -name intel ! -name mellanox ! -name intel-ucode -exec rm -rf {} + ; fi", + # Wi-Fi firmware: wired-only fleet (no iwlwifi). Remove the packages cleanly + # so the rpmdb stays honest (the find above dropped their iwlwifi-*.ucode). + "dnf remove -y 'iwl*-firmware' 2>/dev/null || true", + "echo \"==> firmware after strip: $(du -sh /usr/lib/firmware 2>/dev/null | cut -f1) (was ~678 MB)\"", + # ---- Build the fleet-generic initramfs ------------------------------ # %%{ escapes the rpm query tags so Packer's HCL template engine treats # them as literals (a bare %{...} is parsed as a template directive). @@ -416,6 +442,13 @@ build { # under pipefail the pipeline reports failure even when the file is # present (a false negative that wrongly failed the build for many runs). "lsinitrd /boot/initramfs-generic.img > /tmp/lsinitrd.txt", + # Initramfs footprint (this .img is embedded in the signed UKI and pulled + # over PXE/HTTP on every boot). Report the built size + any firmware that + # still made it in — post-strip this should be i915 only (pulled by + # plymouth's drm dep); if amdgpu/radeon/etc. appear, the strip didn't run + # before dracut. See docs/TODO #18. + "echo \"==> initramfs size: $(du -h /boot/initramfs-generic.img | cut -f1)\"", + "echo '==> firmware bundled in initramfs (expect i915 only):'; grep -i '/firmware/' /tmp/lsinitrd.txt || echo ' (none)'", "grep -E 'macsec|wpa_supplicant|tpm2_nvread|nvme.tcp|erofs|veritysetup' /tmp/lsinitrd.txt", # Assert NetworkManager is in the initramfs — the network-manager dracut # module is what renews the DHCP lease post-switch-root. A missing/renamed @@ -924,30 +957,9 @@ build { "if [ -d /usr/lib64/chromium-browser/locales ]; then find /usr/lib64/chromium-browser/locales -type f -name '*.pak' ! -name 'en-US.pak' -delete; fi", # App translation catalogs (.mo) for locales this fleet never uses. "[ -d /usr/share/locale ] && find /usr/share/locale -mindepth 1 -maxdepth 1 -type d ! -name 'en*' ! -name 'C*' -exec rm -rf {} + || true", - # Firmware slimming (biggest single win — see docs/TODO #18). linux-firmware - # ships ~678 MB of blobs for thousands of devices this fixed-hardware fleet - # will never have (amdgpu/nvidia/radeon/ath/qcom/rtl/…). A live fleet audit - # (2026-07-03, `modinfo -F firmware` across all loaded modules + `lspci`/sysfs - # driver bindings on the real 820-class hosts and the VMs) proved the ONLY - # loadable firmware ANY host requests is Intel **i915** (GPU). Every other - # driver is firmware-free: NICs are e1000e / virtio_net (e1000e's ethtool - # "firmware-version" is on-chip NVM, not a /usr/lib/firmware file), storage - # ahci, USB xhci, audio snd_hda_intel — none call request_firmware(). So NO - # NIC needs firmware, which removes the catastrophic case. KEEP: i915 (GPU, - # all Intel gens for mixed models) + intel/ (ice DDP insurance for the - # ice/mlx5 server-NIC build variant + small Intel blobs) + mellanox + - # intel-ucode; STRIP the rest (~600 MB off the uncompressed erofs). Risk - # asymmetry: missing NIC fw would brick the fleet (none needed) but missing - # GPU fw only degrades a display. BENCH-VERIFY the kiosk still renders on the - # 820 (i915 DMC/GuC load) after this; widen the keep-list if a future host - # has a non-Intel GPU or an ice/mlx5 NIC. Strip-in-place (rm, not rpm -e): - # linux-firmware can't be removed as a package without also losing i915. - "if [ -d /usr/lib/firmware ]; then find /usr/lib/firmware -mindepth 1 -maxdepth 1 ! -name i915 ! -name intel ! -name mellanox ! -name intel-ucode -exec rm -rf {} + ; fi", - # Wi-Fi firmware: wired-only fleet (no iwlwifi). Remove the packages cleanly - # so the rpmdb stays honest (the find above already dropped their top-level - # iwlwifi-*.ucode files). Glob quoted so the shell doesn't expand it. - "dnf remove -y 'iwl*-firmware' 2>/dev/null || true", - "echo \"==> firmware after strip: $(du -sh /usr/lib/firmware 2>/dev/null | cut -f1) (was ~678 MB)\"", + # (linux-firmware slimming moved to step 2, BEFORE the dracut build, so the + # UKI initramfs shrinks too — see TODO #18. Nothing re-adds firmware after + # that point, so the rootfs erofs is already trimmed by the time we get here.) ] } diff --git a/docs/TODO.md b/docs/TODO.md index a59ce99..c9b0e1f 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1483,7 +1483,12 @@ pulls `glibc-all-langpacks` (all languages); swapped for `glibc-minimal-langpack `glibc-langpack-en`. ~220 MB reclaimed; image is English-only (we also strip `/usr/share/locale` in 2d). **BENCH-VERIFY:** locale still `en_US.UTF-8`; kiosk + login OK. -**[x] DONE — linux-firmware strip to a hardware-audited keep-list** (`diskless.pkr.hcl` 2d). +**[x] DONE — linux-firmware strip to a hardware-audited keep-list** (`diskless.pkr.hcl` +step 2, run **BEFORE the dracut build** so the UKI initramfs shrinks too — not just the +rootfs. `--no-hostonly` + plymouth's `drm` dep instmods a broad DRM set and dracut bundles +each module's firmware into the initramfs, amdgpu being the classic UKI bloater; the strip +runs first so dracut never sees it. A post-build diagnostic reports the `.img` size + any +firmware still bundled — expected i915 only.) Live fleet audit (`modinfo -F firmware` over all loaded modules + sysfs/`lspci` driver bindings on the real 820-class hosts AND the VMs) proved the **only** loadable firmware any host requests is Intel **i915** (GPU). Every other driver is firmware-free —