fix(linux/build): scrub apt/ldconfig caches + force xorriso mtimes (M1.1 iter31)
Some checks failed
Build SilverMetal Linux ISO (reproducibility-gated) / builder-image (push) Successful in 1s
Build SilverMetal Linux ISO (reproducibility-gated) / build-and-verify (push) Failing after 17m44s

Run #4278 with iter30's chroot scrub still produced different ISOs.
The diagnostic was clean and pointed at a tight set of remaining
divergences:

* Inside the squashfs, three files differed:
    /var/cache/apt/pkgcache.bin
    /var/cache/apt/srcpkgcache.bin
    /var/cache/ldconfig/aux-cache
  — all post-install binary caches with internal pointers/timestamps
  that vary across runs. Standard reproducible-Debian practice is to
  drop them; `apt` regenerates pkgcache on first `apt-get update` (and
  implicitly when anything else needs it), and ldconfig regenerates
  aux-cache on its next run.

* In the outer ISO TOC:
    /boot.catalog        mtime  May  7 21:27   vs   May  7 21:44
    /live/filesystem.squashfs   May  7 21:27   vs   May  7 21:44
  — xorriso's `-update` and the boot-catalog rewrite were stamping
  files with wall-clock time, not SOURCE_DATE_EPOCH.

Two additions to post_process_for_reproducibility:

1. Three more entries in the chroot rm list (apt's two pkgcaches
   and ldconfig aux-cache).

2. xorriso post-update fixups:
     -alter_date_r m "=${SOURCE_DATE_EPOCH}" /
     -volume_date c "=${SOURCE_DATE_EPOCH}"
     -volume_date m "=${SOURCE_DATE_EPOCH}"
   set every file's mtime in the ISO and both volume-descriptor
   dates to the pinned epoch. (`=N` is xorriso's syntax for a
   literal decimal epoch.)

If diffoscope flagged everything in run #4278 honestly (its full
output was 3 file diffs in the squashfs + the squashfs metadata
size delta, then nothing — TOC was reduced to just the two mtime
lines), this should clear M1.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 22:50:28 +01:00
parent 84179b3642
commit d354040bd6

View File

@@ -158,9 +158,30 @@ post_process_for_reproducibility() {
# Files we know to be non-deterministic. sudo because the chroot
# is owned by root.
#
# Why each one:
# /etc/nvme/host{id,nqn} — random UUIDs (nvme-cli postinst).
# nvme-cli regenerates on first boot.
# /var/lib/dkms/<…>/log — wall-clock build timestamps in
# DKMS make.log; not consulted at
# runtime.
# /var/cache/apt/{,src}pkgcache.bin
# — apt's compiled package index, has
# internal pointers/timestamps that
# vary run-to-run. Regenerated on
# first `apt-get update` (and
# transparently triggered by anything
# that needs it).
# /var/cache/ldconfig/aux-cache
# — ldconfig auxiliary cache, also
# with internal nondet state.
# Regenerated by ldconfig.
sudo --non-interactive rm -f \
"${chroot_dir}/etc/nvme/hostid" \
"${chroot_dir}/etc/nvme/hostnqn"
"${chroot_dir}/etc/nvme/hostnqn" \
"${chroot_dir}/var/cache/apt/pkgcache.bin" \
"${chroot_dir}/var/cache/apt/srcpkgcache.bin" \
"${chroot_dir}/var/cache/ldconfig/aux-cache"
sudo --non-interactive find "${chroot_dir}/var/lib/dkms" \
-mindepth 1 -type d -name log -prune -exec rm -rf {} + \
2>/dev/null || true
@@ -201,12 +222,21 @@ post_process_for_reproducibility() {
local new_iso="${iso_file%.iso}.silvermetal-clean.iso"
sudo --non-interactive rm -f "${new_iso}"
echo "post-process: replacing /live/filesystem.squashfs in ISO"
# `-alter_date_r m` rewrites every file's mtime to the pinned epoch
# so the new /live/filesystem.squashfs and the regenerated
# /boot.catalog don't carry the wall-clock time of the post-process
# step (run #4278's TOC diff caught both: 21:27 vs 21:44).
# `-volume_date` covers the volume-descriptor-level dates that
# xorriso also stamps on -commit.
sudo --non-interactive xorriso \
-return_with SORRY 0 \
-indev "${iso_file}" \
-outdev "${new_iso}" \
-boot_image any keep \
-update "${new_sqfs}" /live/filesystem.squashfs \
-alter_date_r m "=${SOURCE_DATE_EPOCH}" / \
-volume_date c "=${SOURCE_DATE_EPOCH}" \
-volume_date m "=${SOURCE_DATE_EPOCH}" \
-commit
sudo --non-interactive mv -f "${new_iso}" "${iso_file}"
sudo --non-interactive rm -f "${new_sqfs}"