Adoption mode: a node in use is adopted before it is converged (hq ADR 0100–0103) #44

Merged
jschoubben merged 33 commits from feat/adoption-mode into main 2026-09-22 19:01:51 +00:00
2 changed files with 22 additions and 10 deletions
Showing only changes of commit 9280513afa - Show all commits
+12 -5
View File
@@ -279,13 +279,20 @@ func issueFor(ctx context.Context, inv *inventory.Inventory, existing, fresh str
}
name = node.Name
}
// Saying adopted makes the node adopted. Not saying it leaves the node as it is: re-issuing a
// token for an adopted node does not converge it — converging is its own act, previewed
// (novox/hq ADR 0100).
if adopted {
if err := inv.SetAdopted(ctx, name, true); err != nil {
// Not saying adopted leaves the node as it is: re-issuing a token for an adopted node does not
// converge it — converging is its own act, previewed (novox/hq ADR 0100). And saying it for a
// node already converged is refused rather than done quietly: returning a node to adopted is
// its own act too, which unloads the mesh's filter and enables the found firewall again.
if adopted && fresh == "" {
node, err := inv.NodeByName(ctx, name)
if err != nil {
return inventory.Issued{}, err
}
if !node.Adopted {
return inventory.Issued{}, fmt.Errorf("%s is converged, and a token does not change "+
"that: run `adopt %s` to return it to adopted, then issue the token without "+
"--adopted", name, name)
}
}
return inv.IssueToken(ctx, name, validFor)
+10 -5
View File
@@ -139,11 +139,16 @@ func TestATokenIssuedAdoptedSaysSoAndReissuingDoesNotConverge(t *testing.T) {
if !again.Node.Adopted {
t.Fatal("re-issuing without --adopted converged the node; converging is its own act")
}
existing, err := issueFor(ctx, open.inventory, "laptop", "", true, time.Hour)
if err != nil {
// --adopted for a node already converged is refused, and points at the act that does it.
if _, err := issueFor(ctx, open.inventory, "laptop", "", true, time.Hour); err == nil ||
!strings.Contains(err.Error(), "adopt laptop") {
t.Fatalf("--adopted on a converged node was not refused: %v", err)
}
if n, _ := open.inventory.NodeByName(ctx, "laptop"); n.Adopted {
t.Fatal("a refused token flipped the node to adopted")
}
// And said for a node that is adopted already, it is the ordinary re-issue.
if _, err := issueFor(ctx, open.inventory, "joiner", "", true, time.Hour); err != nil {
t.Fatal(err)
}
if !existing.Node.Adopted {
t.Fatal("--adopted on an existing record did not make it adopted")
}
}