package main import ( "context" "fmt" "path" "strings" "git.novox.be/novox/mesh-sdk/go/catalogue" "github.com/novox/mesh-controller/internal/inventory" "github.com/novox/mesh-controller/internal/link" ) // The list of predefined keys the mesh publishes (novox/hq ADR 0348 §7, design 57 package K2, issue 661). // // **The newest trunk build of the catalogue wins.** A build of the catalogue reads predefined.json at the commit // it builds and carries it with the commit's generation (link.PredefinedList). Registration keeps it in the // controller's store when that generation is larger than the one kept (inventory.KeepPredefined), so an older // build's list heard later never replaces a newer one, and every manifest the controller reads again is judged // against the list kept (catalogue.UsePredefined). mesh-config publishes it on the bus from there (design 57 // package K3); the controller keeps no config value, only the keys. // fromTheCatalogue is whether a build is of the catalogue's repository, whose list alone the mesh publishes: by // its name, in the URL form or the seat form. func fromTheCatalogue(result link.BuildResult) bool { for _, repository := range []string{result.Repository, sourceRepository(result)} { name := strings.TrimSuffix(path.Base(strings.TrimRight(repository, "/")), ".git") if name == catalogue.CatalogueRepository { return true } } return false } func sourceRepository(result link.BuildResult) string { if result.Source == nil { return "" } return result.Source.Repository } // carriedList is the list a build of the catalogue carried, read strictly; nil for a build of another // repository, or one that carried none. func carriedList(result link.BuildResult) (catalogue.PredefinedList, error) { if result.Predefined == nil || !fromTheCatalogue(result) { return nil, nil } list, err := catalogue.ParsePredefined(result.Predefined.Keys) if err != nil { return nil, fmt.Errorf("%s carried a list of predefined keys that is refused: %w", result.ID, err) } return list, nil } // judgedWith is the list a build's manifest is first judged against at registration: the catalogue's own at the // commit built, which its build judged it against, where it carried one; the list kept otherwise. func judgedWith(result link.BuildResult) (catalogue.PredefinedList, error) { list, err := carriedList(result) if err != nil || list != nil { return list, err } return catalogue.PublishedPredefined(), nil } // loadPredefined makes the list kept in the store the one this controller judges manifests against. A store // keeping none leaves the list it has. func loadPredefined(ctx context.Context, inv *inventory.Inventory) error { kept, has, err := inv.PredefinedKept(ctx) if err != nil || !has { return err } catalogue.UsePredefined(kept.Keys) return nil } // publishPredefined keeps a trunk build's list when it is newer than the one kept, says so, and loads what the // store keeps then — this build's, or a newer one another controller process kept. func publishPredefined(ctx context.Context, inv *inventory.Inventory, result link.BuildResult, list catalogue.PredefinedList) error { kept, err := inv.KeepPredefined(ctx, inventory.PredefinedRecord{Keys: list, Repository: result.Repository, Commit: result.Commit, Generation: result.Predefined.Generation, Build: result.ID}) if err != nil { return err } if kept { fmt.Printf("%s: the list of predefined keys at %s (generation %d) is published: %s\n", result.ID, short(result.Commit), result.Predefined.Generation, strings.Join(list.Keys(), ", ")) } else { fmt.Printf("%s: the list of predefined keys at %s (generation %d) is not newer than the one kept, which "+ "stands\n", result.ID, short(result.Commit), result.Predefined.Generation) } return loadPredefined(ctx, inv) }