Read a rebuild of an unchanged source as no move, whatever image digest it made (hq issue 280)
mesh/merge-gate error: the check could not run: a throwaway postgres:17-alpine could not be raised: docker run --label mesh.build=build-1791317509716888018…
mesh/delivery delivered
mesh/merge-gate error: the check could not run: a throwaway postgres:17-alpine could not be raised: docker run --label mesh.build=build-1791317509716888018…
mesh/delivery delivered
An image is not byte-reproducible, so ADR 0236's 'same artifacts is no move' never held for one: a catalogue merge that did not touch the bus rebuilt it, and every send to the control node waited for a planned bus upgrade. The builder now records a source fingerprint per build (module tree, context trees, bases and toolchains by digest). A rebuild with the fingerprint of the build it repeats is registered with that build's artifacts, handed to modules standing on it, holds no push, demands no bus step, and a plan sends and gates nothing for it. Identical artifacts remain a second way to be no move.
This commit is contained in:
@@ -72,8 +72,10 @@ var errWalkedElsewhere = errors.New("a plan already walking a build there sends
|
||||
type moveFacts struct {
|
||||
current map[string]inventory.CurrentBuild
|
||||
fps map[string]map[string]string
|
||||
passed map[string]map[string]bool
|
||||
plans []inventory.Plan
|
||||
// srcs is, per module, per commit, its build's source fingerprint (novox/hq issue 280).
|
||||
srcs map[string]map[string]string
|
||||
passed map[string]map[string]bool
|
||||
plans []inventory.Plan
|
||||
}
|
||||
|
||||
func readMoveFacts(ctx context.Context, inv *inventory.Inventory) (moveFacts, error) {
|
||||
@@ -85,6 +87,9 @@ func readMoveFacts(ctx context.Context, inv *inventory.Inventory) (moveFacts, er
|
||||
if f.fps, err = inv.Fingerprints(ctx); err != nil {
|
||||
return f, err
|
||||
}
|
||||
if f.srcs, err = inv.SourceFingerprints(ctx); err != nil {
|
||||
return f, err
|
||||
}
|
||||
if f.passed, err = inv.PassedCommits(ctx); err != nil {
|
||||
return f, err
|
||||
}
|
||||
@@ -92,12 +97,17 @@ func readMoveFacts(ctx context.Context, inv *inventory.Inventory) (moveFacts, er
|
||||
return f, err
|
||||
}
|
||||
|
||||
// identical is whether two builds of a module put the same thing on a machine: the same commit, or
|
||||
// builds that made the same artifacts from the same manifest.
|
||||
// identical is whether two builds of a module put the same thing on a machine: the same commit,
|
||||
// builds made from the same source (novox/hq issue 280) — the module's tree, the contexts it read, its
|
||||
// bases and toolchains, whatever digests an image rebuild made of them — or builds that made the same
|
||||
// artifacts from the same manifest.
|
||||
func (f moveFacts) identical(module, a, b string) bool {
|
||||
if a == b || sameCommit(a, b) {
|
||||
return true
|
||||
}
|
||||
if sa := f.srcs[module][a]; sa != "" && sa == f.srcs[module][b] {
|
||||
return true
|
||||
}
|
||||
fa := f.fps[module][a]
|
||||
return fa != "" && fa == f.fps[module][b]
|
||||
}
|
||||
@@ -112,6 +122,40 @@ func (f moveFacts) gated(module, commit string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// unchangedOnEvery is whether a plan's build of a module was made from the source of the build every
|
||||
// machine running it was last sent (novox/hq issue 280): no move on any of them. False when no machine
|
||||
// runs it, when what one was sent is not known, or when the build stands for itself.
|
||||
func unchangedOnEvery(ctx context.Context, inv *inventory.Inventory, module, build string, running []string) (bool, error) {
|
||||
if build == "" || len(running) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
same, err := inv.SameSourceCommits(ctx, module, build)
|
||||
if err != nil || len(same) == 0 {
|
||||
return false, err
|
||||
}
|
||||
for _, n := range running {
|
||||
sent, known, err := inv.SentBuilds(ctx, n)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
was, carried := sent[module]
|
||||
if !known || !carried || !inRun(same, was) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// inRun is whether a commit is one of a run's, however either is abbreviated.
|
||||
func inRun(run map[string]bool, commit string) bool {
|
||||
for c := range run {
|
||||
if sameCommit(c, commit) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// moves is what a machine's next send would move that no gate has seen: modules whose policy rolls out
|
||||
// (a recorded one is a person's push), that the machine was sent before, moving to a build not identical
|
||||
// to the one it runs and that has passed no gate. A machine whose last send's builds are not known names
|
||||
|
||||
Reference in New Issue
Block a user