Merge feat/modules-name-no-node into bulk-a
This commit is contained in:
@@ -347,7 +347,7 @@ func TestAReportIsReadAsTheAgentModuleWritesIt(t *testing.T) {
|
|||||||
func TestANodeReportingAnAdoptedAccountLaterIsBoundToIt(t *testing.T) {
|
func TestANodeReportingAnAdoptedAccountLaterIsBoundToIt(t *testing.T) {
|
||||||
mm := newMesh(t)
|
mm := newMesh(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
_, _ = mm.m.Consider(ctx, []Holdings{mm.login("novox", "rt-new", true, t0)})
|
_, _ = mm.m.Consider(ctx, []Holdings{mm.login("node-c", "rt-new", true, t0)})
|
||||||
late := mm.login("laptop", "rt-older", true, t0.Add(-24*time.Hour))
|
late := mm.login("laptop", "rt-older", true, t0.Add(-24*time.Hour))
|
||||||
_, _ = mm.m.Consider(ctx, []Holdings{late})
|
_, _ = mm.m.Consider(ctx, []Holdings{late})
|
||||||
if mm.state["laptop"].Licence != licence1 {
|
if mm.state["laptop"].Licence != licence1 {
|
||||||
@@ -477,16 +477,16 @@ func TestEveryMoveSaysWhatWhyAndWho(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
asked := WithCause(ctx, Cause{Why: "the switch verb", By: "g14.node-tools"})
|
asked := WithCause(ctx, Cause{Why: "the switch verb", By: "node-b.node-tools"})
|
||||||
if _, err := mm.m.Bind(asked, "laptop", "api"); err != nil {
|
if _, err := mm.m.Bind(asked, "laptop", "api"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if s := mm.state["laptop"]; s.Why != "the switch verb" || s.By != "g14.node-tools" {
|
if s := mm.state["laptop"]; s.Why != "the switch verb" || s.By != "node-b.node-tools" {
|
||||||
t.Fatalf("the node is told %+v", s)
|
t.Fatalf("the node is told %+v", s)
|
||||||
}
|
}
|
||||||
said := strings.Join(lines, "\n")
|
said := strings.Join(lines, "\n")
|
||||||
if !strings.Contains(said, "switched laptop from "+licence1+" to api (generation ") ||
|
if !strings.Contains(said, "switched laptop from "+licence1+" to api (generation ") ||
|
||||||
!strings.Contains(said, "the switch verb; asked by g14.node-tools") {
|
!strings.Contains(said, "the switch verb; asked by node-b.node-tools") {
|
||||||
t.Fatalf("the journal said:\n%s", said)
|
t.Fatalf("the journal said:\n%s", said)
|
||||||
}
|
}
|
||||||
var switched string
|
var switched string
|
||||||
@@ -495,18 +495,18 @@ func TestEveryMoveSaysWhatWhyAndWho(t *testing.T) {
|
|||||||
switched = e
|
switched = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, want := range []string{`"by":"g14.node-tools"`, `"from":"` + licence1 + `"`, `"licence":"api"`, `"consumer":"laptop"`, `"generation":`} {
|
for _, want := range []string{`"by":"node-b.node-tools"`, `"from":"` + licence1 + `"`, `"licence":"api"`, `"consumer":"laptop"`, `"generation":`} {
|
||||||
if !strings.Contains(switched, want) {
|
if !strings.Contains(switched, want) {
|
||||||
t.Fatalf("the event %q lacks %s; events %v", switched, want, mm.events)
|
t.Fatalf("the event %q lacks %s; events %v", switched, want, mm.events)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last := mm.store.Audits[len(mm.store.Audits)-1]
|
last := mm.store.Audits[len(mm.store.Audits)-1]
|
||||||
if raw, _ := json.Marshal(last); !strings.Contains(string(raw), `"by":"g14.node-tools"`) || !strings.Contains(string(raw), "switched") {
|
if raw, _ := json.Marshal(last); !strings.Contains(string(raw), `"by":"node-b.node-tools"`) || !strings.Contains(string(raw), "switched") {
|
||||||
t.Fatalf("the audit kept %s", raw)
|
t.Fatalf("the audit kept %s", raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = mm.m.Rotate(WithCause(ctx, Cause{Why: "the refresh verb", By: "novox.node-tools"}), licence1, true)
|
_, _ = mm.m.Rotate(WithCause(ctx, Cause{Why: "the refresh verb", By: "node-c.node-tools"}), licence1, true)
|
||||||
if !strings.Contains(strings.Join(mm.events, "|"), `licence.rotated {"by":"novox.node-tools"`) {
|
if !strings.Contains(strings.Join(mm.events, "|"), `licence.rotated {"by":"node-c.node-tools"`) {
|
||||||
t.Fatalf("a rotation asked for said no caller: %v", mm.events)
|
t.Fatalf("a rotation asked for said no caller: %v", mm.events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ through an injected runner and a fake root in the tests.
|
|||||||
|
|
||||||
## What changes when it is assigned
|
## What changes when it is assigned
|
||||||
|
|
||||||
| | g14 | shanks |
|
| | node-b | node-d |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| package | none: `nextcloud-client` 34.0.4 is installed, explicitly, from `extra` | the same |
|
| package | none: `nextcloud-client` 34.0.4 is installed, explicitly, from `extra` | the same |
|
||||||
| start | none: dex starts it from the client's own entry (`--background`, in the login session's scope) | none on disk. **The client running now came from the predecessor's window-manager line** (`nextcloud`, a child of i3, since the session of 2026-10-04 16:00). That session began before the `i3` module dropped the line and installed `dex`, so the next login is the first that starts it from its entry |
|
| start | none: dex starts it from the client's own entry (`--background`, in the login session's scope) | none on disk. **The client running now came from the predecessor's window-manager line** (`nextcloud`, a child of i3, since the session of 2026-10-04 16:00). That session began before the `i3` module dropped the line and installed `dex`, so the next login is the first that starts it from its entry |
|
||||||
@@ -83,11 +83,11 @@ The workstations are already in the state this module describes.
|
|||||||
|
|
||||||
Nothing is required on either machine.
|
Nothing is required on either machine.
|
||||||
|
|
||||||
- **shanks:** log out and in once, or run `nextcloud_restart`, and the client runs from its one start.
|
- **node-d:** log out and in once, or run `nextcloud_restart`, and the client runs from its one start.
|
||||||
`nextcloud_check` then answers `ok`.
|
`nextcloud_check` then answers `ok`.
|
||||||
- **Optional, both:** the client has kept a `nextcloud.cfg.backup_<date>_<version>` from every upgrade
|
- **Optional, both:** the client has kept a `nextcloud.cfg.backup_<date>_<version>` from every upgrade
|
||||||
since 2023 (about twenty on each machine). It also keeps a sync log that it no longer writes, at
|
since 2023 (about twenty on each machine). It also keeps a sync log that it no longer writes, at
|
||||||
`~/.config/Nextcloud/Nextcloud_sync.log`, from 2024 on g14 and 2023 on shanks. They are the
|
`~/.config/Nextcloud/Nextcloud_sync.log`, from 2024 on node-b and 2023 on node-d. They are the
|
||||||
operator's to delete. The module leaves them.
|
operator's to delete. The module leaves them.
|
||||||
|
|
||||||
## Leaves as found
|
## Leaves as found
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ type SecretAnswer struct {
|
|||||||
var aName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,62}$`)
|
var aName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,62}$`)
|
||||||
|
|
||||||
// aCaller is who asked, as the controller names the bus's caller (novox/hq ADR 0277): a principal such as
|
// aCaller is who asked, as the controller names the bus's caller (novox/hq ADR 0277): a principal such as
|
||||||
// `g14/claude-code`, or an account at a shell, in a name's characters and spaces, at most 80. Nothing else — no line
|
// `node-b/claude-code`, or an account at a shell, in a name's characters and spaces, at most 80. Nothing else — no line
|
||||||
// break, no markup, no punctuation a sentence is written with — so the prompt's words stay this holder's.
|
// break, no markup, no punctuation a sentence is written with — so the prompt's words stay this holder's.
|
||||||
var aCaller = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._/@ -]{0,79}$`)
|
var aCaller = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._/@ -]{0,79}$`)
|
||||||
|
|
||||||
|
|||||||
@@ -113,11 +113,11 @@ func TestThePromptIsWrittenHereFromNamesAndSaysTheControllerAsks(t *testing.T) {
|
|||||||
t.Errorf("prompt %q, message %q", q.Prompt, q.Message)
|
t.Errorf("prompt %q, message %q", q.Prompt, q.Message)
|
||||||
}
|
}
|
||||||
// Asked by the vault's own account, as the runtime proved it (issue 723): the prompt says the vault asks.
|
// Asked by the vault's own account, as the runtime proved it (issue 723): the prompt says the vault asks.
|
||||||
if q, err := secretQuestion("novox.mesh-vault", base); err != nil ||
|
if q, err := secretQuestion("node-c.mesh-vault", base); err != nil ||
|
||||||
!strings.HasPrefix(q.Message, "The mesh's vault asks for telegram-token") {
|
!strings.HasPrefix(q.Message, "The mesh's vault asks for telegram-token") {
|
||||||
t.Errorf("asked by the vault: %q %v", q.Message, err)
|
t.Errorf("asked by the vault: %q %v", q.Message, err)
|
||||||
}
|
}
|
||||||
if q, _ := secretQuestion("novox.mesh-vault-not", base); !strings.HasPrefix(q.Message, "The mesh's controller") {
|
if q, _ := secretQuestion("node-c.mesh-vault-not", base); !strings.HasPrefix(q.Message, "The mesh's controller") {
|
||||||
t.Errorf("a caller that is not the vault's account is said to be the vault: %q", q.Message)
|
t.Errorf("a caller that is not the vault's account is said to be the vault: %q", q.Message)
|
||||||
}
|
}
|
||||||
// And who asked the controller, when it says so (novox/hq ADR 0277): a caller's name, in a name's characters.
|
// And who asked the controller, when it says so (novox/hq ADR 0277): a caller's name, in a name's characters.
|
||||||
@@ -125,13 +125,13 @@ func TestThePromptIsWrittenHereFromNamesAndSaysTheControllerAsks(t *testing.T) {
|
|||||||
for k, v := range base {
|
for k, v := range base {
|
||||||
withAsker[k] = v
|
withAsker[k] = v
|
||||||
}
|
}
|
||||||
withAsker["asked_by"] = "g14/claude-code"
|
withAsker["asked_by"] = "node-b/claude-code"
|
||||||
q, err = secretQuestion("unproven", withAsker)
|
q, err = secretQuestion("unproven", withAsker)
|
||||||
if err != nil || !strings.Contains(q.Message, "It was asked for by g14/claude-code.") {
|
if err != nil || !strings.Contains(q.Message, "It was asked for by node-b/claude-code.") {
|
||||||
t.Errorf("asked_by: %q %v", q.Message, err)
|
t.Errorf("asked_by: %q %v", q.Message, err)
|
||||||
}
|
}
|
||||||
withAsker["asked_by"] = "jochen at a shell on novox"
|
withAsker["asked_by"] = "operator at a shell on node-c"
|
||||||
if q, err = secretQuestion("unproven", withAsker); err != nil || !strings.Contains(q.Message, "It was asked for by jochen at a shell on novox.") {
|
if q, err = secretQuestion("unproven", withAsker); err != nil || !strings.Contains(q.Message, "It was asked for by operator at a shell on node-c.") {
|
||||||
t.Errorf("asked_by at a shell: %q %v", q.Message, err)
|
t.Errorf("asked_by at a shell: %q %v", q.Message, err)
|
||||||
}
|
}
|
||||||
for key, value := range map[string]any{
|
for key, value := range map[string]any{
|
||||||
|
|||||||
@@ -45,15 +45,15 @@ func (b *bucketBus) Delete(_ context.Context, bucket, key string) error {
|
|||||||
// the entry's values are the controller's composition, copied unchanged, and no vault is asked.
|
// the entry's values are the controller's composition, copied unchanged, and no vault is asked.
|
||||||
func TestAConsumerOfARouteIsToldItsNamesFromItsPlanEntry(t *testing.T) {
|
func TestAConsumerOfARouteIsToldItsNamesFromItsPlanEntry(t *testing.T) {
|
||||||
bus := &bucketBus{buckets: map[string]map[string][]byte{}}
|
bus := &bucketBus{buckets: map[string]map[string][]byte{}}
|
||||||
plan, _ := json.Marshal(map[string]any{"node": "g14", "module": "gitea", "provisioning": map[string]any{
|
plan, _ := json.Marshal(map[string]any{"node": "node-b", "module": "gitea", "provisioning": map[string]any{
|
||||||
"provisions": []any{map[string]any{"provision": ProvisionName, "provider": "novox",
|
"provisions": []any{map[string]any{"provision": ProvisionName, "provider": "node-c",
|
||||||
"provider-module": ModuleName, "at": "10.7.0.1", "from": "novox", "as": "mesh_g14_gitea",
|
"provider-module": ModuleName, "at": "10.7.0.1", "from": "node-c", "as": "mesh_node_b_gitea",
|
||||||
"names": map[string]any{"name": "git.example.org", "internal-name": "git.novox.internal",
|
"names": map[string]any{"name": "git.example.org", "internal-name": "git.node-c.internal",
|
||||||
"name-web": "git.example.org"}}}}})
|
"name-web": "git.example.org"}}}}})
|
||||||
if err := bus.Put(context.Background(), provider.AssignmentsBucket, "g14.gitea", plan); err != nil {
|
if err := bus.Put(context.Background(), provider.AssignmentsBucket, "node-b.gitea", plan); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
p := newProvider("novox", bus, t.Logf)
|
p := newProvider("node-c", bus, t.Logf)
|
||||||
out, err := p.Pass(context.Background())
|
out, err := p.Pass(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -62,11 +62,11 @@ func TestAConsumerOfARouteIsToldItsNamesFromItsPlanEntry(t *testing.T) {
|
|||||||
t.Fatalf("the pass did %+v", out)
|
t.Fatalf("the pass did %+v", out)
|
||||||
}
|
}
|
||||||
var e provider.Entry
|
var e provider.Entry
|
||||||
if err := json.Unmarshal(bus.buckets[provider.BucketOf(ModuleName)]["g14.gitea.route"], &e); err != nil {
|
if err := json.Unmarshal(bus.buckets[provider.BucketOf(ModuleName)]["node-b.gitea.route"], &e); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if e.Values["name-web"] != "git.example.org" || e.Values["name"] != "git.example.org" ||
|
if e.Values["name-web"] != "git.example.org" || e.Values["name"] != "git.example.org" ||
|
||||||
e.Values["internal-name"] != "git.novox.internal" || e.VaultName != "" || e.User != "" || e.Refused != "" {
|
e.Values["internal-name"] != "git.node-c.internal" || e.VaultName != "" || e.User != "" || e.Refused != "" {
|
||||||
t.Fatalf("the entry is %+v", e)
|
t.Fatalf("the entry is %+v", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user