pack — design
Class:
design· Function axis:f1(AIRGAP1). States only the shape we ship.
What pack produces
pack gathers a product's artifacts (and, optionally, target-identical dependencies) into a versioned staging tree — the input Archive::pack (f2) seals. It also records provenance.
The staging tree
pub struct Staging { root, version } (pack.rs:31) — the builder.
| method | signature | what it does |
new |
Staging::new(root, version) -> Staging (pack.rs:38) |
create an empty staging root |
add_artifact |
add_artifact(src, rel) -> String (pack.rs:50) |
copy a file in under relative path rel |
add_component_spec |
add_component_spec(spec) -> String (pack.rs:63) |
write manifests/<name>.json |
artifacts |
artifacts() -> Vec<String> (pack.rs:73) |
enumerate staged files (sorted) |
VERSION lives outside the bundle
pack::write_version_file(beside_bundle, version) -> PathBuf (pack.rs:84) writes a VERSION file next to the bundle, not inside it — so bumping the shipped version never requires repacking the archive.
Provenance
pack::pack(staging, product, built_in_container) -> PackManifest (pack.rs:95) records a PackManifest { product, version, built_in_container, artifacts } (pack.rs:18) by enumerating the staging tree — the per-product record of what went in.
Target-identical dependency capture
pub trait ContainerBuild { build_into(product, target_triple, into) -> Vec<String> } (pack.rs:107) is the seam for capturing a component's deps byte-alike with the destination by building it in a container. The real impl is PodmanBuild (pack.rs:124):
new(base_image)(pack.rs:139),step(run)(pack.rs:149) — builder.containerfile(product, target_triple) -> String(pack.rs:157) — pure Containerfile render.runtime_available() -> bool—podman --versioncheck (the lean/default path only).-
build_into— captures the deps into the staging subdir, via one of two engines:- default (lean):
podman build → create → copy /out → cleanup; honest bail if podman is absent, never a faked capture. pack-ocifeature: the same build over draupnir's ONE OCI engine —ContainerBoot::build_image+extract_path(thecreate+cptwin), zero-shell, one engine constellation-wide.copy_tree_contentsflattens the extract to the exactcp /out/.layout so both engines leaveintobyte-identical. Seemsi-oci-routing.md.
- default (lean):
This is a build-host-only seam — it never runs at airgap-install time.
Contract (inject-assert tests)
pack_collects_staging_tree_and_version_file_is_outside asserts the VERSION file lands outside the bundle tree; podman_build_renders_containerfile_and_is_honest_when_absent asserts the exact Containerfile bytes and the honest failure when podman is absent; copy_tree_contents_flattens_extracted_out_dir_into_staging asserts the pack-oci engine's extract flattens to the same relative paths the podman cp /out/. path produced (byte-identical into).