mesh/delivery-group group feat/774-l3-reland rejected: composed together: the checker's verdict at the members' heads (b48c90fea31f): integration: mesh-self-ch…
mesh/delivery closed: a newer head of the same pull request
mesh/check failed: integration: mesh-self-check/cmd/mesh-self-check.TestTheSelfCheckWholeRunsOnTheBus: the run answered {Run:doctor-1793351737-1 At:20…
One commit with exactly the tree of the reviewed head35b4509c0a, on main12c2574c9d, so two compiled programs added and removed on the branch leave no trace in history (issue 1577).
123 lines
4.3 KiB
Go
123 lines
4.3 KiB
Go
package main
|
|
|
|
// The seat mesh-artifact-sweep's verbs (novox/hq ADR 0571 clause 2; catalogue.ArtifactSweepSeat), each a tool named
|
|
// `artifact-store.<verb>` as the runtime serves a seat's verb, answering as the controller's verb answered: {output,
|
|
// ok, answer}.
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// verbAnswer is the controller's verbs' answer shape, which the builder and docker read (answerOf).
|
|
type verbAnswer struct {
|
|
Output string `json:"output"`
|
|
OK bool `json:"ok"`
|
|
Answer any `json:"answer"`
|
|
}
|
|
|
|
// SeatTools are the seat's verbs over h; s reads the store's listing for mirrors.
|
|
func SeatTools(h *Holder, s *Store) []stdio.Tool {
|
|
seat := catalogue.ArtifactSweepSeat + "."
|
|
return []stdio.Tool{
|
|
{Name: seat + "artifacts", Description: "Every artifact the mesh made that the store holds: kept and why, eligible, " +
|
|
"or with collected those it no longer holds.",
|
|
Run: func(args map[string]any) (any, error) {
|
|
r, err := h.Artifacts(text(args, "repository"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if text(args, "collected") != "true" {
|
|
refs := r.References[:0:0]
|
|
for _, x := range r.References {
|
|
if x.State != "collected" {
|
|
refs = append(refs, x)
|
|
}
|
|
}
|
|
r.References = refs
|
|
}
|
|
return verbAnswer{Output: fmt.Sprintf("%d kept, %d eligible, %d collected\n", r.Counts["kept"],
|
|
r.Counts["eligible"], r.Counts["collected"]), OK: true, Answer: r}, nil
|
|
}},
|
|
{Name: seat + "held", Description: "Whether the store holds each reference given: held, gone or unknown with why.",
|
|
Run: func(args map[string]any) (any, error) {
|
|
a, err := h.Held(listOf(args["references"]))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return verbAnswer{Output: fmt.Sprintf("the artifact store at %s holds %d of the %d reference(s) asked\n",
|
|
a.Store, len(a.Held), len(a.Held)+len(a.Gone)+len(a.Unknown)), OK: true, Answer: a}, nil
|
|
}},
|
|
{Name: seat + "collect", Description: "The sweep now: a dry run without confirm; with confirm and why, every kept " +
|
|
"archive held, then each eligible artifact let go of, each recorded in the hand-act log.",
|
|
Run: func(args map[string]any) (any, error) {
|
|
most, err := count(args, "most", MostPerSweep, 1, MostAtAll)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
a, err := h.Collect(text(args, "why"), text(args, "confirm") == "true", most)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return verbAnswer{Output: fmt.Sprintf("let go of %d, would let go of %d, %d left\n", len(a.LetGo),
|
|
len(a.WouldLetGo), a.Left), OK: true, Answer: a}, nil
|
|
}},
|
|
{Name: seat + "mirrors", Description: "The bases the mesh copied into its store, each kept (a kept build stood on " +
|
|
"it), eligible (only builds no longer kept stood on it) or unrecorded (no build the builder's log holds stood " +
|
|
"on it: never removed).",
|
|
Run: func(args map[string]any) (any, error) {
|
|
if text(args, "record") != "" {
|
|
return nil, fmt.Errorf("mirrors records nothing by hand on this seat: a copy is recorded by the builds the " +
|
|
"builder's log says stood on it (novox/hq ADR 0571 clause 1)")
|
|
}
|
|
m, err := h.MirrorsNow()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return verbAnswer{Output: fmt.Sprintf("%d copies\n", len(m.Copies)), OK: true, Answer: m}, nil
|
|
}},
|
|
{Name: seat + "images", Description: "Every container image one machine's wants and haves name.",
|
|
Run: func(args map[string]any) (any, error) {
|
|
node := text(args, "node")
|
|
if node == "" {
|
|
return nil, fmt.Errorf("images names the machine")
|
|
}
|
|
address := ""
|
|
if d, err := h.Door(); err == nil {
|
|
address = d.Address()
|
|
}
|
|
a, err := h.ImagesOf(node, address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return verbAnswer{Output: fmt.Sprintf("%s: %d images\n", node, len(a.Images)), OK: true, Answer: a}, nil
|
|
}},
|
|
}
|
|
}
|
|
|
|
// listOf is a list argument: a list, or one text separated by commas.
|
|
func listOf(v any) []string {
|
|
var out []string
|
|
add := func(s string) {
|
|
for _, p := range strings.Split(s, ",") {
|
|
if p = strings.TrimSpace(p); p != "" && !contains(out, p) {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
}
|
|
switch x := v.(type) {
|
|
case string:
|
|
add(x)
|
|
case []any:
|
|
for _, e := range x {
|
|
if s, ok := e.(string); ok {
|
|
add(s)
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|