A module names the module its build stands on, not a copy of it
A fingerprint written into a recipe names one particular copy of the base — the copy on whichever machine the person typing it was using. On any other mesh that copy has never existed, so the build stops on its first line with a message about an image nobody can look up. Three modules in the catalogue were in exactly that state, and the line each of them replaced was equally dead. A module now names the module and artifact instead, and the mesh answers with what it holds. The builder is still a thing that clones, builds and answers: the answer travels with the question, because only the mesh knows what it has. A base the mesh has not built is refused before anything is built, naming which module has to exist first.
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/novox/mesh-control/internal/builder"
|
||||
)
|
||||
@@ -34,6 +35,8 @@ func buildOnce(ctx context.Context, args []string) error {
|
||||
registry := set.String("registry", "",
|
||||
"host:port to publish to. Without it the artifacts stay in this machine's container runtime, which is the genesis case")
|
||||
workspace := set.String("workspace", "", "where to clone and build (default: a temporary directory)")
|
||||
on := multiple(set, "on",
|
||||
"a base this build stands on, as <module>/<artifact>=<reference>. Repeatable")
|
||||
positionals, err := parseAround(set, args)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,6 +51,22 @@ func buildOnce(ctx context.Context, args []string) error {
|
||||
where = os.TempDir() + "/mesh-builder-once"
|
||||
}
|
||||
|
||||
// What this build may stand on, said on the command line because there is no mesh to ask.
|
||||
//
|
||||
// **This is the genesis case and it is meant to be awkward.** On a running mesh the control
|
||||
// plane answers this, because only it knows what this mesh holds. Here nothing has been built
|
||||
// yet, so whoever runs this says what to use — and for the control plane, which is the one
|
||||
// module raised before anything else exists, the answer is ordinarily nothing at all.
|
||||
bases := map[string]string{}
|
||||
for _, pair := range *on {
|
||||
key, reference, found := strings.Cut(pair, "=")
|
||||
if !found || key == "" || reference == "" {
|
||||
return fmt.Errorf(
|
||||
"--on takes <module>/<artifact>=<reference>, and %q is not that", pair)
|
||||
}
|
||||
bases[key] = reference
|
||||
}
|
||||
|
||||
// Local unless told otherwise, because the moment this exists for has nowhere to publish. A
|
||||
// default pointing at a registry would mean genesis failing at a push to something that is not
|
||||
// there yet, one step away from the thing that could explain it.
|
||||
@@ -65,7 +84,7 @@ func buildOnce(ctx context.Context, args []string) error {
|
||||
}
|
||||
fmt.Fprintln(os.Stderr)
|
||||
|
||||
built, buildErr := builder.Build(ctx, builder.Command, publisher, repository, *path, *ref, where)
|
||||
built, buildErr := builder.Build(ctx, builder.Command, publisher, repository, *path, *ref, where, bases)
|
||||
if buildErr != nil {
|
||||
return buildErr
|
||||
}
|
||||
@@ -132,3 +151,15 @@ func parseAround(set *flag.FlagSet, args []string) ([]string, error) {
|
||||
rest = rest[1:]
|
||||
}
|
||||
}
|
||||
|
||||
// multiple is a flag that may be given more than once.
|
||||
type repeated []string
|
||||
|
||||
func (r *repeated) String() string { return strings.Join(*r, ", ") }
|
||||
func (r *repeated) Set(v string) error { *r = append(*r, v); return nil }
|
||||
|
||||
func multiple(set *flag.FlagSet, name, usage string) *[]string {
|
||||
var values repeated
|
||||
set.Var(&values, name, usage)
|
||||
return (*[]string)(&values)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user