mesh-catalog #495 gave read on every repository to the tools' account alone. The build modules fetch over ssh as nox-builder (the forge-account provider's builders account, ADR 0466 §3), so ace's and g14's fetch of jschoubben/car-hunter and jschoubben/snake still failed; the machines' agents (nox-agent, ADR 0410 §1) could not read them either. - gitea: readall.ts grants every account of one list, meshAccounts in tools-account.ts (mesh-tools, nox-builder, nox-agent; a Go test holds the two Go names to internal/forgeaccount's constants), on the same start pass, forge events and tools. gitea_unreadable_repos answers per account and names the accounts the forge does not hold yet; gitea_grant_read takes accounts as well as repositories. An absent account is asked nothing; the start pass runs again ten minutes apart until every account was there once. - mesh-build-go, mesh-build-node, mesh-build-image: pin mesh-sdk 84275cfc (fix/fetch-reads-all), whose forgekey.Said keeps git's words past the bare "error:" line: the mirror's line said only "git -C: error:". Their own git reasons (ls-files, ls-remote, rev-parse, repack) go through it too.
56 lines
1.9 KiB
Go
56 lines
1.9 KiB
Go
package forgeaccount
|
|
|
|
import (
|
|
"os"
|
|
"regexp"
|
|
"testing"
|
|
)
|
|
|
|
func TestForgeUserOfAMachineAccountIsTheOneAgentUser(t *testing.T) {
|
|
if got := ForgeUser("g14", "machine"); got != "nox-agent" {
|
|
t.Fatalf("ForgeUser = %q", got)
|
|
}
|
|
if got := ForgeUser("g14", "other"); got != "" {
|
|
t.Fatalf("a kind not built yet has no forge user, got %q", got)
|
|
}
|
|
if got := ForgeUser("ace", "machine"); got != "nox-agent" {
|
|
t.Fatalf("every machine shares one forge user, got %q", got)
|
|
}
|
|
if got := NodeAccount("g14"); got != "agent-g14" {
|
|
t.Fatalf("the token tool's per-node account = %q", got)
|
|
}
|
|
// The accounts that read every repository (readall.ts, meshAccounts in tools-account.ts) name these two users: the
|
|
// list is held to the Go constants here, so the two cannot drift apart (the operator, 2026-10-26).
|
|
ts, err := os.ReadFile("../../tools-account.ts")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for name, want := range map[string]string{"BUILDER_ACCOUNT": BuilderUser, "AGENT_ACCOUNT": AgentUser} {
|
|
m := regexp.MustCompile(`export const ` + name + ` = "([^"]+)";`).FindSubmatch(ts)
|
|
if m == nil || string(m[1]) != want {
|
|
t.Errorf("tools-account.ts %s = %q, want %q (internal/forgeaccount)", name, m, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRemoveKeysTitledTakesOnlyTheMeshKeysOfThatTitle(t *testing.T) {
|
|
f := &keyForge{keys: map[string][]heldKey{"agent-g14": {
|
|
{ID: 1, Title: "mesh:g14.nox", Key: keyA},
|
|
{ID: 2, Title: "mesh:g14.other", Key: keyB},
|
|
{ID: 3, Title: "by hand", Key: "ssh-ed25519 CCCC"},
|
|
}}, next: 3}
|
|
a := keyAccounts(t, f)
|
|
if _, err := a.RemoveKeysTitled(t.Context(), "agent-g14", "mesh:g14.nox"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := f.keys["agent-g14"]; len(got) != 2 || got[0].ID != 2 || got[1].ID != 3 {
|
|
t.Fatalf("held = %v", got)
|
|
}
|
|
if _, err := a.RemoveKeysTitled(t.Context(), "agent-g14", "by hand"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(f.keys["agent-g14"]) != 2 {
|
|
t.Fatal("a key that is not the mesh's was removed")
|
|
}
|
|
}
|