zsh: let a machine withhold node-login-shell's execute
mesh/merge-gate pass: builds zsh → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group withhold-login-shell-execute delivered: every member is delivered
mesh/merge-gate pass: builds zsh → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group withhold-login-shell-execute delivered: every member is delivered
execute runs any command as the operator account, which can become root without a person. The operator withholds it on the control-node until a call needs a person's approval (hq ADR 0268); the other machines keep it for now. The setting execute (serve by default) is written into a root-owned file the tools bundle reads at start, and anything but serve withholds the verb, so the machine's runtime does not offer it.
This commit is contained in:
@@ -69,3 +69,26 @@ test("the tools bundle registers the seat's verb under node-login-shell", () =>
|
||||
assert.match(src, /registerModuleTools\("node-login-shell", seatVerbs\)/);
|
||||
assert.doesNotMatch(src, /runuser|"login-shell"/);
|
||||
});
|
||||
|
||||
test("execute is a per-machine setting, served unless a machine withholds it (ADR 0268)", () => {
|
||||
assert.deepEqual(Object.keys(m.settings), ["execute"]);
|
||||
assert.equal(m.settings.execute.kind, "preference");
|
||||
assert.equal(m.settings.execute.default, "serve");
|
||||
assert.match(m.settings.execute.why, /withhold/);
|
||||
const dir = resource("state");
|
||||
assert.deepEqual(dir, { id: "state", type: "directory", place: ".", owner: "root", mode: "0755" });
|
||||
const conf = resource("tools-conf");
|
||||
assert.equal(conf.type, "file");
|
||||
assert.equal(conf.path, "${dir:state}/tools.conf");
|
||||
assert.equal(conf.owner, "root", "the account the runtime runs as may read it, never change it");
|
||||
assert.equal(conf.mode, "0644");
|
||||
assert.match(conf.content, /^execute=\$\{setting:execute\}$/m);
|
||||
const [bundle] = m.build.artifacts;
|
||||
assert.deepEqual(bundle.env, { ZSH_TOOLS_CONF: conf.path }, "the word names the file exactly, so its change restarts the runtime");
|
||||
});
|
||||
|
||||
test("the tools bundle registers execute only where the machine's setting serves it", () => {
|
||||
const src = readFileSync(new URL("../tools/index.ts", import.meta.url), "utf8");
|
||||
assert.match(src, /readExecuteSetting\(env\)/);
|
||||
assert.match(src, /if \(!setting\.served\)[\s\S]{0,200}return \[\]/);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Withholding node-login-shell's `execute` on one machine (novox/hq ADR 0268). It runs any command as the
|
||||
// operator account, which can become root without a person, so the operator withholds it on the
|
||||
// control-node until a call to it needs a person's approval. The machine's choice is the module's
|
||||
// setting `execute`, written by the mesh into a root-owned file the tools bundle reads at start; the
|
||||
// bundle then registers the verb or not, so the machine's runtime does not offer it at all.
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { executeServed, readExecuteSetting, TOOLS_CONF_WORD } from "../shell.ts";
|
||||
|
||||
test("execute is served only when the machine's setting says serve", () => {
|
||||
assert.equal(executeServed("execute=serve\n").served, true);
|
||||
assert.equal(executeServed("# the mesh's\nexecute = serve \n").served, true);
|
||||
const withheld = executeServed("execute=withhold\n");
|
||||
assert.equal(withheld.served, false);
|
||||
assert.match(withheld.why, /withhold/);
|
||||
});
|
||||
|
||||
test("anything but serve withholds it: a wrong value, no line, no file", () => {
|
||||
for (const text of ["execute=yes\n", "execute=\n", "", "other=serve\n", "execute=serve-ish\n"]) {
|
||||
const got = executeServed(text);
|
||||
assert.equal(got.served, false, JSON.stringify(text));
|
||||
assert.ok(got.why.length > 0, "it says why");
|
||||
}
|
||||
const none = executeServed(undefined);
|
||||
assert.equal(none.served, false);
|
||||
assert.match(none.why, /no setting/);
|
||||
});
|
||||
|
||||
test("the setting is read from the file the bundle's word names", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "zsh-tools-"));
|
||||
const file = join(dir, "tools.conf");
|
||||
writeFileSync(file, "execute=serve\n");
|
||||
assert.equal(readExecuteSetting({ [TOOLS_CONF_WORD]: file }).served, true);
|
||||
writeFileSync(file, "execute=withhold\n");
|
||||
assert.equal(readExecuteSetting({ [TOOLS_CONF_WORD]: file }).served, false);
|
||||
const missing = readExecuteSetting({ [TOOLS_CONF_WORD]: join(dir, "absent.conf") });
|
||||
assert.equal(missing.served, false);
|
||||
assert.match(missing.why, /cannot read/);
|
||||
const unnamed = readExecuteSetting({});
|
||||
assert.equal(unnamed.served, false);
|
||||
assert.match(unnamed.why, new RegExp(TOOLS_CONF_WORD));
|
||||
});
|
||||
Reference in New Issue
Block a user