Installation sets up the builder, so a raised mesh can produce

Genesis ended with a mesh that runs and cannot make anything: every module in
the catalogue names artifacts and nothing had built them, so the first thing
anybody had to do was install a builder by hand.

The installer already carries one — it is what built the control plane — so
this is the same two acts the control plane goes through, in the same order:
publish it, so the mesh names it by a digest its own registry assigned rather
than a local identity nothing else can fetch, then install it as an ordinary
module pinned to that. And then the part only it needs, a broker account, issued
before the push so it arrives with the declaration rather than after it.

Verified on a bare machine: the install ends with a builder running, and that
mesh then built the shared base images and a module on top of them with nobody
helping it.
This commit is contained in:
2026-09-14 12:31:43 +02:00
parent 3dfe574e46
commit 8eeb28f00b
4 changed files with 138 additions and 10 deletions
+17 -5
View File
@@ -57,7 +57,19 @@ type Published struct {
func PublishControlPlane(ctx context.Context, o Options, d Deps, imageID string,
say func(string)) (Published, error) {
remote := o.Registry + "/" + ControlPlaneRepository
return publishAs(ctx, o, d, imageID, ControlPlaneRepository, say)
}
// publishAs puts one locally held image into this mesh's registry, under a repository name.
//
// **The same act for every image genesis has to place**, which is now two: the control plane it
// built, and the builder it carried. They arrive differently and are published identically — the
// registry does not care where an image came from, and a second copy of this that drifted would be
// the kind of difference nobody finds until one of them stops working.
func publishAs(ctx context.Context, o Options, d Deps, imageID, repository string,
say func(string)) (Published, error) {
remote := o.Registry + "/" + repository
out := Published{Tagged: remote + ":" + genesisTag}
// Asked first. A digest already served is a fact about the registry, and re-pushing an image
@@ -72,7 +84,7 @@ func PublishControlPlane(ctx context.Context, o Options, d Deps, imageID string,
}
if _, err := d.Run(ctx, "docker", "tag", imageID, out.Tagged); err != nil {
return out, fmt.Errorf("cannot tag the carried image as %s: %w", out.Tagged, err)
return out, fmt.Errorf("cannot tag %s as %s: %w", imageID, out.Tagged, err)
}
if _, err := d.Run(ctx, "docker", "push", out.Tagged); err != nil {
return out, fmt.Errorf(
@@ -93,9 +105,9 @@ func PublishControlPlane(ctx context.Context, o Options, d Deps, imageID string,
if pinned == "" {
return out, fmt.Errorf(
"%s was pushed and the registry does not serve it.\n"+
"The next step names the control plane's module by the digest this was supposed to "+
"produce, so there is nothing to name. Check `docker push` and "+
"http://%s/v2/%s/tags/list", out.Tagged, o.Registry, ControlPlaneRepository)
"The next step names this module by the digest this was supposed to produce, so "+
"there is nothing to name. Check `docker push` and "+
"http://%s/v2/%s/tags/list", out.Tagged, o.Registry, repository)
}
out.Reference = pinned
say(" published " + pinned)