-
Notifications
You must be signed in to change notification settings - Fork 3
wire source_date_epoch into rootfs and initramfs image builds #204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f0516a7
39aa61d
3cc5cfd
1a294be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| //! Guard: the image runs actually inject `SOURCE_DATE_EPOCH`. | ||
| //! | ||
| //! Both halves of this feature are unit-tested — `inject_source_date_epoch`'s | ||
| //! three-way `Option` behavior in `utils::container`, and the rootfs script's | ||
| //! `mkfs.erofs -T "${SOURCE_DATE_EPOCH:-0}"` in `rootfs::image` — but the call | ||
| //! that connects them was covered by neither. Deleting it leaves the whole | ||
| //! suite green while a configured epoch silently stops reaching the container, | ||
| //! which is the exact regression the feature exists to prevent. | ||
| //! | ||
| //! The check lives here rather than in a `mod tests` inside those files | ||
| //! because the needle would then appear in the file it scans, and the | ||
| //! assertion would hold with the real call site deleted. (Confirmed the hard | ||
| //! way.) Same reason `no_hand_rolled_stdio_flags.rs` sits out here. | ||
| //! | ||
| //! ponytail: pins the call's spelling, not its effect. Testing the effect | ||
| //! means lifting env-map construction out of the async run path in both | ||
| //! commands; worth doing when a third image type wants the same stamp. | ||
|
|
||
| use std::fs; | ||
| use std::path::PathBuf; | ||
|
|
||
| /// The call every image-building run has to make. | ||
| const INJECTION: &str = "inject_source_date_epoch(&mut env_vars, config.source_date_epoch)"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The guard cannot see either Four call sites spell the injection - rootfs/image.rs:402, initramfs/image.rs:318, runtime/build.rs:541, runtime/build.rs:2890 - and this guard pins the first two. runtime/build.rs:541 matches the needle byte-for-byte but is never scanned, and :2890, the call this commit adds, is spelled Demonstrated rather than argued: I deleted both runtime/build.rs injections and ran the full suite - 1395/1404 unit tests plus every integration target passed, this guard included. What that leaves exposed is the primary path. runtime/build.rs:541 feeds the runtime build script Credit where due: this is not the generated-text pattern - it reads the real source files, and deleting rootfs/image.rs:402 does turn it red with a clear message. Two narrower notes for the fix: it is a |
||
|
|
||
| fn source(relative: &str) -> String { | ||
| let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(relative); | ||
| fs::read_to_string(&path).unwrap_or_else(|e| panic!("reading {}: {e}", path.display())) | ||
| } | ||
|
|
||
| #[test] | ||
| fn rootfs_image_run_injects_source_date_epoch() { | ||
| assert!( | ||
| source("src/commands/rootfs/image.rs").contains(INJECTION), | ||
| "the rootfs image run must inject SOURCE_DATE_EPOCH into its container env" | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn initramfs_image_run_injects_source_date_epoch() { | ||
| // Inert on this base — the initramfs script has no reader until the | ||
| // mtime-normalization pass lands — so a deletion here would be entirely | ||
| // invisible without this. | ||
| assert!( | ||
| source("src/commands/initramfs/image.rs").contains(INJECTION), | ||
| "the initramfs image run must inject SOURCE_DATE_EPOCH into its container env" | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The post_build claim covers only one of the two post_build hooks
"Rootfs, initramfs and
post_buildruns now all carry it" reads as unqualified, but there are tworun_post_buildimplementations in this tree and only the runtime one was wired. The extension hook (src/commands/ext/build.rs:1473) still passes bareenv_vars: self.runtime_env_vars()at :1520 with no injection.The runtime side is genuinely wired end to end, to be clear -
config.source_date_epochreachesrun_post_build(runtime/build.rs:743), is injected into that container's env map (:2890), andRunConfig.env_varsreaches the container as-e KEY=VALUEon both the local (container.rs:1450) and runs_on remote (:1510) paths, carrying the same value the build run at :541 uses.Failure path:
avocado.yamlsetssource_date_epoch: 1700000000; an extension declarespost_build: scripts/bake.shthat gzips or tars a generated file into the ext sysroot. Per ext/build.rs:705 that hook runs before the .raw is sealed, so wall-clock timestamps land in the artifact's content - gzip and tar headers,.pyc- whichmkfs.erofs -Tcannot normalize afterwards. The .raw then differs build to build while this entry tells the user post_build is covered.Within one
avocado build, Phase 1 runs the ext post_build hook with no epoch andext imagethen seals the .raw with one, so the value is not consistent across hooks in a single build. The ext hook already holdsconfig: &Configin scope, so this is a one-line wiring rather than a plumbing constraint.