@@ -355,14 +355,32 @@ dnf install -y --setopt=install_weak_deps=False \
355355work=$(mktemp -d)
356356mkdir -p "$work"/iso-root/{images/pxeboot,LiveOS} "$work"/EFI
357357
358+ # Same single-kernel reasoning as the live Containerfile: two kernels
359+ # here would silently copy one image and boot the other's modules.
360+ # Resolved before mksquashfs because the exclude list below names the
361+ # kernel's files by version.
362+ kver="$(ls "$rootfs/usr/lib/modules")"
363+ [ "$(echo "$kver" | wc -l)" -eq 1 ] || { echo >&2 "expected exactly one kernel, got: $kver"; exit 1; }
364+
358365# The live root filesystem, in one file.
359366#
360367# sysroot and ostree are an installed machine's deployment machinery and
361368# mean nothing to a live boot, which mounts this squashfs as / directly.
369+ # The kernel and initramfs are excluded for the same reason, one level
370+ # up: they are boot artifacts, and the copies this ISO actually loads
371+ # are the ones under images/pxeboot that GRUB names. The pair inside the
372+ # rootfs serves an installed machine's kernel-update machinery, which a
373+ # throwaway live root never runs. The initramfs is the expensive one —
374+ # 242 MB since v0.18 put plymouth in it, because a splash needs a
375+ # framebuffer and dracut's drm module then packs every GPU driver's
376+ # firmware into a --no-hostonly build — and it is already a zstd
377+ # stream, so squashfs stores it at full size. Carrying it twice took
378+ # the ISO from 1.80 GB to 2.11 GB and over the release-asset budget;
379+ # measured, not estimated, on the niri image of 2026-08-27.
362380# zstd at 19 because this number is the ISO's size: the whole point of
363381# the exercise is fitting under a 2 GB release asset cap.
364382#
365- # -e goes LAST and takes both patterns , because mksquashfs treats every
383+ # -e goes LAST and takes every pattern , because mksquashfs treats every
366384# remaining argument as an exclude pattern once it sees -e. Writing it
367385# in the middle does not error: it silently excludes files named "-comp"
368386# and "19", and falls back to gzip. That cost 60 MB here and it is
@@ -380,12 +398,12 @@ mkdir -p "$work"/iso-root/{images/pxeboot,LiveOS} "$work"/EFI
380398# boot on the writable overlay rather than baking one into the image.
381399mksquashfs "$rootfs" "$work/iso-root/LiveOS/squashfs.img" \
382400 -noappend -comp zstd -Xcompression-level 19 \
383- -e sysroot ostree
401+ -e sysroot ostree \
402+ "usr/lib/modules/$kver/initramfs.img" \
403+ "usr/lib/modules/$kver/vmlinuz"
384404
385- # Same single-kernel reasoning as the live Containerfile: two kernels
386- # here would silently copy one image and boot the other's modules.
387- kver="$(ls "$rootfs/usr/lib/modules")"
388- [ "$(echo "$kver" | wc -l)" -eq 1 ] || { echo >&2 "expected exactly one kernel, got: $kver"; exit 1; }
405+ # The boot pair GRUB actually loads. Copied from the rootfs, not the
406+ # squashfs, so the excludes above do not touch this.
389407cp "$rootfs/usr/lib/modules/$kver/vmlinuz" "$work/iso-root/images/pxeboot/vmlinuz"
390408cp "$rootfs/usr/lib/modules/$kver/initramfs.img" "$work/iso-root/images/pxeboot/initrd.img"
391409
@@ -806,6 +824,29 @@ mod tests {
806824 assert ! ( comp < exclude, "-e must come last or it eats the compressor flags" ) ;
807825 }
808826
827+ /// The kernel and initramfs ride the ISO once, under images/pxeboot,
828+ /// because those are the copies GRUB loads. The same files inside
829+ /// the squashfs serve an installed machine's kernel-update
830+ /// machinery, which a throwaway live root never runs — and the
831+ /// initramfs is a 242 MB zstd stream that squashfs cannot shrink, so
832+ /// carrying it twice is what took the ISO from 1.80 GB to 2.11 GB
833+ /// and over the release-asset budget in v0.18. The splash grew it;
834+ /// the doubling made it fatal.
835+ #[ test]
836+ fn the_squashfs_carries_no_boot_artifacts ( ) {
837+ let script = super :: BUILD_ISO_SCRIPT ;
838+ assert ! (
839+ script. contains( "\" usr/lib/modules/$kver/initramfs.img\" " ) ,
840+ "the initramfs is the ISO's biggest file; it rides once, in pxeboot"
841+ ) ;
842+ assert ! ( script. contains( "\" usr/lib/modules/$kver/vmlinuz\" " ) ) ;
843+ // The exclude list names the kernel's files by version, so the
844+ // version has to be resolved before mksquashfs runs.
845+ let kver = script. find ( "kver=\" $(ls" ) . unwrap ( ) ;
846+ let exclude = script. find ( "usr/lib/modules/$kver/initramfs.img" ) . unwrap ( ) ;
847+ assert ! ( kver < exclude, "kver must exist before the exclude list names it" ) ;
848+ }
849+
809850 /// Found by booting: `-all-root` makes every file root-owned, and
810851 /// liveuser's 0700 home then belongs to root, so the live user
811852 /// cannot write to it. Symptom is a broken desktop with no obvious
0 commit comments