Complete the internal “100 task” roadmap: coreutils and shell parity (xargs,
sh, diff/patch, sort, printf, find, test, getfacl/setfacl/xattr), expanded /proc and metrics (process table, syscalls, replication, net, security posture, worker budget, swarm/replication hints), initd DAG supervision metadata and richer restart journal telemetry, synthetic process groups via IPC (assignProcessGroup/signalProcessGroup) mirrored into process_table, optional kernel.ext.d incremental hot reload (BARE_OS_KERNEL_EXT_D_HOT_RELOAD) with reload audit NDJSON, features proc for hyperblobs dedup and systemd subset documentation, vault threat model doc plus posture fields for AEAD, Pear enclave pointer, account rotation continuity, and Ed25519 consistency across boot manifest / extensions / replication. Adds or extends tests and keeps kernel/ and packages/bare-os-seeder/kernel/ in parity; guest init is bundled from kernel/lib/init/init-main.js via bundle-kernel-init.
This commit is contained in:
@@ -42,6 +42,13 @@
|
||||
* BARE_OS_BOOT_MANIFEST_SIGN=1: verify Ed25519 signature in /etc/bare-os/boot.manifest.sig over the raw
|
||||
* manifest bytes; public key from BARE_OS_BOOT_MANIFEST_PUBKEY_HEX (64 hex chars). Uses ctx.bareOsVerifyBootManifestSignature.
|
||||
*
|
||||
* BARE_OS_KERNEL_EXT_D_HOT_RELOAD=1: after boot, exposes **`ctx.bareOsReloadKernelExtDropinsSafe()`** which re-scans
|
||||
* `/etc/bare-os/kernel.ext.d` and runs only extension scripts not yet recorded in **`ctx.bareOsLoadedKernelExtScripts`**
|
||||
* (append-only; does not unload). Append-only audit: **`/run/bare-os/kernel-ext-reload.ndjson`** when **`ctx.vfs.writeFile`** exists.
|
||||
*
|
||||
* BARE_OS_VFS_HYPERBLOBS_DEDUP=1: operator hint surfaced in **`/proc/bare_os/features`** — content-defined chunking may be enabled
|
||||
* in host mirror/hyperblob pipelines; the guest VFS does not turn on hyperblobs automatically.
|
||||
*
|
||||
* BARE_OS_BOOT_POLICY=1: merge `skipBootStages` / `denyBootStages` from boot.policy (legacy `skipPhases` / `denyBootPhases` still honored; see applyBootPolicyFile). Optional `policyFallbackPaths` for tiered skip merge; `initdAdmission` sets initd env caps; `extensionSignerPinsV5` multi-signer pins.
|
||||
* Boot policy v2 (optional): `maxExecLineDepth`, `denyEnvKeys`, `requireProcNodes` (VFS paths under /proc).
|
||||
* Optional `minKernelCapabilitiesPrimary` / `requireSeedCaps` (integers) when ctx exposes
|
||||
@@ -109,6 +116,43 @@ function applyBootSafeMode(ctx) {
|
||||
pol.add('onboot')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
*/
|
||||
function kernelExtHotReloadEnabled(ctx) {
|
||||
const v = ctx.env?.BARE_OS_KERNEL_EXT_D_HOT_RELOAD
|
||||
return v === '1' || v === 'true'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {Record<string, unknown>} row
|
||||
*/
|
||||
async function maybeAppendKernelExtReloadJournal(ctx, row) {
|
||||
const vfs = ctx.vfs
|
||||
const b4 = ctx.b4a
|
||||
if (!vfs || typeof vfs.writeFile !== 'function' || !b4) return
|
||||
const path = '/run/bare-os/kernel-ext-reload.ndjson'
|
||||
const line =
|
||||
JSON.stringify({
|
||||
kernelExtReloadSchemaVersion: 1,
|
||||
ts: Date.now(),
|
||||
...row
|
||||
}) + '\n'
|
||||
try {
|
||||
let prev = ''
|
||||
try {
|
||||
const buf = await vfs.readFile(path)
|
||||
if (buf) prev = b4.toString(buf)
|
||||
} catch {
|
||||
/* new */
|
||||
}
|
||||
await vfs.writeFile(path, b4.from(prev + line))
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
async function maybeAppendBootTransactionJournal(ctx, row) {
|
||||
const en = ctx.env && ctx.env.BARE_OS_BOOT_TRANSACTION_JOURNAL
|
||||
if (en !== '1' && en !== 'true' && en !== 'ndjson') return
|
||||
@@ -2017,12 +2061,20 @@ function kernelExtDependencyDepth(entries) {
|
||||
/**
|
||||
* Optional `/etc/bare-os/kernel.ext.d/*.json` with `{ "scripts": ["/lib/bare-os/extensions/foo.js"] }`.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {{ incremental?: boolean, ranScripts?: string[] }} [opts]
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runKernelExtDropins(ctx) {
|
||||
async function runKernelExtDropins(ctx, opts = {}) {
|
||||
const incremental = opts.incremental === true
|
||||
const ranScripts = opts.ranScripts
|
||||
const { drive, console } = ctx
|
||||
const run = ctx.bareOsRunImageScript
|
||||
if (typeof run !== 'function') return true
|
||||
if (!ctx.bareOsLoadedKernelExtScripts) {
|
||||
ctx.bareOsLoadedKernelExtScripts = new Set()
|
||||
}
|
||||
/** @type {Set<string>} */
|
||||
const loadedSet = /** @type {Set<string>} */ (ctx.bareOsLoadedKernelExtScripts)
|
||||
const denyRaw = String(
|
||||
ctx.env?.BARE_OS_BOOT_POLICY_DENY_KERNEL_EXT_IDS || ''
|
||||
).trim()
|
||||
@@ -2174,12 +2226,17 @@ async function runKernelExtDropins(ctx) {
|
||||
console.error(`[kernel.ext.d] rejected script path: ${imgPath}`)
|
||||
continue
|
||||
}
|
||||
if (incremental && loadedSet.has(imgPath)) {
|
||||
continue
|
||||
}
|
||||
if (dry) {
|
||||
console.error(`[boot-dry-run] skip kernel.ext.d script: ${imgPath}`)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await run(imgPath)
|
||||
loadedSet.add(imgPath)
|
||||
if (Array.isArray(ranScripts)) ranScripts.push(imgPath)
|
||||
if (typeof ctx.bareOsRegisterKernelExtensionRecord === 'function') {
|
||||
ctx.bareOsRegisterKernelExtensionRecord({
|
||||
dropin: ent.file,
|
||||
@@ -2459,6 +2516,38 @@ async function runKernelSelftest(ctx) {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {number} bootT0
|
||||
* @param {string[]} stageLog
|
||||
*/
|
||||
async function maybeWriteBootPerfJson(ctx, bootT0, stageLog) {
|
||||
const vfs = ctx.vfs
|
||||
const b4 = ctx.b4a
|
||||
if (!vfs || typeof vfs.readFile !== 'function' || typeof vfs.writeFile !== 'function' || !b4)
|
||||
return
|
||||
const wall = Date.now() - bootT0
|
||||
const budgetRaw = Number.parseInt(
|
||||
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_COLD || ''),
|
||||
10
|
||||
)
|
||||
const budget = Number.isFinite(budgetRaw) && budgetRaw > 0 ? budgetRaw : null
|
||||
const row =
|
||||
JSON.stringify({
|
||||
schema: 1,
|
||||
coldWallMs: wall,
|
||||
bootBudgetMsCold: budget,
|
||||
withinBudget: budget == null ? null : wall <= budget,
|
||||
stageCount: stageLog.length,
|
||||
completedAtMs: Date.now()
|
||||
}) + '\n'
|
||||
try {
|
||||
await vfs.writeFile('/run/bare-os/boot-perf.json', b4.from(row))
|
||||
} catch {
|
||||
/* optional */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string[]} stageLog
|
||||
@@ -2505,7 +2594,8 @@ function publishBootReady(ctx, stageLog) {
|
||||
schema: 1,
|
||||
state: 'committed',
|
||||
note: 'Guest kernel finished boot stage sequence; see boot-transaction.ndjson for per-stage rows.'
|
||||
}
|
||||
},
|
||||
kernelExtHotReload: kernelExtHotReloadEnabled(ctx)
|
||||
}
|
||||
},
|
||||
initd: { awaited: true }
|
||||
@@ -2731,6 +2821,27 @@ async function start(ctx) {
|
||||
)
|
||||
if (!bootOk) return
|
||||
publishBootReady(ctx, stageLog)
|
||||
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
|
||||
if (kernelExtHotReloadEnabled(ctx)) {
|
||||
ctx.bareOsReloadKernelExtDropinsSafe = async () => {
|
||||
if (!kernelExtHotReloadEnabled(ctx)) {
|
||||
return { ok: false, reason: 'env_disabled', atMs: Date.now() }
|
||||
}
|
||||
/** @type {string[]} */
|
||||
const ran = []
|
||||
const ok = await runKernelExtDropins(ctx, {
|
||||
incremental: true,
|
||||
ranScripts: ran
|
||||
})
|
||||
await maybeAppendKernelExtReloadJournal(ctx, {
|
||||
ok,
|
||||
incremental: true,
|
||||
ranScripts: ran,
|
||||
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
|
||||
})
|
||||
return { ok, ranScripts: ran, atMs: Date.now() }
|
||||
}
|
||||
}
|
||||
{
|
||||
const budget = Number.parseInt(
|
||||
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_COLD || ''),
|
||||
|
||||
Reference in New Issue
Block a user