A have waiting for a yes says whether the move changes the build alone: the composer composes the build the module runs with today's settings and secrets and the agent compares it with what runs, so a release's Approve answers it and a changed setting is still asked (ADR 0601 §1)
This commit is contained in:
+25
-1
@@ -58,6 +58,8 @@ type Have struct {
|
||||
// waits for a person's yes (ADR 0547 §3).
|
||||
Judgement string
|
||||
Waits string
|
||||
// BuildAlone says, in phase waiting-yes, the move changes the build alone (novox/hq ADR 0601 §1, delivery.Have.BuildAlone).
|
||||
BuildAlone bool
|
||||
// Sealed is, on a node composing its own, each value the composition it names carries sealed to the node's key, by
|
||||
// slot (delivery.Have.SealedAt): kept in the have so the composer reuses them after a restart (ADR 0547 §3), each at
|
||||
// its own slot alone (issue 1126, C1).
|
||||
@@ -153,6 +155,11 @@ type Env struct {
|
||||
// move of a module of policy record that recreates a container or moves its data waits for a person's yes in its
|
||||
// want (ADR 0547 §3). Nil judges no move.
|
||||
Policy func(ctx context.Context, module string) string
|
||||
// ComposedToday is the digest of a module composed at the build fp with today's settings and secrets, as the node would
|
||||
// compose it now, and whether it could be composed: a move to another build whose composition of the build it runs is
|
||||
// what runs changes the build alone (novox/hq ADR 0601 §1), and the have says so. Nil: no move is said to change the
|
||||
// build alone, and each is asked of a person.
|
||||
ComposedToday func(ctx context.Context, module, fp string) (string, bool)
|
||||
// HoldsData says whether a module's manifest declares data (catalogue.Manifest.DataItems), and whether its manifest
|
||||
// could be read: what a composition's Data is, for what runs of a module from the kept declaration, which carries no
|
||||
// Data of its own. A composition says Data, so without it a data module from the kept declaration is judged to move
|
||||
@@ -1649,10 +1656,27 @@ func (a *Agent) waitsForYes(ctx context.Context, module string, w wantNow, comp
|
||||
prev := a.running[module]
|
||||
a.mu.Unlock()
|
||||
a.writeHave(ctx, Have{Module: module, FP: prev.FP, Composed: prev.Composed, Phase: string(delivery.PhaseWaitingYes),
|
||||
Detail: j.Words, Judgement: string(j.Judgement), Waits: comp.Dig})
|
||||
Detail: j.Words, Judgement: string(j.Judgement), Waits: comp.Dig, BuildAlone: a.buildAlone(ctx, module, prev, w.Want.FP)})
|
||||
return true
|
||||
}
|
||||
|
||||
// buildAlone says a move of module from what runs to the build want changes the build alone (ADR 0601 §1): another build than
|
||||
// the one it runs, and the build it runs composed with today's settings and secrets is the composition it runs. Anything it
|
||||
// cannot tell is no: the move is then asked of a person.
|
||||
func (a *Agent) buildAlone(ctx context.Context, module string, prev delivery.Have, want string) bool {
|
||||
if prev.FP == "" && prev.Composed == "" {
|
||||
// Nothing of it run since this agent's start: its last have says what runs, as the have written keeps it.
|
||||
if h, ok := a.env.Haves.Read(ctx, module); ok {
|
||||
prev.FP, prev.Composed = h.FP, h.Composed
|
||||
}
|
||||
}
|
||||
if a.env.ComposedToday == nil || prev.FP == "" || prev.Composed == "" || prev.FP == want {
|
||||
return false
|
||||
}
|
||||
dig, ok := a.env.ComposedToday(ctx, module, prev.FP)
|
||||
return ok && dig == prev.Composed
|
||||
}
|
||||
|
||||
// runningComposition is what the module runs now: the composition last applied, else its resources in the declaration
|
||||
// the node kept from before the switch. Called with a.mu held.
|
||||
//
|
||||
|
||||
@@ -1288,6 +1288,17 @@ func TestTheNodesOwnCompositionIsAppliedWhenItDiffersAndARecordMoveWaitsForAYes(
|
||||
}
|
||||
return catalogue.PolicyRoll
|
||||
}
|
||||
// ADR 0601 §1: what runs composed today. rec's build composed again is what it runs, so its move changes the build alone;
|
||||
// db's is not (a setting changed too).
|
||||
b.env.ComposedToday = func(_ context.Context, m, fp string) (string, bool) {
|
||||
switch m {
|
||||
case "rec":
|
||||
return "sha256:" + strings.Repeat("8", 64), fp == fpOf("d")
|
||||
case "db":
|
||||
return "sha256:" + strings.Repeat("6", 64), true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
// The bucket's revisions of each key, as the verb composition reads them (issue 774).
|
||||
var historyMu sync.Mutex
|
||||
history := map[string][]Update{}
|
||||
@@ -1452,6 +1463,9 @@ func TestTheNodesOwnCompositionIsAppliedWhenItDiffersAndARecordMoveWaitsForAYes(
|
||||
h := b.haves.last("db")
|
||||
return h.Phase == string(delivery.PhaseWaitingYes) && h.Waits == ddigMoved
|
||||
})
|
||||
if h := b.haves.last("db"); h.BuildAlone {
|
||||
t.Errorf("a revision at the build it runs is said to change the build alone: %+v", h)
|
||||
}
|
||||
// The verb composition says why it waits: the revision that waits, what runs, the judgement, and with diff the
|
||||
// container it recreates; the revision that runs, asked by its digest, is no move (issue 774).
|
||||
keep(dk, draw)
|
||||
@@ -1508,7 +1522,8 @@ func TestTheNodesOwnCompositionIsAppliedWhenItDiffersAndARecordMoveWaitsForAYes(
|
||||
for _, row := range []struct {
|
||||
module, fp, composed, waits string
|
||||
sealed delivery.Seals
|
||||
}{{"db", fp, "", ddig2, nil}, {"rec", recFP, recDig, rdig, delivery.Seals{"rec.key#sealed": `{"box":"rec"}`}}} {
|
||||
alone bool
|
||||
}{{"db", fp, "", ddig2, nil, false}, {"rec", recFP, recDig, rdig, delivery.Seals{"rec.key#sealed": `{"box":"rec"}`}, true}} {
|
||||
eventually(t, row.module+"'s move did not wait for a yes", func() bool {
|
||||
h := b.haves.last(row.module)
|
||||
return h.Phase == string(delivery.PhaseWaitingYes) && h.Waits == row.waits
|
||||
@@ -1518,6 +1533,9 @@ func TestTheNodesOwnCompositionIsAppliedWhenItDiffersAndARecordMoveWaitsForAYes(
|
||||
(row.sealed != nil && !maps.Equal(h.Sealed, row.sealed)) {
|
||||
t.Errorf("%s's have waiting for a yes does not keep what runs: %+v", row.module, h)
|
||||
}
|
||||
if h.BuildAlone != row.alone {
|
||||
t.Errorf("%s's have waiting for a yes says build alone %v, want %v", row.module, h.BuildAlone, row.alone)
|
||||
}
|
||||
}
|
||||
if got := b.appliedList(); len(got) != applied {
|
||||
t.Fatalf("a move waiting for a yes was applied: %v", got)
|
||||
|
||||
Reference in New Issue
Block a user