The installer carries a builder and builds the control plane it raises

It carried the thing it was going to run; it now carries the thing that makes
it. One artifact either way — but a mesh raised this way holds a control plane
it built from a repository and a commit it can name, and can therefore build
again. A mesh handed a finished image could not, and had no way to find that
out until somebody needed it to.

A build step sits between load and bundle, because the bundle must name an
image and that image no longer arrives finished. Everything after it is
unchanged: a locally built image is named by the digest of its own
configuration, which is exactly what the carried one was named by.

Refused in preflight when nothing says what to build, so a run that cannot
finish says so before it has changed anything.
This commit is contained in:
2026-09-13 04:08:58 +02:00
parent cab83b61c8
commit e1a2fe7323
10 changed files with 312 additions and 37 deletions
+9
View File
@@ -32,6 +32,15 @@ func Preflight(ctx context.Context, o Options, d Deps, say func(string)) ([]byte
if image.IsEmpty() {
return nil, image.ErrEmpty
}
// And was it told what to build?
//
// Asked here rather than at the build, for the same reason as the line above: a run that
// cannot finish should say so before it has changed anything. The installer carries a builder
// and nothing else (novox/hq ADR 0073), so an installer with no source is an installer that
// would raise a store and a broker and then have nothing to raise a control plane from.
if err := o.Source.Check(); err != nil {
return nil, fmt.Errorf("%w. Nothing has been changed on this machine", err)
}
saved, err := image.Saved()
if err != nil {
return nil, err