Make hostd jail destroy non-interactive (Sam & Claude)

Feed bastille destroy confirmation through hostd so scripts can switch from sudo pipelines to hostd-call.sh safely.

---
Build: pass
Tests: pass — 90 passed (1 file)

---
Build: pass | Tests: pass — 2372 passed (704 files)
This commit is contained in:
Operator & Codex 2026-05-10 18:14:57 +02:00
parent 7dca9282bb
commit 537c6139d4
2 changed files with 13 additions and 2 deletions

View file

@ -53,6 +53,7 @@ describe('handleOp — dispatch', () => {
'bastille-stop',
'bastille-restart',
'bastille-list',
'bastille-destroy',
'bastille-pkg-install',
'bastille-mount-pkg-cache',
'zfs-snapshot',
@ -292,6 +293,15 @@ describe('handleOp — spawnSync args (Bastille)', () => {
);
});
it('bastille-destroy confirms the interactive prompt non-interactively', () => {
handleOp('bastille-destroy', { jail: 'clawdie-old' });
expect(mockSpawnSync).toHaveBeenCalledWith(
'bastille',
['destroy', 'clawdie-old'],
expect.objectContaining({ input: 'y\n' }),
);
});
it('bastille-pkg-install: splits packages into args', () => {
handleOp('bastille-pkg-install', {
jail: 'clawdie-worker',

View file

@ -70,12 +70,13 @@ export interface OpResult {
function exec(
cmd: string,
args: string[],
opts: { timeoutMs?: number } = {},
opts: { timeoutMs?: number; input?: string } = {},
): OpResult {
const result = spawnSync(cmd, args, {
encoding: 'utf-8',
env: process.env,
...(opts.timeoutMs ? { timeout: opts.timeoutMs } : {}),
...(opts.input !== undefined ? { input: opts.input } : {}),
});
const output = [result.stdout || '', result.stderr || '']
.filter(Boolean)
@ -248,7 +249,7 @@ const OPS: Record<string, OpEntry> = {
},
'bastille-destroy': {
schema: z.object({ jail: jailName }),
handler: (p) => exec('bastille', ['destroy', String(p.jail)]),
handler: (p) => exec('bastille', ['destroy', String(p.jail)], { input: 'y\n' }),
},
// ── ZFS ──────────────────────────────────────────────────────────────────