From 9464e7fc2aca22368a7b418eaf53922b243d0bed Mon Sep 17 00:00:00 2001 From: Audiobuzz Date: Fri, 3 Jul 2026 05:23:49 +0000 Subject: [PATCH] =?UTF-8?q?trim:=20slim=20image=20~800=20MB=20=E2=80=94=20?= =?UTF-8?q?glibc=20langpacks=20en-only=20+=20linux-firmware=20strip=20(TOD?= =?UTF-8?q?O=20#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 2b rpm-size manifest revealed the biggest packages aren't the kiosk but base bloat: linux-firmware 678 MB and glibc-all-langpacks 228 MB (vs chromium 370 + llvm 129). The uncompressed erofs is read over NVMe/TCP on every boot, so this is fleet-wide dead weight + attack surface. glibc: swap glibc-all-langpacks (every language) for glibc-minimal-langpack + glibc-langpack-en. ~220 MB; image is English-only. linux-firmware: a live fleet audit (modinfo -F firmware over loaded modules + sysfs/lspci driver bindings on the real 820-class hosts and the VMs) proved the only firmware any host loads is Intel i915 (GPU). Every NIC is firmware-free (e1000e reports on-chip NVM, not a fw file; virtio_net loads nothing), so the catastrophic missing-NIC-firmware case is off the table. Keep i915 + intel/ (ice DDP insurance) + mellanox + intel-ucode; strip the ~600 MB of foreign vendor blobs (amdgpu/nvidia/radeon/ath/qcom/...). Remove iwl*-firmware (Wi-Fi, ~83 MB) on a wired-only fleet. Strip-in-place since the package can't be removed without losing i915; du reports the result in the build log. BENCH-VERIFY: kiosk still renders on the 820 (i915 DMC/GuC load) — the one real risk; widen the keep-list if any host has a non-Intel GPU or an ice/mlx5 NIC. --- diskless.pkr.hcl | 34 ++++++++++++++++++++++++++++++++++ docs/TODO.md | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/diskless.pkr.hcl b/diskless.pkr.hcl index b7a85fd..2a02198 100644 --- a/diskless.pkr.hcl +++ b/diskless.pkr.hcl @@ -296,6 +296,16 @@ build { # talks to the TPM directly via go-tpm. So this list stays at the baseline.) "dnf -y install wpa_supplicant tpm2-tools tpm2-tss nvme-cli cryptsetup dracut-network NetworkManager zstd openssl", + # Locale trim: @^minimal-environment pulls glibc-all-langpacks — ~228 MB of + # locale data for EVERY language (measured 2026-07-03, 3rd-largest package in + # the whole image). This fleet is English-only (we also strip + # /usr/share/locale in 2d). Swap it for the English langpack + the C/POSIX + # minimal set → reclaims ~220 MB of the read-only erofs. Install the small + # replacements first, then drop the monolith (nothing Requires it; strict so + # a surprise dep surfaces in CI rather than silently bloating the image). + "dnf -y install glibc-minimal-langpack glibc-langpack-en", + "dnf -y remove glibc-all-langpacks", + # EFI / Secure Boot management tools (efivar, mokutil, efibootmgr — all base # repos). Used over SSH on a workstation: `mokutil --sb-state/--pk/--kek/--db` # reads Secure Boot state + the enrolled PK/KEK/db; efibootmgr manages boot @@ -914,6 +924,30 @@ 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)\"", ] } diff --git a/docs/TODO.md b/docs/TODO.md index 66ba6d4..a59ce99 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1469,3 +1469,42 @@ connection to `:4420` established in the initramfs BEFORE firewalld starts. Veri default → should, but UNVERIFIED); a reconnect within `ctrl_loss_tmo` re-establishes *through* the firewall; DHCP renew + MKA keepalives unaffected; SSH in; no AVCs; verity hash reproducible. If it drops the root, that is the fleet-wide outage risk — gate hard. + +## [~] 18. Slim the image — locale + firmware (biggest erofs-size wins) + +**Finding (image-size audit via the 2b `rpm -qa --qf '%{SIZE}'` manifest, 2026-07-03):** +the largest packages in the 534-package image are NOT the kiosk — they're base bloat: +`linux-firmware` **678 MB**, `glibc-all-langpacks` **228 MB**, then chromium (370) + +llvm-libs (129). The uncompressed erofs is read over NVMe/TCP on every boot of every +host, so every dead byte is fleet-wide waste + attack surface. + +**[x] DONE — glibc langpacks → en-only** (`diskless.pkr.hcl` step 2). `@^minimal-environment` +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). +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 — +crucially **e1000e** (on-chip NVM, not a fw file) and **virtio_net**, so NO NIC needs +firmware and the fleet-brick case is off the table. Keep-list: `i915` + `intel/` (ice +DDP insurance for the `ice`/`mlx5` server-NIC build variant + small Intel blobs) + +`mellanox` + `intel-ucode`; strip the rest (amdgpu/nvidia/radeon/ath/qcom/rtl/iwlwifi… +~600 MB). Wi-Fi (`iwl*-firmware`, ~83 MB) removed as packages (wired-only fleet). +Strip-in-place (`find … -exec rm -rf`, not `rpm -e` — can't drop the package without +losing i915); a `du -sh /usr/lib/firmware` line reports the result in the build log. +**BENCH-VERIFY:** (a) kiosk still RENDERS on the 820 after the strip (i915 DMC/GuC still +load — the one real risk); (b) if any host has a non-Intel GPU or an `ice`/`mlx5` NIC, +widen the keep-list before trusting fleet-wide. Audited models so far: HP-820-class +(i915 + e1000e + iwlwifi-dropped) and virtio VMs. + +**Combined:** ~**800 MB** off the uncompressed erofs (langpacks + firmware), dwarfing the +kiosk weak-deps trim (#4). NEXT candidates from the manifest (measure, don't guess): +`iso-codes` (19 MB), `samba-client-libs`/`intel-mediasdk`/`gstreamer` (chromium-common +HARD deps — only removable by dropping HTML5 media), `binutils` (25 MB, build-only?), +`cracklib-dicts` (9.8 MB, needed for pam pwquality — keep). + +**Stack note:** committed on `trim-rpm`. When `optimise-ram` rebases onto the new +`trim-rpm`, expect a trivial `docs/TODO.md` tail conflict (both branches appended after +#16 — `optimise-ram` added #17 fapolicyd, this added #18); resolve by keeping both.