Ubuntu 24.04 LTS support: stage the kernel from the ISO's live layer (refs #66) - #123
Open
adihanifsdr wants to merge 3 commits into
Open
Ubuntu 24.04 LTS support: stage the kernel from the ISO's live layer (refs #66)#123adihanifsdr wants to merge 3 commits into
adihanifsdr wants to merge 3 commits into
Conversation
…kernel Refs jamesstringer90#66. do_ubuntu_to_vhdx builds the rootfs from casper/minimal.squashfs and picks the kernel version up from the first /boot/vmlinuz-* it sees during the walk. On the Ubuntu 26.04 desktop ISO that layer carries the kernel; on 24.04 it does not (the kernel lives only in the minimal.standard.live overlay). A full ingest of ubuntu-24.04.4-desktop-amd64.iso walks 85,075 files / 4.9 GiB and never sees a vmlinuz, so kernel_ver stays empty and the bootstrap grub.cfg is written as: linux /boot/vmlinuz- root=UUID=... ro ... initrd /boot/initrd.img- GRUB cannot load that, the guest sits at the GRUB prompt with one vCPU busy and ~24 MB of RAM touched, the agent never comes up, and the UI shows "Installing Linux" forever with nothing in the log explaining why. Two changes: * tools/iso-patch/ubuntu_vhdx.c: after the squashfs ingest, treat an empty kernel version as a hard error. log_err() reports which image lacked /boot/vmlinuz-* and that only Ubuntu Desktop 26.04 LTS ISOs are supported; exit_code stays 1 so cleanup deletes the VHDX. Also log the detected kernel version as a STATUS line on success. * src/backend_win/asb_core.c (run_iso_patch_ubuntu): forward iso-patch STATUS: and ERROR: lines into the app log. The Windows --to-vhdx path deliberately ignores STATUS lines because the in-guest installer logs are available later; the Linux build has no such fallback, so these lines are the only host-side record of how the disk was built. A cheaper pre-flight on casper/minimal.manifest was considered and dropped: the manifest lists no linux-image-* package on the 26.04 and 26.04.1 ISOs either, so it cannot tell bootable from unbootable images. The post-ingest check reads the actual squashfs contents and only rejects builds that would have produced an unbootable disk. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Refs jamesstringer90#66. Ubuntu Desktop ISOs since 23.04 are "fsimage-layered". On 26.04 the base layer (casper/minimal.squashfs) still carries /boot/vmlinuz-*, initrd and /usr/lib/modules, so the plain ingest boots. On 24.04 it does not: the kernel lives only in minimal.standard.live.squashfs and the initrd only as casper/initrd, which is why a 24.04 build used to hang at GRUB ("Installing Linux" forever). Three things were needed to make 24.04 an installable target end to end: iso-patch (ubuntu_vhdx.c) * The squashfs ingest is now a function (ingest_squashfs) with an optional include-prefix filter, so an overlay layer can be walked for just /boot/{vmlinuz,System.map,config}-* and /usr/lib/modules/*. * When the base layer yields no kernel, stage_kernel_from_live_layer() pulls those from the live overlay, stores casper/initrd as /boot/initrd.img-<ver>, adds boot=local to the bootstrap grub.cfg (the live initrd defaults to BOOT=casper but honours boot=) plus an /etc/default/grub.d drop-in so update-grub keeps it, and leaves /etc/appsandbox-kernel-from-iso for first boot. * First boot gains STEP 7.6: with that marker present, apt-install linux-image/-modules/-modules-extra for the running kernel from the local mirrors so dpkg owns the files and a regular initrd is generated. Best-effort - the ISO initrd keeps working if it cannot. * The no-kernel error from the previous commit now only fires when the fallback also finds nothing. prefetch-build-deps (prefetch_build_deps.c) * Merge the <codename>-updates Packages index after the release one. Point-release ISOs (24.04.4) are -updates snapshots: the base already has libasound2t64 1.2.11-1ubuntu0.1, and the release pocket's libasound2-dev pins "= 1.2.11-1build2", so apt refused the whole build tool set. Later stanzas win in the hash chain, so -updates is preferred. * Seed build-essential and dkms (the 24.04.4 pool has gcc-13 but not libstdc++-13-dev / libgcc-13-dev / cpp-13) and initramfs-tools + linux-base (needed by STEP 7.6, absent from the pool). * Retry each download 3x with back-off; only the last attempt logs an ERROR. One flaky GET out of ~180 used to abort the run. * On failure wipe the output dir. A half-populated dir left the raw release-pocket Packages index behind and apt in the guest happily resolved "= version" candidates from it - then failed on everything. app (asb_core.c) * detect_iso_kernel reads the release string from casper/vmlinuz's bzImage header (falling back to the pool scan). On 24.04 the pool scan returned the GA 6.8 headers while the ISO boots the HWE 6.17 kernel, so the prefetched linux-headers did not match uname -r. * spawn_iso_patch_prefetch captures the child's output and forwards ERROR: and summary STATUS: lines to the app log, so a failed prefetch finally says why. Verified on Windows 11 26200 / RTX 3070 with ubuntu-24.04.4-desktop-amd64.iso through the headless daemon: build 3.5 min (+ prefetch), first boot runs all steps OK (apt build tools, kernel dpkg registration + initrd regen, agent build, DKMS asb_drm + dxgkrnl against 6.17.0-14-generic), reboot, agent online, sshState 4. Inside the guest: /dev/dxg and /dev/dri/card1 present, all four appsandbox services active, nvidia-smi reports the host GPU. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Refs jamesstringer90#66. Follow-up to the 24.04 layered-ISO support: with the kernel sorted, the guest came online but the display stayed black, and a Force Stop then left it unbootable. Both turned out to be general robustness gaps that 24.04 merely exposed first. Black desktop * The wsl-mesa prebuilt is built on 26.04 against LLVM 21. STEP 13 put it on ld.so.conf unconditionally, which shadows the distro Mesa for every process. On 24.04 libgallium cannot resolve libLLVM.so.21.1, so mutter fails to create a GBM device on asb_drm ("No GPUs found"), the Xorg fallback finds no screens, gdm gives up, and appsandbox-display waits forever for a framebuffer. * STEP 13 now runs ldd on the extracted libgallium/libgbm and only activates the prebuilt when everything resolves; otherwise it removes /opt/wsl-mesa and logs which libraries are missing. The desktop then runs on the distro Mesa (llvmpipe, exactly what the compositor uses on 26.04 as well). * 50-appsandbox-gpu and appsandbox-gpu gain a fallback: with /dev/dxg present but no /opt/wsl-mesa, they select the distro Mesa's own d3d12 gallium driver (Ubuntu builds it for WSL; libdxcore/libd3d12 come from the wsl-deps prefetch already on the loader path). OpenGL apps still reach the host GPU; Vulkan stays on lavapipe because stock mesa-vulkan-drivers ships no dzn ICD. Unbootable after Force Stop * iso-patch's ext4 writer lays the root fs down without a journal. An unclean stop of a running guest (Force Stop while a graceful shutdown was still in progress) left it "not clean with errors"; the boot-time fsck could not preen it, dropped to a maintenance prompt nobody can see, and the VM sat idle with no agent. * fsck.repair=yes on the bootstrap cmdline and a grub.d drop-in that keeps it there after update-grub (plus GRUB_RECORDFAIL_TIMEOUT=5 so a failed boot does not park the menu for ever). * New first-boot STEP 98 adds a journal to the mounted root with tune2fs -O has_journal right before the reboot, so later unclean stops replay a journal instead of needing a full check. Verified so far on the 24.04.4 guest from the previous commit, with the same changes applied offline through a WSL mount of its VHDX: e2fsck -fy brought the fs back from 'not clean with errors', tune2fs -O has_journal added the journal, and the boot-time journal explained the black desktop (mutter: 'MESA-LOADER: failed to open dri: libLLVM.so.21.1', 'No GPUs found'). A fresh 24.04 build exercising STEP 13's rollback and STEP 98 end to end is the next test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Author
|
Pushed a third commit after running the 24.04 guest for real: the kernel side was fine, but the desktop stayed black and a Force Stop then left the VM unbootable. Both are general gaps that 24.04 just exposed first:
Diagnosed by mounting the guest VHDX in WSL and reading its journal; the offline-applied version of these fixes is running on that guest now, and a fresh 24.04 build to exercise the first-boot path end to end is next. |
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Refs #66. Stacked on #122 (its commit is included here; merging this closes both).
@jamesstringer90 — I know 24.04 is not a target you planned to support, but the gap turned out to be small and well-contained, so here it is in case you want it. With this a stock
ubuntu-24.04.4-desktop-amd64.isoinstalls and comes online exactly like 26.04, including GPU-PV.Why 24.04 hung
Ubuntu Desktop ISOs since 23.04 are "fsimage-layered". On 26.04 the base layer
casper/minimal.squashfsstill contains/boot/vmlinuz-*, the initrd and/usr/lib/modules, so the plain ingest boots. On 24.04 it does not (verified by walking all 85,075 entries): the kernel is only inminimal.standard.live.squashfsand the initrd only ascasper/initrd. The bootstrapgrub.cfgended up pointing at/boot/vmlinuz-and the guest sat at GRUB while the UI showed "Installing Linux".Two more 24.04-specific problems showed up once the guest booted:
noble-updatessnapshot, but--prefetch-build-depsonly read thenoblerelease index, so the stagedlibasound2-devpinnedlibasound2t64 (= 1.2.11-1build2)against an installed1.2.11-1ubuntu0.1and apt refused every build tool. The 24.04.4 pool also lackslibstdc++-13-dev/libgcc-13-dev/cpp-13, sobuild-essentialcould not resolve from the pool alone.detect_iso_kernelscannedpool/main/l/linux/and found the GA 6.8 headers, while the ISO boots the HWE 6.17 kernel.What this does
iso-patch
ingest_squashfs()with an optional include-prefix filter.stage_kernel_from_live_layer()walks the live overlay for/boot/{vmlinuz,System.map,config}-*+/usr/lib/modules/*, storescasper/initrdas/boot/initrd.img-<ver>, addsboot=localto the bootstrap cmdline (the live initrd defaults toBOOT=casperbut honoursboot=— checked in its/init), plants an/etc/default/grub.ddrop-in soupdate-grubkeeps it, and leaves/etc/appsandbox-kernel-from-iso.apt-get install linux-image/-modules/-modules-extra-$(uname -r)from the local mirrors so dpkg owns the kernel and a regular initrd is generated. Best-effort; the ISO initrd keeps working if it can't.prefetch-build-deps
<codename>-updatesindex after the release one (later stanzas win in the hash chain). Skipped gracefully if the pocket doesn't exist.build-essential,dkms,initramfs-tools,linux-base.ERROR:), and wipes the output dir on failure — a half-populated dir left the raw release-pocket index behind, which is exactly what made apt pick the wrong versions in my first runs.app
detect_iso_kernelreads the release out ofcasper/vmlinuz's bzImage header (HdrS,kernel_versionat 0x20E), falling back to the pool scan (arm64 images aren't bzImage).spawn_iso_patch_prefetchnow captures the child's output and forwardsERROR:and summarySTATUS:lines to the app log. Before, a failed prefetch was justWARN: prefetch-build-deps failedwith no reason.No behaviour change for 26.04: the fallback only runs when the base layer has no kernel, STEP 7.6 only with the marker, and the
-updatesmerge just adds newer candidates.Proof
Ubuntu 24.04.4 LTS guest built from the stock desktop ISO, started from the App Sandbox GUI, IDD display open (GNOME on asb_drm, agent online, GPU-PV attached, SSH key deployed):
Inside that guest:
uname -r=6.17.0-14-generic,asb_drm+dxgkrnlloaded,/dev/dxgpresent,appsandbox-displaycapturing 1920x1080, root ext4has_journal+ clean, cmdline withfsck.repair=yes.Verified
Windows 11 26200, RTX 3070 Laptop GPU,
ubuntu-24.04.4-desktop-amd64.iso, via the headless daemon +asb.py:noble+noble-updates), first boot: STEP 7.4 OK, STEP 7.6 OK (kernel registered, initrd regenerated), STEP 8 OK, STEP 12dkms build/install asb_drm+dxgkrnlOK against6.17.0-14-generic, reboot,state: online,agentOnline: true,sshState: 4.uname -r=6.17.0-14-generic, cmdline carriesboot=local,linux-image/-modules/-headers-6.17.0-14-genericinstalled,asb_drm+dxgkrnl+hv_sockloaded,/dev/dxgand/dev/dri/card1present, all fourappsandbox-*services active,nvidia-smireports the host GPU.iso-patch.vcxproj+AppSandbox.slnRelease|x64 build clean apart from the pre-existing warnings.🤖 Generated with Claude Code