A node names its provisioner client's account whenever a client runs there, filled files or not (issue 774)
mesh/delivery ready: it is merged on the Approve
mesh/check pass 8e325830891c on 6019c6d514a7 | unit 1589 run, 420 kept, 31 skipped | integration 1600 run, 420 kept, 26 skipped | over bound: unit (sl…
mesh/delivery ready: it is merged on the Approve
mesh/check pass 8e325830891c on 6019c6d514a7 | unit 1589 run, 420 kept, 31 skipped | integration 1600 run, 420 kept, 26 skipped | over bound: unit (sl…
The declaration named the account only beside its filled files (node.go), so a node whose every filled-file module was held this pass named none: on ace from 2026-11-04 01:29 its build modules and ssh-client were held for their forge binding, and the node-engine refused every write of the files they keep, and of every other module's. The account is the node's, named whenever the rendering has one. A row holds restic, the provisioned mesh's one filled-file module, with the client placed: the node's own still names the account; it named none before. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
This commit is contained in:
@@ -228,7 +228,11 @@ func TestTheProvisionedMeshHandsAPlanWithItsProvision(t *testing.T) {
|
||||
for _, row := range []struct {
|
||||
own, placed bool // the account read from the running own composition, else the client's running process; the client placed
|
||||
userless bool // the client placed and not held, its process naming no user: it composes no account
|
||||
}{{true, true, false}, {false, true, false}, {true, false, false}, {false, false, false}, {true, true, true}} {
|
||||
// filledHeld holds every module with a filled file (restic, its build not done) and not the client: the node still
|
||||
// names the account (issue 774, ace 2026-11-04: its build modules and ssh-client held, no filled file, no account)
|
||||
filledHeld bool
|
||||
}{{true, true, false, false}, {false, true, false, false}, {true, false, false, false}, {false, false, false, false},
|
||||
{true, true, true, false}, {true, true, false, true}} {
|
||||
own := row.own
|
||||
runs := running
|
||||
if !own { // what runs names no account of its own: the client's running process says it
|
||||
@@ -262,6 +266,8 @@ func TestTheProvisionedMeshHandsAPlanWithItsProvision(t *testing.T) {
|
||||
built.Manifest = mod.Manifest
|
||||
bb.Builds["mesh-provisioner-client "+fps["mesh-provisioner-client"]] = &built
|
||||
want = ""
|
||||
} else if row.filledHeld {
|
||||
bb.Builds["restic "+fps["restic"]] = &delivery.BuilderBuild{State: delivery.BuildBuilding}
|
||||
} else if row.placed {
|
||||
// held: its build not done while it runs
|
||||
bb.Builds["mesh-provisioner-client "+fps["mesh-provisioner-client"]] = &delivery.BuilderBuild{State: delivery.BuildBuilding}
|
||||
@@ -273,13 +279,16 @@ func TestTheProvisionedMeshHandsAPlanWithItsProvision(t *testing.T) {
|
||||
want = ""
|
||||
}
|
||||
after, _, held, err := frombus.Compose(context.Background(), bb, frombus.Mesh{}, frombus.Scope{Node: Node, Running: runs}, fps)
|
||||
if _, isHeld := held["mesh-provisioner-client"]; err != nil || isHeld != (row.placed && !row.userless) {
|
||||
if _, isHeld := held["mesh-provisioner-client"]; err != nil || isHeld != (row.placed && !row.userless && !row.filledHeld) {
|
||||
t.Fatalf("%+v: held %v: %v", row, held, err)
|
||||
}
|
||||
if got := after[ownKey].Own.Provisioner; got != want {
|
||||
t.Errorf("%+v: the node's own names %q, want %q", row, got, want)
|
||||
}
|
||||
if row.placed && !row.userless && !reflect.DeepEqual(after[resticKey].Filled, before[resticKey].Filled) {
|
||||
if _, resticHeld := held["restic"]; row.filledHeld && !resticHeld {
|
||||
t.Errorf("%+v: restic held %v", row, resticHeld)
|
||||
}
|
||||
if row.placed && !row.userless && !row.filledHeld && !reflect.DeepEqual(after[resticKey].Filled, before[resticKey].Filled) {
|
||||
t.Errorf("%+v: restic's filled files %v, want %v", row, after[resticKey].Filled, before[resticKey].Filled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,11 @@ func (d Declared) Body() ([]byte, error) {
|
||||
}
|
||||
if len(d.Filled) > 0 {
|
||||
envelope["filled_files"] = d.Filled
|
||||
}
|
||||
// The provisioner client's account is the node's, named whenever a client runs here, filled files or not: a node
|
||||
// whose every filled-file module is held this pass names none of its files, and still keeps them, so the client's
|
||||
// writes of them must be accepted (issue 774, ace 2026-11-04: its build modules and ssh-client held, no account).
|
||||
if d.Provisioner != "" {
|
||||
envelope["provisioner_account"] = d.Provisioner
|
||||
}
|
||||
// An empty declaration is deliberate: the node owns nothing the mesh put there (novox/hq issue 127), and the host refuses an
|
||||
@@ -202,9 +207,7 @@ func (c *composer) declaration(nodeName string, mode Mode) (Declared, error) {
|
||||
Filled: composed.Filled, LocalNetwork: resolution.LocalNetworkPorts(rules, with.LocalNetworks),
|
||||
CoreBoxesWanted: rendered.CoreBoxesWanted, Said: rendered.Said,
|
||||
Sequence: node.Sequence, Epoch: node.Epoch, Generation: node.Generation}
|
||||
if len(composed.Filled) > 0 {
|
||||
out.Provisioner = with.Provisioner
|
||||
}
|
||||
out.Provisioner = with.Provisioner
|
||||
// A handed module only pulled in by another keeps what requires it, for its value of its own in the assignments mirror (issue 765).
|
||||
for module := range composed.Plans {
|
||||
if by := resolution.RequiredBy(plan, module); by != "" {
|
||||
|
||||
Reference in New Issue
Block a user