fix(gate): repair three latent failures in the Linux-native deb proof - #283
Closed
TheShiftedBit wants to merge 1 commit into
Closed
TheShiftedBit wants to merge 1 commit into
TheShiftedBit wants to merge 1 commit into
Conversation
The exact Debian package proof (DebProof) only runs on a native Linux host with /dev/kvm and /dev/vhost-vsock. CI runners lack vhost-vsock (the proof selector skips it) and macOS release machines cross-compile host!=target (skipped too), so this rail had never executed end-to-end on a real machine until now. Running `capsem-gate cross-compile x86_64` on a regular machine surfaced three independent bugs, each of which failed the gate: 1. Staging ownership: the sealed install-test image excludes /cache via .dockerignore, so Docker materializes the mountpoint chain /src/cache/target for the read-only packages mount as root. Staging then runs as the container user `capsem` (uid 1000) and dies with `mkdir: cannot create directory 'cache/target/tests': Permission denied` on any host whose uid is not 1000. InstallContainer solved exactly this with _claim_paths() after await_systemd; DebProof never did. Fix: give DebProof the same _claim_paths() (root mkdir -p + chown -R of layout.owned_paths and owned_parent_paths), called right after systemd is ready. 2. Authored-graph path: `capsem-admin assets channel build --channel X` writes <out_dir>/assets/X/manifest.json, but ReleaseGraph's build_channel() returned the hardcoded config constant graph_manifest = "assets/local/manifest.json". The paths only coincide for the install gate's channel "local"; DebProof authors the package channel (default "stable", and its own validation refuses "local"), so record-binary immediately failed with `read .../assets/local/manifest.json: No such file or directory`. Fix: build_channel() now derives the authored path from the channel it just built (assets/<channel>/<basename>), and hand_off() takes the channel and validates against the same channel-aware location. Behavior for the install gate (channel=local) is unchanged. 3. Split provenance in the installed-release verification: for a preverified payload the postinst deliberately keeps the package's baked manifest-metadata (update_status_refresh_skipped reason=preverified_install_payload) while the bytes are hydrated from the proof's authored handoff channel. verify-installed-release models exactly this split via --metadata-manifest-url (the release probe already passes it), but DebProof._verify_release only passed --manifest-url, so the proof failed comparing the metadata URL against the handoff URL. Fix: pass --metadata-manifest-url with the baked URL alongside --manifest-url with the handoff. Tests: the four gate tests that pinned the buggy constants are updated to pin the fixed behavior (channel-aware authored path; hand_off's channel argument). 53/53 pass in tests/gate/test_gate_debproof.py + test_gate_install_ordering.py. With these three fixes the full cross-compile gate passes on a native Linux+KVM host, including dpkg install inside the sealed systemd container, release verification, and the guest shell boot proof.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #283 +/- ##
=========================================
- Coverage 65.3% 65.3% -0.1%
=========================================
Files 1456 1456
Lines 128450 128463 +13
Branches 91944 91944
=========================================
+ Hits 83938 83940 +2
- Misses 39527 39537 +10
- Partials 4985 4986 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Author
|
Actually, I'm closing this - this PR fixed the issues by simply hardcoding things. The bugs are real, but the fix makes it work for me at the expense of potentially breaking it for other situations. |
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.
Summary
The exact Debian package proof (
DebProof) only runs on a native Linux host with/dev/kvm+/dev/vhost-vsock. CI runners lack vhost-vsock (the proof selector skips the proof) and macOS release machines cross-compile host≠target (also skipped) — so this rail had never executed end-to-end until I rancapsem-gate cross-compile x86_64on a gLinux workstation (host uid 399710). That run surfaced three independent bugs, each a hard gate failure. With all three fixed, the full cross-compile gate passes on a native Linux+KVM host: deb install inside the sealed systemd container, release verification, and the guest shell boot proof.Bug 1 — staging ownership in the proof container (
debproof.py)Symptom:
mkdir: cannot create directory 'cache/target/tests': Permission deniedduringstage_content_from.Cause:
.dockerignoreexcludes/cache, so the sealed install-test image has no/src/cache. Docker materializes the mountpoint chain/src/cache/targetfor the read-onlycache/target/packagesmount as root. Staging runs as the container usercapsem(uid 1000), which only works on hosts whose uid happens to be 1000 (e.g. CI).Fix:
InstallContaineralready solved exactly this with_claim_paths()(rootmkdir -p+chown -Roflayout.owned_pathsandowned_parent_paths) called right after systemd is ready.DebProofnow does the same.Bug 2 — authored-graph path ignores the channel (
releasegraph.py)Symptom:
record-binaryfails withread .../install-proof/assets/local/manifest.json: No such file or directory.Cause:
capsem-admin assets channel build --channel Xwrites<out_dir>/assets/X/manifest.json, butReleaseGraph.build_channel()returned the hardcoded config constantgraph_manifest = "assets/local/manifest.json". The two coincide only for the install gate's channellocal.DebProofauthors the package channel (defaultstable; its own validation refuseslocal), so the gate read a path the admin never wrote.Fix:
build_channel()derives the authored location from the channel it just built (assets/<channel>/<basename>), andhand_off()takes the channel and validates against the same channel-aware path. Install-gate behavior (channel=local) is unchanged.Bug 3 — split provenance in installed-release verification (
debproof.py)Symptom:
installed release verification failed: manifest-metadata manifest_url is '<baked URL>', expected '<handoff URL>'— afterdpkg -ialready succeeded.Cause: for a preverified payload the postinst deliberately keeps the package's baked manifest-metadata (
update_status_refresh_skipped reason=preverified_install_payload) while the bytes are hydrated from the proof's authored handoff channel.verify-installed-releasemodels exactly this split via--metadata-manifest-url(the release probe already passes it), butDebProof._verify_releaseonly passed--manifest-url.Fix: pass
--metadata-manifest-url <baked URL>alongside--manifest-url <handoff URL>.Tests
The four gate tests that pinned the buggy constants now pin the fixed behavior (channel-aware authored path;
hand_off's channel argument).build_system/tests/gate/test_gate_debproof.py+test_gate_install_ordering.py: 53/53 pass.Verification
capsem-gate cross-compile x86_64on gLinux (64-core, KVM): ok in 2m45s including the full package proof.Capsem_0.6.4_amd64.debinstalled and verified on the same host (service healthy,capsem doctor265/265 in-guest diagnostics, VM smoke test).