3.4 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| building it | accepted | 2026-09-21 | jochen | false | 02-DECISIONS/0096-an-upstream-image-is-copied-between-registries.md |
97. A vendor image is a declared build input, and a recipe fetches nothing undeclared
Context
Three modules could not be built by the mesh's builder because their recipes reached for what no manifest named: a public package, or a binary copied out of a public image (issue 064). A module already names the bases it stands on — another module's artifact, by name — and the builder answers with what the mesh holds; a vendor's image had no such declaration, so a recipe named it directly and the build worked when the public registry answered, which is sometimes.
Considered Options
- Let the build environment reach public registries. Rejected: a build that fetches from somebody else's registry on its own is one the mesh cannot rebuild the same way twice.
- A vendor image is a base like any other, declared under
build.onwith the argument the recipe reads it from, pinned by digest, copied into the mesh's registry before the build (ADR 0096). Adopted.
Decision
A build's on entry is either a module's artifact or an image published elsewhere, pinned by
digest, read from one build argument. Before the build the image is copied into the mesh's
registry under the module's repository and the recipe is handed the copy; genesis, with no
registry, pulls it into the first machine's store. A recipe whose COPY --from names a registry
image the manifest did not declare is refused before the build, naming the image and the remedy;
its own stages, declared arguments and scratch are not fetches. An unpinned vendor image is
refused: a tag is what somebody else can move.
A recipe whose FROM names an undeclared base was at first said, not refused: the mesh's own
images — the control plane's, the tool runtime's, the route proxy's — started from a public base
and declared none, and refusing those refuses genesis. Amended the same day: those three declare
their bases now, and an undeclared FROM is refused like an undeclared copy. The builder's own
image and the examples are built by make, not by the mesh, and take arguments with defaults.
The package half of the issue is not decided here: the mesh's package registry already proxies the public one, and the failure the report saw has to be run again to be placed.
Consequences
A module's build inputs are all in its manifest, and every one of them is something the mesh holds a copy of. What got harder: a recipe that used to name a base image on its first line now names an argument, and the manifest names the image.
How it is checked
A builder test declares a pinned vendor image, asserts it is copied under the module's
repository and handed to the recipe as the argument, and asserts an unpinned one is refused. A
recipe test asserts an undeclared FROM, an undeclared COPY --from and an undeclared argument
are named, and that stages, declared arguments and scratch are not.