Files
hq/02-DECISIONS/0096-an-upstream-image-is-copied-between-registries.md
T

67 lines
3.6 KiB
Markdown

---
topic: building it
status: accepted
date: 2026-09-21
deciders: jochen
reconstructed: false
extends: 02-DECISIONS/0006-the-substrate-and-the-control-plane.md
---
# 96. An upstream image is copied between registries, never through a machine's image store
## Context
A module may declare that an artifact is an image published elsewhere, to be copied into the
mesh's own registry so machines fetch it by a digest this mesh assigned rather than by a name
somebody else controls. The builder pulled it into the build machine's image store and pushed it
under the mesh's name, and the push was refused: a published image is an index over several
architectures, the runtime's store keeps the index, and pushing one platform out of it fails
however the platform is asked for
([issue 046](../04-ISSUES/046-an-upstream-image-cannot-be-mirrored-into-the-mesh/00-report.md)).
Every variant of pull-then-push was tried and failed the same way.
## Considered Options
1. **Resolve the index to one platform and push that.** Tried, reverted: it did not make the
push work, and a workaround for a store's behaviour is a thing nobody removes later.
2. **Tooling that copies between registries**, installed on the build machine. Rejected: one
more thing the builder's image carries, for a protocol the builder already speaks for blobs.
3. **Copy over the registry API**, in the builder. Adopted.
## Decision
The builder copies an upstream image between registries and never through a machine's image
store: it reads the index and every manifest it names, moves each blob by digest into the mesh's
registry — skipping what is already there, since blobs are content-named — puts the manifests
and then the index under the module's repository, and pins the index's digest. Public images are
read with the anonymous bearer token the registry hands out on challenge, which is how the
public hub and the others the catalogue names serve them. The mesh mirrors the whole index, so
what a machine fetches is the image for its own architecture; that every machine on one mesh is
the same architecture is an assumption this mesh makes and had not written down until now.
Genesis has no registry to copy into and keeps the pull: the image stays in the first machine's
store, named by its own id, as every artifact does before there is anywhere to publish.
## Consequences
An upstream artifact builds. What got harder: the builder now holds a registry client of its
own, some two hundred lines, where a runtime command used to do; and a private upstream that
demands a credential is refused, since the copy is anonymous by design.
## How it is checked
A test raises a fake upstream registry serving an index over two platforms behind a bearer
challenge, and a fake mesh registry that records what arrives: every blob of both platforms
arrives once, two manifests and the index are put under their digests, the reference returned
pins the index under the module's repository, and a second copy uploads nothing. A reference
test reads names the way a runtime does. *Proven against the real thing the same day:* the genesis
bed built the tool runtime through the mesh's builder with its node base copied out of the public
hub into the mesh's registry by this code — after one finding the fake could not give: the builder
ran on the default bridge, where loopback is not the machine, and now runs on the host network.
## References
- [issue 046](../04-ISSUES/046-an-upstream-image-cannot-be-mirrored-into-the-mesh/00-report.md)
- [ADR 0006](0006-the-substrate-and-the-control-plane.md)
- [`03-DESIGN/01-to-be/18-building-a-module.md`](../03-DESIGN/01-to-be/18-building-a-module.md)