- Docs: kernel-program truth, PLACEHOLDER_BASELINE, POSIX_DECLARED_PROFILE, env appendix (BARE_OS_SHELL_PIPEFAIL, BARE_OS_WASM_KERNEL), package-bare-os-booter - Booter: syscalls.json fd model, process_table exitStatusModel, shell pipeline exit status + kernel-runner script-error path, mirror mounts test + handbook - Seeder: corestore_snapshot proc alignment test; hyperswarm ^4.17.0; kernel mirror sync - Vault: vault_save audit after saveVaultToDrive; split bare-os-vault-rotation-audit.js - Contract: protomux/hyperswarm lock fixture + test; IPC stats ipcBackpressure test - Coreutils: XCU tests, bare-cron man seed, ACL/xattr metadata path test - Tooling: kernel-microbench + release-gate fixture doc; ADR 002 WASM compile hook - Changelog/ctx d.ts and dependency/lockfile updates as needed
204 lines
5.3 KiB
JavaScript
204 lines
5.3 KiB
JavaScript
/**
|
|
* getfacl / setfacl / xattr against an in-memory vfs stub.
|
|
*/
|
|
import { readFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import test from 'brittle'
|
|
import b4a from 'b4a'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor
|
|
|
|
/**
|
|
* @param {string} name
|
|
*/
|
|
async function loadBin(name) {
|
|
const runtime = await readFile(
|
|
path.join(__dirname, '../lib/runtime.js'),
|
|
'utf8'
|
|
)
|
|
const body = await readFile(
|
|
path.join(__dirname, `../src/${name}.js`),
|
|
'utf8'
|
|
)
|
|
return new AsyncFunction(
|
|
'ctx',
|
|
'argv',
|
|
`${runtime}\n${body}\nif (typeof run === 'function') return await run(ctx, argv)\n`
|
|
)
|
|
}
|
|
|
|
function createCtx(store) {
|
|
const logs = []
|
|
const errs = []
|
|
return {
|
|
b4a,
|
|
exitCode: 0,
|
|
shellStdin: '',
|
|
console: {
|
|
log: (m) => logs.push(String(m)),
|
|
error: (m) => errs.push(String(m))
|
|
},
|
|
vfs: {
|
|
async stat(p) {
|
|
if (!Object.prototype.hasOwnProperty.call(store.files, p)) return null
|
|
return store.files[p].stat
|
|
},
|
|
async readFile(p) {
|
|
const ent = store.files[p]
|
|
if (!ent) return null
|
|
return ent.body
|
|
},
|
|
async writeFile(p, body) {
|
|
store.files[p] = {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: Date.now() },
|
|
body: body instanceof Uint8Array ? body : b4a.from(body)
|
|
}
|
|
},
|
|
async unlink(p) {
|
|
delete store.files[p]
|
|
}
|
|
},
|
|
_logs: logs,
|
|
_errs: errs
|
|
}
|
|
}
|
|
|
|
test('getfacl synthesizes mode triples and reads sidecar', async (t) => {
|
|
const store = {
|
|
files: {
|
|
'/a': {
|
|
stat: { mode: 0o755, type: 'file', mtimeMs: 1 },
|
|
body: null
|
|
},
|
|
'/b': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: null
|
|
},
|
|
'/b.bare_acl': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: b4a.from('user::rw-\n')
|
|
}
|
|
}
|
|
}
|
|
const runA = await loadBin('getfacl')
|
|
const ctxA = createCtx(store)
|
|
await runA(ctxA, ['getfacl', '-c', '/a'])
|
|
t.is(ctxA.exitCode, 0)
|
|
t.is(ctxA._logs.join('\n'), 'user::rwx\ngroup::r-x\nother::r-x')
|
|
|
|
const runB = await loadBin('getfacl')
|
|
const ctxB = createCtx(store)
|
|
await runB(ctxB, ['getfacl', '/b'])
|
|
t.is(ctxB.exitCode, 0)
|
|
t.ok(ctxB._logs[0].includes('user::rw-'))
|
|
})
|
|
|
|
test('getfacl documents mask-style sidecars for VFS enforcement', async (t) => {
|
|
const store = {
|
|
files: {
|
|
'/c': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: null
|
|
},
|
|
'/c.bare_acl': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: b4a.from('user::rw-\nother::---\n')
|
|
}
|
|
}
|
|
}
|
|
const run = await loadBin('getfacl')
|
|
const ctx = createCtx(store)
|
|
await run(ctx, ['getfacl', '-c', '/c'])
|
|
t.is(ctx.exitCode, 0)
|
|
t.ok(ctx._logs.join('\n').includes('other::---'))
|
|
})
|
|
|
|
test('setfacl -b and stdin write', async (t) => {
|
|
const store = {
|
|
files: {
|
|
'/x': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: null
|
|
},
|
|
'/x.bare_acl': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: b4a.from('old\n')
|
|
}
|
|
}
|
|
}
|
|
const runClear = await loadBin('setfacl')
|
|
const ctx1 = createCtx(store)
|
|
await runClear(ctx1, ['setfacl', '-b', '/x'])
|
|
t.is(ctx1.exitCode, 0)
|
|
t.absent(store.files['/x.bare_acl'])
|
|
|
|
const runSet = await loadBin('setfacl')
|
|
const ctx2 = createCtx(store)
|
|
ctx2.shellStdin = 'user::r--\n'
|
|
await runSet(ctx2, ['setfacl', '/x'])
|
|
t.is(ctx2.exitCode, 0)
|
|
t.is(b4a.toString(store.files['/x.bare_acl'].body), 'user::r--\n')
|
|
})
|
|
|
|
test('xattr -w -l -d round trip', async (t) => {
|
|
const store = {
|
|
files: {
|
|
'/f': {
|
|
stat: { mode: 0o644, type: 'file', mtimeMs: 1 },
|
|
body: null
|
|
}
|
|
}
|
|
}
|
|
const runW = await loadBin('xattr')
|
|
const ctxW = createCtx(store)
|
|
await runW(ctxW, ['xattr', '-w', 'user.t', 'hi', '/f'])
|
|
t.is(ctxW.exitCode, 0)
|
|
|
|
const runL = await loadBin('xattr')
|
|
const ctxL = createCtx(store)
|
|
await runL(ctxL, ['xattr', '-l', '/f'])
|
|
t.is(ctxL.exitCode, 0)
|
|
t.is(ctxL._logs.join('\n'), 'user.t: hi')
|
|
|
|
const runD = await loadBin('xattr')
|
|
const ctxD = createCtx(store)
|
|
await runD(ctxD, ['xattr', '-d', 'user.t', '/f'])
|
|
t.is(ctxD.exitCode, 0)
|
|
|
|
const runNames = await loadBin('xattr')
|
|
const ctxN = createCtx(store)
|
|
await runNames(ctxN, ['xattr', '/f'])
|
|
t.is(ctxN.exitCode, 0)
|
|
t.is(ctxN._logs.length, 0)
|
|
})
|
|
|
|
test('getfacl and xattr on personal-drive-shaped metadata paths', async (t) => {
|
|
const meta = '/.bare/os/registry.json'
|
|
const store = {
|
|
files: {
|
|
[meta]: {
|
|
stat: { mode: 0o600, type: 'file', mtimeMs: 1 },
|
|
body: b4a.from('{}')
|
|
},
|
|
[`${meta}.bare_acl`]: {
|
|
stat: { mode: 0o600, type: 'file', mtimeMs: 1 },
|
|
body: b4a.from('user::rw-\nother::---\n')
|
|
}
|
|
}
|
|
}
|
|
const runG = await loadBin('getfacl')
|
|
const ctxG = createCtx(store)
|
|
await runG(ctxG, ['getfacl', '-c', meta])
|
|
t.is(ctxG.exitCode, 0)
|
|
t.ok(ctxG._logs.join('\n').includes('other::---'))
|
|
|
|
const runX = await loadBin('xattr')
|
|
const ctxX = createCtx(store)
|
|
await runX(ctxX, ['xattr', '-w', 'user.meta', 'v1', meta])
|
|
t.is(ctxX.exitCode, 0)
|
|
t.ok(store.files[`${meta}.bare_xattr.json`])
|
|
})
|