diff --git a/go/delivery/compose_candidate_test.go b/go/delivery/compose_candidate_test.go index 4c9558c..b7d069d 100644 --- a/go/delivery/compose_candidate_test.go +++ b/go/delivery/compose_candidate_test.go @@ -81,8 +81,11 @@ func TestComposeCandidateAndComposedPlanRoundTripAndRefuse(t *testing.T) { } d1, _ := ComposedDigestOf(planned) d0, _ := ComposedDigestOf(Composed{Node: "ace", Module: "netcheck", FP: fp, Resources: []json.RawMessage{}}) - if d1 == "" || d1 == d0 { - t.Error("the digest does not move with the plan") + if d1 == "" || d1 != d0 { + t.Error("the digest moves with the plan: it is the resources' alone") + } + if SameComposed(planned, Composed{Node: "ace", Module: "netcheck", FP: fp, Resources: []json.RawMessage{}}) { + t.Error("a plan change is not a new composition value") } refused := Composed{Node: "ace", Module: "netcheck", FP: fp, Refused: "the setting domain has no value"} if raw, err = EncodeComposed(refused); err != nil { diff --git a/go/delivery/composed_value.go b/go/delivery/composed_value.go index b98f85e..787f88d 100644 --- a/go/delivery/composed_value.go +++ b/go/delivery/composed_value.go @@ -50,7 +50,8 @@ type Composed struct { // Plan is the module's whole provisioning plan as the node-engine hands it to the provisioner (templates, files, // own secrets by name, items, collections, provisions; never a value), composed node-wide (novox/hq ADR 0593 §6, // §8): the provisioner makes every plan from it. Nil when the module hands the provisioner nothing; only on a - // module's key. It is part of the encoding, so the digest moves when the plan does. + // module's key. It is part of the encoding (SameComposed sees a plan change) but not of the digest + // (ComposedDigestOf): a have, a want and the apply name a composition by its resources. Plan *catalogue.Plan // Refused is why the module cannot be composed at this fingerprint on this node, the rest of the node composed // (ADR 0593 §6): a refused composition holds no resource, filled file, data or plan, and has no digest @@ -233,7 +234,7 @@ func DecodeComposed(data []byte) (Composed, error) { return c, nil } -// ComposedDigestOf is a composition's digest, "sha256:", of its encoding without its signature. A want names it +// ComposedDigestOf is a composition's digest, "sha256:", of its encoding without its signature and its plan. A want names it // (ADR 0539 clause 1), the controller writes it beside the composition, and the signature signs it. // // A refused composition has no digest: it is refused, naming the module (ADR 0593 §6). @@ -242,6 +243,7 @@ func ComposedDigestOf(c Composed) (string, error) { return "", fmt.Errorf("delivery: the composition of %s on %s is refused (%s) and has no digest", c.Module, c.Node, c.Refused) } c.Signature = nil + c.Plan = nil raw, err := EncodeComposed(c) if err != nil { return "", err