Move no module whose fingerprint is unchanged, and let a key's build stand on the held build-agent build of the same digests at the switch (issue 1851, A9)
This commit is contained in:
@@ -2,6 +2,8 @@ package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/chain"
|
||||
)
|
||||
@@ -43,6 +45,11 @@ func (i *Inventory) sourceRows(ctx context.Context, module string) (map[string][
|
||||
|
||||
// standing is, of a module's builds newest first, the index of the build that stands for the build at
|
||||
// `from`: the oldest of the unbroken run of builds behind it with its source fingerprint.
|
||||
//
|
||||
// **Across the switch to the new form** (novox/hq ADR 0453 §6, ADR 0499; R4e A9): a build of the new form (`src2:`, taken
|
||||
// from the builder's key) continues the run of the build before it of the old form (`src1:` or none, build-agent's)
|
||||
// when every artifact of the two has the same digest: the fingerprints cannot be compared, the programs can, and equal
|
||||
// digests are no move. Past it the run goes on by the old fingerprint.
|
||||
func standing(builds []sourceRow, from int) int {
|
||||
at := from
|
||||
fp := builds[from].fingerprint
|
||||
@@ -50,14 +57,53 @@ func standing(builds []sourceRow, from int) int {
|
||||
return at
|
||||
}
|
||||
for j := from + 1; j < len(builds); j++ {
|
||||
if builds[j].fingerprint != fp || builds[j].failedGate {
|
||||
if builds[j].failedGate {
|
||||
break
|
||||
}
|
||||
if builds[j].fingerprint != fp {
|
||||
if !newForm(fp) || newForm(builds[j].fingerprint) || !sameDigests(builds[at].made, builds[j].made) {
|
||||
break
|
||||
}
|
||||
fp = builds[j].fingerprint
|
||||
}
|
||||
at = j
|
||||
}
|
||||
return at
|
||||
}
|
||||
|
||||
// newForm says a source fingerprint is of the new form (ADR 0453 §6).
|
||||
func newForm(fp string) bool { return strings.HasPrefix(fp, "src2:") }
|
||||
|
||||
// sameDigests says two builds' artifacts, as recorded (JSON of []Artifact), are the same programs: the same names, each
|
||||
// with the same digest, wherever each was pushed. A build naming an artifact with no digest is never the same.
|
||||
func sameDigests(a, b []byte) bool {
|
||||
digests := func(raw []byte) map[string]string {
|
||||
var made []Artifact
|
||||
if json.Unmarshal(raw, &made) != nil || len(made) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := map[string]string{}
|
||||
for _, m := range made {
|
||||
d := digestIn(m.Reference)
|
||||
if d == "" {
|
||||
return nil
|
||||
}
|
||||
out[m.Name] = d
|
||||
}
|
||||
return out
|
||||
}
|
||||
da, db := digests(a), digests(b)
|
||||
if da == nil || db == nil || len(da) != len(db) {
|
||||
return false
|
||||
}
|
||||
for name, d := range da {
|
||||
if db[name] != d {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// StandingBuild is the build that stands for a module's build (novox/hq issue 280): the oldest build of
|
||||
// the unbroken run of builds with its source fingerprint, at or before it — itself when its fingerprint
|
||||
// is empty or it starts the run. Answers its id and the manifest it was recorded with; empty when the
|
||||
|
||||
Reference in New Issue
Block a user