feat: ctx 1.37.0, /bin/link, blind-peer proc gate, and CI/docs follow-ups
- Bump bareOsCtxApiVersion to 1.37.0; sync syscalls.example.json and ctx helper - Add ctx.bareOsReadSnapshotHintsJson mirroring snapshot_hints proc JSON - Gate blind_relay_router / blind_pairing_sketch / relay_geo_hint behind BARE_OS_PROC_BLIND_PEER_RELAY_HINTS; passthrough + env appendix docs - Add POSIX link(1) via coreutils (link.js, man, commands list, kernel bin) - Fix JSDoc in verify-runtime-no-incomplete-markers (avoid */ in glob text) - Align posix-conformance-matrix bareOsSyscallOps with getconf (select, umask) - Add verify-holepunch-clone-drift.mjs (opt-in pretest), holepunch-drift-repos.json, originMainHead in sync-holepunch-clones report - Tests: warm /bin cache clear, blind proc stub, protomux pool schema 2, glob cap - Docs: systemctl man, compatibility matrix boot.policy pins, handbook ch.5 vault/proc note, package-bare-os-booter, kernel-extensions, developer-guide ctx - CHANGELOG and bare-os-ctx.d.ts updates for subprocess bridge and mirror mounts
This commit is contained in:
+2
-2
@@ -139,10 +139,10 @@ const CONF = {
|
||||
_PC_2_SYMLINKS: '1',
|
||||
/** Comma-separated `ctx.bareOsSyscall` op names implemented in stock booter. */
|
||||
BARE_OS_SYSCALL_OPS:
|
||||
'access,chdir,chmod,exists,fcntl,fdatasync,fsync,ftruncate,getcwd,kill,link,lstat,mkdir,mount,pathconf,posixPoll,readFile,readdir,readlink,rename,rmdir,stat,symlink,truncate,umount,unlink,utimes,writeFile',
|
||||
'access,chdir,chmod,exists,fcntl,fdatasync,fsync,ftruncate,getcwd,kill,link,lstat,mkdir,mount,pathconf,posixPoll,readFile,readdir,readlink,rename,rmdir,select,stat,symlink,truncate,umask,umount,unlink,utimes,writeFile',
|
||||
/** POSIX.1 XSH-style names documented in `/proc/bare_os/syscalls.json` opsDetail (not separate ctx ops). */
|
||||
BARE_OS_POSIX_XSH_OPS:
|
||||
'open,close,read,write,lseek,pipe,dup,dup2,fcntl,poll',
|
||||
'open,close,read,write,lseek,pipe,dup,dup2,fcntl,poll,select,umask',
|
||||
/** Encodings accepted by `/bin/iconv` (subset; case-insensitive names). */
|
||||
BARE_OS_ICONV_ENCODINGS: 'UTF-8,ISO-8859-1,UTF-16LE,UTF-16BE',
|
||||
/** Synthetic process table JSON path (logical VFS). */
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
var BARE_OS_HELP_BIN_SPACED = "arch awk baretop base32 base64 basename basenc btop bundlebee cat chgrp chmod chown cksum clear cmp comm cp crontab curl cut date dd df diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help hostid hostname hrpc iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill ln logger login logname logout ls man md5sum mkdir mkfifo mktemp mount mv nano nl nohup nproc numfmt od oidc-publish openssl openssl paste patch pathchk pear-runtime-matrix pr printenv printf procstat ps pwd readlink realpath rev rm rmdir savevault sed seq setfacl sh sha1sum sha256sum sha512sum shuf sidecar sleep sort split ssh-keygen ssh-keygen stat sum sync systemctl tac tail tar tar tee test theme time timeout touch tr true truncate tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami xargs xattr yes"
|
||||
var BARE_OS_HELP_BIN_SPACED = "arch awk baretop base32 base64 basename basenc btop bundlebee cat chgrp chmod chown cksum clear cmp comm cp crontab curl cut date dd df diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help hostid hostname hrpc iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln logger login logname logout ls man md5sum mkdir mkfifo mktemp mount mv nano nl nohup nproc numfmt od oidc-publish openssl openssl paste patch pathchk pear-runtime-matrix pr printenv printf procstat ps pwd readlink realpath rev rm rmdir savevault sed seq setfacl sh sha1sum sha256sum sha512sum shuf sidecar sleep sort split ssh-keygen ssh-keygen stat sum sync systemctl tac tail tar tar tee test theme time timeout touch tr true truncate tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami xargs xattr yes"
|
||||
async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'Bare OS — default user: guest | shell builtins: alias, barerc, cd, command, export, exit, login, logout, readonly, type, umask, unalias, unset, : | /bin: ' +
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — bump when staged /bin script semantics change (see developer guide). */
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
/** @param {number} mode @param {'file' | 'directory' | 'symlink'} type */
|
||||
function bareFormatModeString(mode, type) {
|
||||
const typeChar = type === 'directory' ? 'd' : type === 'symlink' ? 'l' : '-'
|
||||
const perm = mode & 0o777
|
||||
const r = (bit) => (perm & bit ? 'r' : '-')
|
||||
const w = (bit) => (perm & bit ? 'w' : '-')
|
||||
const x = (bit) => (perm & bit ? 'x' : '-')
|
||||
return (
|
||||
typeChar +
|
||||
r(0o400) +
|
||||
w(0o200) +
|
||||
x(0o100) +
|
||||
r(0o040) +
|
||||
w(0o020) +
|
||||
x(0o010) +
|
||||
r(0o004) +
|
||||
w(0o002) +
|
||||
x(0o001)
|
||||
)
|
||||
}
|
||||
|
||||
/** @param {number} mtimeMs @param {number} [nowMs] */
|
||||
function bareFormatLsMtime(mtimeMs, nowMs) {
|
||||
const now = nowMs != null ? nowMs : Date.now()
|
||||
const d = new Date(mtimeMs)
|
||||
const months = [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec'
|
||||
]
|
||||
const mon = months[d.getMonth()]
|
||||
const day = String(d.getDate()).padStart(2, ' ')
|
||||
const sixMo = 180 * 24 * 3600 * 1000
|
||||
if (Math.abs(now - mtimeMs) > sixMo) {
|
||||
const yr = String(d.getFullYear()).padStart(4, ' ')
|
||||
return mon + ' ' + day + ' ' + yr
|
||||
}
|
||||
const hh = String(d.getHours()).padStart(2, '0')
|
||||
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||
return mon + ' ' + day + ' ' + hh + ':' + mm
|
||||
}
|
||||
|
||||
/** @param {number} size */
|
||||
function barePosixBlocks(size) {
|
||||
return Math.ceil(Number(size) / 512) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw stdout for NUL/binary when **`process.stdout.write`** is missing.
|
||||
* If **`ctx.bareOsBinWrite(Uint8Array|string)`** is set (tests / host), use it.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string | Uint8Array} chunk
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bareOsEmitRaw(ctx, chunk) {
|
||||
if (typeof ctx.bareOsBinWrite === 'function') {
|
||||
const b4 = ctx.b4a
|
||||
const u8 =
|
||||
typeof chunk === 'string'
|
||||
? b4 && typeof b4.from === 'function'
|
||||
? b4.from(chunk)
|
||||
: new TextEncoder().encode(chunk)
|
||||
: chunk
|
||||
ctx.bareOsBinWrite(u8 instanceof Uint8Array ? u8 : new Uint8Array(u8))
|
||||
return true
|
||||
}
|
||||
const w = globalThis.process?.stdout?.write
|
||||
if (typeof w === 'function') {
|
||||
w.call(globalThis.process.stdout, chunk)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* POSIX `link` utility — delegates to `ctx.bareOsSyscall('link', …)` (copy-on-Hyperdrive semantics).
|
||||
*/
|
||||
async function run(ctx, argv) {
|
||||
const args = argv.slice(1).filter((a) => a !== '--')
|
||||
if (args.length === 1 && (args[0] === '-h' || args[0] === '--help')) {
|
||||
ctx.console.log(
|
||||
'usage: link FILE1 FILE2\nCreate FILE2 linked to FILE1 (hard link semantics; on Hyperdrive this copies bytes unless the host enforces EOPNOTSUPP).'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (args.length !== 2) {
|
||||
ctx.console.error('usage: link FILE1 FILE2')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (args[0].startsWith('-') || args[1].startsWith('-')) {
|
||||
ctx.console.error('link: unsupported option or operand order')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
let existing = args[0]
|
||||
let newPath = args[1]
|
||||
if (ctx.vfs && typeof ctx.vfs.resolveLogical === 'function') {
|
||||
existing = ctx.vfs.resolveLogical(existing)
|
||||
newPath = ctx.vfs.resolveLogical(newPath)
|
||||
}
|
||||
if (typeof ctx.bareOsSyscall !== 'function') {
|
||||
ctx.console.error('link: bareOsSyscall unavailable')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ctx.bareOsSyscall('link', { existing, newPath })
|
||||
} catch (e) {
|
||||
ctx.console.error('link: ' + ((e && e.message) || e))
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 4,
|
||||
"ctxApiVersion": "1.36.0",
|
||||
"ctxApiVersion": "1.37.0",
|
||||
"posixProfile": {
|
||||
"id": "bare-os-posix-like",
|
||||
"version": "1.0.3"
|
||||
@@ -21,7 +21,7 @@
|
||||
"posixXsh": {
|
||||
"schema": 1,
|
||||
"note": "POSIX.1 XSH names in opsDetail with posixAlignment; not ctx.bareOsSyscall op strings.",
|
||||
"namesCsv": "open,close,read,write,lseek,pipe,dup,dup2,fcntl,poll"
|
||||
"namesCsv": "open,close,read,write,lseek,pipe,dup,dup2,fcntl,poll,select,umask"
|
||||
},
|
||||
"errnoHints": {
|
||||
"ENOENT": 2,
|
||||
|
||||
+421
-77
@@ -179,6 +179,52 @@ function bootGuestOutLine(ctx, step, text) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer **`ctx.console`** for boot-policy and boot-stage messages; when **`BARE_OS_BOOT_TRACE`**
|
||||
* is **`json`** or **`ndjson`**, also emit **`type":"bootLog"`** on stderr for structured parsers.
|
||||
* @param {'error'|'warn'} severity
|
||||
* @param {string} code Stable machine-readable code (policy field name, **`boot.allow`**, etc.).
|
||||
* @param {string} humanLine Operator-visible line (keep **`[boot-policy]`** / **`[boot]`** prefixes).
|
||||
*/
|
||||
function bootStructuredLog(ctx, severity, code, humanLine) {
|
||||
const out = ctx.console
|
||||
const line = String(humanLine)
|
||||
if (severity === 'warn') {
|
||||
if (out && typeof out.warn === 'function') out.warn(line)
|
||||
else if (globalThis.console && typeof globalThis.console.warn === 'function') {
|
||||
globalThis.console.warn(line)
|
||||
}
|
||||
} else {
|
||||
if (out && typeof out.error === 'function') out.error(line)
|
||||
else if (globalThis.console && typeof globalThis.console.error === 'function') {
|
||||
globalThis.console.error(line)
|
||||
}
|
||||
}
|
||||
if (!wantBootTrace(ctx)) return
|
||||
const errFn =
|
||||
out && typeof out.error === 'function'
|
||||
? out.error.bind(out)
|
||||
: globalThis.console && typeof globalThis.console.error === 'function'
|
||||
? globalThis.console.error.bind(globalThis.console)
|
||||
: null
|
||||
if (!errFn) return
|
||||
const msg = line.length > 600 ? line.slice(0, 600) + '\u2026' : line
|
||||
const payload = {
|
||||
type: 'bootLog',
|
||||
bootTraceSchemaVersion: 2,
|
||||
severity,
|
||||
code: String(code),
|
||||
message: msg,
|
||||
ts: Date.now(),
|
||||
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
|
||||
}
|
||||
if (isBootTraceNdjson(ctx)) {
|
||||
errFn(JSON.stringify(payload))
|
||||
} else if (isBootTraceJson(ctx)) {
|
||||
errFn(JSON.stringify({ ...payload, step: 'bootLog' }))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
*/
|
||||
@@ -567,7 +613,7 @@ async function applyBootPolicyFile(ctx) {
|
||||
? ctx.bareOsBootPolicySkipStages
|
||||
: ctx.bareOsBootPolicySkipPhases
|
||||
if (!(merge instanceof Set)) return true
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
const strictPol =
|
||||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
|
||||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
|
||||
@@ -599,7 +645,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
(Array.isArray(pol.skipBootStages) && pol.skipBootStages.length > 0) ||
|
||||
(Array.isArray(pol.denyBootStages) && pol.denyBootStages.length > 0)
|
||||
if (legacySkip && !modernSkip) {
|
||||
console.warn(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'warn',
|
||||
'deprecatedSkipPhases',
|
||||
'[boot-policy] deprecated: skipPhases/denyBootPhases in boot.policy.json — prefer skipBootStages/denyBootStages'
|
||||
)
|
||||
}
|
||||
@@ -614,7 +663,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const pol2 = JSON.parse(b4a.toString(fb))
|
||||
mergeBootPolicySkipStagesIntoSet(merge, pol2)
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'policyFallbackPaths',
|
||||
'[boot-policy] policyFallbackPaths ' +
|
||||
p2 +
|
||||
': ' +
|
||||
@@ -632,7 +684,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
if (!have || have !== need) {
|
||||
console.error('[boot-policy] requireBootBundleSha256Hex not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBootBundleSha256Hex',
|
||||
'[boot-policy] requireBootBundleSha256Hex not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -668,7 +725,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
if (typeof adv === 'number') {
|
||||
const ok = ((adv >>> 0) & need) === need
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] minKernelCapabilitiesPrimary not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'minKernelCapabilitiesPrimary',
|
||||
'[boot-policy] minKernelCapabilitiesPrimary not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -683,7 +745,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need = pol.requireSeedCaps >>> 0
|
||||
const ok = typeof seed === 'number' && ((seed >>> 0) & need) === need
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireSeedCaps not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireSeedCaps',
|
||||
'[boot-policy] requireSeedCaps not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -700,7 +767,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need2 = pol.requireKernelCapabilitiesExtendedSeedingPlatform >>> 0
|
||||
const ok = typeof adv2 === 'number' && ((adv2 >>> 0) & need2) === need2
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesExtendedSeedingPlatform not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesExtendedSeedingPlatform',
|
||||
'[boot-policy] requireKernelCapabilitiesExtendedSeedingPlatform not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -717,7 +789,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need3 = pol.requireKernelCapabilitiesRlimitsDelegatesShell >>> 0
|
||||
const ok = typeof adv3 === 'number' && ((adv3 >>> 0) & need3) === need3
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesRlimitsDelegatesShell not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesRlimitsDelegatesShell',
|
||||
'[boot-policy] requireKernelCapabilitiesRlimitsDelegatesShell not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -734,7 +811,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need4 = pol.requireKernelCapabilitiesOfflineNetExtensions >>> 0
|
||||
const ok = typeof adv4 === 'number' && ((adv4 >>> 0) & need4) === need4
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesOfflineNetExtensions not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesOfflineNetExtensions',
|
||||
'[boot-policy] requireKernelCapabilitiesOfflineNetExtensions not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -751,7 +833,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need5 = pol.requireKernelCapabilitiesHostTransportDelegates >>> 0
|
||||
const ok = typeof adv5 === 'number' && ((adv5 >>> 0) & need5) === need5
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesHostTransportDelegates not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesHostTransportDelegates',
|
||||
'[boot-policy] requireKernelCapabilitiesHostTransportDelegates not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -768,7 +855,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need6 = pol.requireKernelCapabilitiesReplicationOperatorSurface >>> 0
|
||||
const ok = typeof adv6 === 'number' && ((adv6 >>> 0) & need6) === need6
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesReplicationOperatorSurface not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesReplicationOperatorSurface',
|
||||
'[boot-policy] requireKernelCapabilitiesReplicationOperatorSurface not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -785,7 +877,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need7 = pol.requireKernelCapabilitiesPearCorestoreHrpc >>> 0
|
||||
const ok = typeof adv7 === 'number' && ((adv7 >>> 0) & need7) === need7
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesPearCorestoreHrpc not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesPearCorestoreHrpc',
|
||||
'[boot-policy] requireKernelCapabilitiesPearCorestoreHrpc not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -802,7 +899,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need8 = pol.requireKernelCapabilitiesBareRuntimeProtoMux >>> 0
|
||||
const ok = typeof adv8 === 'number' && ((adv8 >>> 0) & need8) === need8
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesBareRuntimeProtoMux not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesBareRuntimeProtoMux',
|
||||
'[boot-policy] requireKernelCapabilitiesBareRuntimeProtoMux not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -819,7 +921,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need9 = pol.requireKernelCapabilitiesBareModuleCryptoStaging >>> 0
|
||||
const ok = typeof adv9 === 'number' && ((adv9 >>> 0) & need9) === need9
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesBareModuleCryptoStaging not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesBareModuleCryptoStaging',
|
||||
'[boot-policy] requireKernelCapabilitiesBareModuleCryptoStaging not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -837,7 +944,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const ok =
|
||||
typeof adv10 === 'number' && ((adv10 >>> 0) & need10) === need10
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesPearInspectLoggerTls not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesPearInspectLoggerTls',
|
||||
'[boot-policy] requireKernelCapabilitiesPearInspectLoggerTls not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -855,7 +967,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const ok =
|
||||
typeof adv11 === 'number' && ((adv11 >>> 0) & need11) === need11
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesHypercorePackHrpcLifecycle not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesHypercorePackHrpcLifecycle',
|
||||
'[boot-policy] requireKernelCapabilitiesHypercorePackHrpcLifecycle not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -879,7 +996,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
if (ok && minS) ok = semverGte(haveS, minS)
|
||||
if (ok && maxS) ok = semverLte(haveS, maxS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearRuntimeRange not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearRuntimeRange',
|
||||
'[boot-policy] requirePearRuntimeRange not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -899,7 +1021,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareRuntimeMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareRuntimeMin',
|
||||
'[boot-policy] requireBareRuntimeMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -919,7 +1046,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearRuntimeMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearRuntimeMin',
|
||||
'[boot-policy] requirePearRuntimeMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -939,7 +1071,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireProtocolPackageMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireProtocolPackageMin',
|
||||
'[boot-policy] requireProtocolPackageMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -959,7 +1096,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBooterSemver not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBooterSemver',
|
||||
'[boot-policy] requireBooterSemver not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -979,7 +1121,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: String(ctx.bareOsCtxApiVersion || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireCtxApiMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireCtxApiMin',
|
||||
'[boot-policy] requireCtxApiMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1019,7 +1166,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const buf = await drive.get('/boot/init.js')
|
||||
const hashFn = ctx.bareOsBootFileSha256Hex
|
||||
if (typeof hashFn !== 'function') {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireInitJsSha256MissingHasher',
|
||||
'[boot-policy] requireInitJsSha256 needs ctx.bareOsBootFileSha256Hex'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1031,7 +1181,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
} else {
|
||||
const hex = hashFn(buf || new Uint8Array())
|
||||
if (hex !== need) {
|
||||
console.error('[boot-policy] requireInitJsSha256 mismatch for /boot/init.js')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireInitJsSha256Mismatch',
|
||||
'[boot-policy] requireInitJsSha256 mismatch for /boot/init.js'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1125,7 +1280,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_CRYPTO_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareCryptoMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareCryptoMin',
|
||||
'[boot-policy] requireBareCryptoMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1143,7 +1303,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_PEAR_IPC_PACKAGE_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearIpcMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearIpcMin',
|
||||
'[boot-policy] requirePearIpcMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1209,7 +1374,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_BOOT_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareBootMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareBootMin',
|
||||
'[boot-policy] requireBareBootMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1256,7 +1426,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_LOGGER_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareLoggerMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareLoggerMin',
|
||||
'[boot-policy] requireBareLoggerMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1285,7 +1460,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_TLS_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareTlsMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareTlsMin',
|
||||
'[boot-policy] requireBareTlsMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1303,7 +1483,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_PACK_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBarePackMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBarePackMin',
|
||||
'[boot-policy] requireBarePackMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1322,7 +1507,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
String(ctx.env.BARE_OS_BARE_ADDON_POLICY_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareAddonPolicyMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareAddonPolicyMin',
|
||||
'[boot-policy] requireBareAddonPolicyMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1409,7 +1599,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const haveSch = Number.parseInt(raw, 10)
|
||||
const ok = Number.isFinite(haveSch) && haveSch >= needSch
|
||||
if (!ok) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootStagesRequireLifecycleMinSchema',
|
||||
'[boot-policy] bootStagesRequireLifecycleMinSchema not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1445,7 +1638,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
: 0
|
||||
if (sch < needSch) throw new Error('proc_index schema too old')
|
||||
} catch {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootStagesRequireProcIndexMinSchema',
|
||||
'[boot-policy] bootStagesRequireProcIndexMinSchema not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1474,7 +1670,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.b4a.from(b).length === 0)
|
||||
if (empty) throw new Error('empty or missing')
|
||||
} catch {
|
||||
console.error('[boot-policy] requireProcNodes not satisfied: ' + p)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireProcNodes',
|
||||
'[boot-policy] requireProcNodes not satisfied: ' + p
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1486,7 +1687,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootPolicyParse',
|
||||
'[boot-policy] boot.policy.json: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
@@ -1733,7 +1937,7 @@ async function loadBootManifest(ctx) {
|
||||
const v = ctx.env && ctx.env.BARE_OS_BOOT_MANIFEST
|
||||
if (v !== '1' && v !== 'true') return null
|
||||
if (bootManifestMemo !== undefined) return bootManifestMemo
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
const buf = await drive.get('/etc/bare-os/boot.manifest.json')
|
||||
if (!buf) {
|
||||
@@ -1752,14 +1956,20 @@ async function loadBootManifest(ctx) {
|
||||
: ''
|
||||
const verifyFn = ctx.bareOsVerifyBootManifestSignature
|
||||
if (typeof verifyFn !== 'function' || !pub) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSignMissingVerifier',
|
||||
'[boot] signed manifest requires ctx.bareOsVerifyBootManifestSignature and BARE_OS_BOOT_MANIFEST_PUBKEY_HEX'
|
||||
)
|
||||
bootManifestMemo = null
|
||||
return null
|
||||
}
|
||||
if (!verifyFn(buf, sigBuf, pub)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSignFailed',
|
||||
'[boot] boot.manifest.json Ed25519 signature verification failed'
|
||||
)
|
||||
bootManifestMemo = null
|
||||
@@ -1769,7 +1979,10 @@ async function loadBootManifest(ctx) {
|
||||
bootManifestMemo = JSON.parse(b4a.toString(buf))
|
||||
return bootManifestMemo
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestParse',
|
||||
'[boot] boot.manifest.json: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
bootManifestMemo = null
|
||||
@@ -1789,7 +2002,10 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
const exp = /** @type {Record<string, string>} */ (sha)[drivePath]
|
||||
if (exp == null || exp === '') return true
|
||||
if (typeof ctx.bareOsBootFileSha256Hex !== 'function') {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestMissingHasher',
|
||||
'[boot] manifest present but bareOsBootFileSha256Hex missing'
|
||||
)
|
||||
return false
|
||||
@@ -1798,7 +2014,12 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
typeof content === 'string' ? ctx.b4a.from(content, 'utf8') : content
|
||||
const hex = ctx.bareOsBootFileSha256Hex(buf)
|
||||
if (hex !== String(exp).trim().toLowerCase()) {
|
||||
ctx.console.error('[boot] manifest sha256 mismatch: ' + drivePath)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSha256Mismatch',
|
||||
'[boot] manifest sha256 mismatch: ' + drivePath
|
||||
)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -1810,7 +2031,7 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
* @returns {Promise<boolean>} false if BARE_OS_BOOT_STRICT and a line threw
|
||||
*/
|
||||
async function runRcLines(ctx, text) {
|
||||
const { execLine, console } = ctx
|
||||
const { execLine } = ctx
|
||||
const strict = bootStrict(ctx)
|
||||
const allow = await loadBootAllowSet(ctx)
|
||||
const dry = bootDryRun(ctx)
|
||||
@@ -1818,7 +2039,12 @@ async function runRcLines(ctx, text) {
|
||||
const t = line.trim()
|
||||
if (!t || t.startsWith('#')) continue
|
||||
if (allow && !bootLineAllowed(t, allow)) {
|
||||
console.error('[boot] command not in boot.allow: ' + t.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootAllowDenied',
|
||||
'[boot] command not in boot.allow: ' + t.slice(0, 120)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1827,13 +2053,23 @@ async function runRcLines(ctx, text) {
|
||||
continue
|
||||
}
|
||||
if (dry) {
|
||||
console.error('[boot-dry-run] skip execLine: ' + t.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunExecLine',
|
||||
'[boot-dry-run] skip execLine: ' + t.slice(0, 120)
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await execLine(t)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'execLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1903,7 +2139,10 @@ async function runProfileRc(ctx, profileName) {
|
||||
if (!profileName) return true
|
||||
const safe = profileName.replace(/[^a-zA-Z0-9._-]/g, '')
|
||||
if (safe !== profileName) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootProfileInvalidChars',
|
||||
'[boot] profile name contains unsupported characters; skipping rc.profile'
|
||||
)
|
||||
return true
|
||||
@@ -1922,7 +2161,7 @@ async function runProfileRc(ctx, profileName) {
|
||||
*/
|
||||
async function runOnboot(ctx) {
|
||||
if (!ctx.bareOsSkipRepl) return true
|
||||
const { execLine, console, drive, b4a, env } = ctx
|
||||
const { execLine, drive, b4a, env } = ctx
|
||||
const strict = bootStrict(ctx)
|
||||
const allow = await loadBootAllowSet(ctx)
|
||||
/** @type {string[]} */
|
||||
@@ -1945,13 +2184,21 @@ async function runOnboot(ctx) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('onboot: ' + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootRead',
|
||||
'onboot: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
const dry = bootDryRun(ctx)
|
||||
for (const line of lines) {
|
||||
if (allow && !bootLineAllowed(line, allow)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootBootAllowDenied',
|
||||
'[boot] onboot command not in boot.allow: ' + line.slice(0, 120)
|
||||
)
|
||||
if (strict) {
|
||||
@@ -1962,13 +2209,23 @@ async function runOnboot(ctx) {
|
||||
continue
|
||||
}
|
||||
if (dry) {
|
||||
console.error('[boot-dry-run] skip onboot: ' + line.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunOnboot',
|
||||
'[boot-dry-run] skip onboot: ' + line.slice(0, 120)
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await execLine(line)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootExecLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1986,7 +2243,7 @@ async function runOnboot(ctx) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runRcFileAt(ctx, drivePath, label) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
const buf = await drive.get(drivePath)
|
||||
if (!buf) return true
|
||||
@@ -2001,7 +2258,12 @@ async function runRcFileAt(ctx, drivePath, label) {
|
||||
}
|
||||
return await runRcLines(ctx, text)
|
||||
} catch (e) {
|
||||
console.error(`${label}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rcFileRead',
|
||||
`${label}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -2024,7 +2286,7 @@ function isBareOsRcSnippetFile(name) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runBareOsKernelDir(ctx) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
/** @type {string[]} */
|
||||
const names = []
|
||||
@@ -2072,17 +2334,32 @@ async function runBareOsKernelDir(ctx) {
|
||||
if (!buf) continue
|
||||
const txt = b4a.toString(buf)
|
||||
if (!kernelSnippetEnvGuardsOk(ctx, txt)) {
|
||||
console.error(`[boot] kernel.d/${name}: ConditionEnvironment / AssertEnvironment not met; skip`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.envGuardSkip',
|
||||
`[boot] kernel.d/${name}: ConditionEnvironment / AssertEnvironment not met; skip`
|
||||
)
|
||||
continue
|
||||
}
|
||||
const cont = await runRcLines(ctx, txt)
|
||||
if (!cont) return false
|
||||
} catch (e) {
|
||||
console.error(`kernel.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.exec',
|
||||
`kernel.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.outer',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -2181,7 +2458,7 @@ function kernelExtDependencyDepth(entries) {
|
||||
async function runKernelExtDropins(ctx, opts = {}) {
|
||||
const incremental = opts.incremental === true
|
||||
const ranScripts = opts.ranScripts
|
||||
const { drive, console } = ctx
|
||||
const { drive } = ctx
|
||||
const run = ctx.bareOsRunImageScript
|
||||
if (typeof run !== 'function') return true
|
||||
if (!ctx.bareOsLoadedKernelExtScripts) {
|
||||
@@ -2232,7 +2509,12 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
? String(pol.id).trim()
|
||||
: name.replace(/\.json$/i, '')
|
||||
if (deny.has(extId)) {
|
||||
console.error(`[kernel.ext.d] denied by policy id: ${extId}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.denyId',
|
||||
`[kernel.ext.d] denied by policy id: ${extId}`
|
||||
)
|
||||
continue
|
||||
}
|
||||
const scripts = pol.scripts
|
||||
@@ -2268,7 +2550,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
? ctx.bareOsCtxApiVersion.trim()
|
||||
: String(ctx.bareOsCtxApiVersion || '').trim()
|
||||
if (!haveS || !semverGte(haveS, minExtCtx)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.minCtxApiVersion',
|
||||
`[kernel.ext.d] ${name}: minCtxApiVersion ${minExtCtx} not satisfied (have ${haveS || 'none'})`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2288,7 +2573,12 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
signaturePointer: sig || undefined
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(`kernel.ext.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.dropinParse',
|
||||
`kernel.ext.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
const idToCollected = new Map(collected.map((e) => [e.extId, e]))
|
||||
@@ -2309,7 +2599,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
for (const e of collected) {
|
||||
for (const c of e.conflictsWith) {
|
||||
if (idSet.has(c)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.conflict',
|
||||
`[kernel.ext.d] conflict: extension "${e.extId}" conflictsWith "${c}"`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2319,7 +2612,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
if (maxDepthCap > 0) {
|
||||
const d = kernelExtDependencyDepth(collected)
|
||||
if (d > maxDepthCap) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.maxDepth',
|
||||
`[kernel.ext.d] maxKernelExtensionDepth exceeded (${d} > ${maxDepthCap})`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2329,7 +2625,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
/** @type {typeof collected} */
|
||||
let ordered
|
||||
if (!topo.ok) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.cycle',
|
||||
'[kernel.ext.d] dependency cycle in extension drop-ins; ext ids: ' +
|
||||
topo.cycleExtIds.join(', ')
|
||||
)
|
||||
@@ -2402,14 +2701,24 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
for (const sp of ent.scripts) {
|
||||
const imgPath = String(sp).trim()
|
||||
if (!imgPath.startsWith('/lib/bare-os/extensions/')) {
|
||||
console.error(`[kernel.ext.d] rejected script path: ${imgPath}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.rejectedPath',
|
||||
`[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}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunKernelExt',
|
||||
`[boot-dry-run] skip kernel.ext.d script: ${imgPath}`
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
@@ -2426,7 +2735,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.scriptThrown',
|
||||
`[kernel.ext.d] ${ent.file}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
@@ -2441,7 +2753,7 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runBareOsRcDir(ctx) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
const skip = parseRcDSkipPatterns(ctx)
|
||||
try {
|
||||
/** @type {string[]} */
|
||||
@@ -2491,11 +2803,21 @@ async function runBareOsRcDir(ctx) {
|
||||
const cont = await runRcLines(ctx, b4a.toString(buf))
|
||||
if (!cont) return false
|
||||
} catch (e) {
|
||||
console.error(`rc.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rc.d.exec',
|
||||
`rc.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rc.d.outer',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -2813,7 +3135,10 @@ function mergeBootCapabilityContract(ctx) {
|
||||
const ap = /** @type {{ primary?: number }} */ (adv).primary
|
||||
const sp = /** @type {{ primary?: number }} */ (seed).primary
|
||||
if (typeof ap === 'number' && typeof sp === 'number' && ap !== sp) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCapabilityPrimaryMismatch',
|
||||
'[boot] strict: primary kernel capability word mismatch (advertised vs seed)'
|
||||
)
|
||||
if (typeof ctx.requestBooterExit === 'function') ctx.requestBooterExit(1)
|
||||
@@ -2823,8 +3148,11 @@ function mergeBootCapabilityContract(ctx) {
|
||||
const dbg =
|
||||
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === '1' ||
|
||||
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === 'true'
|
||||
if (dbg && ctx.console) {
|
||||
ctx.console.error(
|
||||
if (dbg) {
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCapabilityContractDebug',
|
||||
'[boot] capability contract debug: advertised=' +
|
||||
(adv ? 'yes' : 'no') +
|
||||
' seed=' +
|
||||
@@ -2846,7 +3174,10 @@ function enforceBootCtxApiMin(ctx) {
|
||||
? ctx.bareOsCtxApiVersion.trim()
|
||||
: ''
|
||||
if (!have || !semverGte(have, need)) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCtxApiMin',
|
||||
'[boot] BARE_OS_REQUIRE_CTX_API_MIN not satisfied (need ' +
|
||||
need +
|
||||
', have ' +
|
||||
@@ -2868,7 +3199,7 @@ function enforceBootCtxApiMin(ctx) {
|
||||
|
||||
async function start(ctx) {
|
||||
const bootT0 = Date.now()
|
||||
const { readLine, execLine, console } = ctx
|
||||
const { readLine, execLine } = ctx
|
||||
/** @type {string[]} */
|
||||
const stageLog = []
|
||||
const bootPolicySkipSet = new Set()
|
||||
@@ -3040,9 +3371,17 @@ async function start(ctx) {
|
||||
if (Number.isFinite(budget) && budget > 0) {
|
||||
const wall = Date.now() - bootT0
|
||||
if (wall > budget) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootBudgetColdExceeded',
|
||||
`[boot] cold wall ${wall}ms exceeds BARE_OS_BOOT_BUDGET_MS_COLD=${budget}ms`
|
||||
)
|
||||
if (ctx.env) {
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_EXCEEDED = '1'
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_WALL_MS = String(wall)
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_LIMIT_MS = String(budget)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3055,7 +3394,12 @@ async function start(ctx) {
|
||||
try {
|
||||
status = await execLine(t)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'replExecLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
if (status === 'exit') break
|
||||
}
|
||||
|
||||
+202
-202
@@ -7,18 +7,18 @@
|
||||
"b4a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"keys": [
|
||||
"hypercoreIdEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/safetyCatch.js",
|
||||
"keys": [
|
||||
"safetyCatch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"keys": [
|
||||
"hypercoreIdEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/compactEncoding.js",
|
||||
"keys": [
|
||||
@@ -38,9 +38,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePath.js",
|
||||
"path": "/lib/bare/bundles/bareEncoding.js",
|
||||
"keys": [
|
||||
"barePath"
|
||||
"bareEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -50,9 +50,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareEncoding.js",
|
||||
"path": "/lib/bare/bundles/barePath.js",
|
||||
"keys": [
|
||||
"bareEncoding"
|
||||
"barePath"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -68,9 +68,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAnsiEscapes.js",
|
||||
"path": "/lib/bare/bundles/bareAddonResolve.js",
|
||||
"keys": [
|
||||
"bareAnsiEscapes"
|
||||
"bareAddonResolve"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -79,24 +79,18 @@
|
||||
"bareReadline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAnsiEscapes.js",
|
||||
"keys": [
|
||||
"bareAnsiEscapes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareCrypto.js",
|
||||
"keys": [
|
||||
"bareCrypto"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAddonResolve.js",
|
||||
"keys": [
|
||||
"bareAddonResolve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAtomics.js",
|
||||
"keys": [
|
||||
"bareAtomics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAsyncHooks.js",
|
||||
"keys": [
|
||||
@@ -109,6 +103,18 @@
|
||||
"bareAppKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAtomics.js",
|
||||
"keys": [
|
||||
"bareAtomics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAssert.js",
|
||||
"keys": [
|
||||
@@ -121,30 +127,24 @@
|
||||
"bareApk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBmp.js",
|
||||
"keys": [
|
||||
"bareBmp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"keys": [
|
||||
"bareBundle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundleCompile.js",
|
||||
"keys": [
|
||||
"bareBundleCompile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBuffer.js",
|
||||
"keys": [
|
||||
"bareBuffer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundleEvaluate.js",
|
||||
"keys": [
|
||||
@@ -152,9 +152,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"path": "/lib/bare/bundles/bareBuffer.js",
|
||||
"keys": [
|
||||
"bareBundle"
|
||||
"bareBuffer"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -169,24 +169,30 @@
|
||||
"bareBoot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDaemon.js",
|
||||
"keys": [
|
||||
"bareDaemon"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundleId.js",
|
||||
"keys": [
|
||||
"bareBundleId"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareConsole.js",
|
||||
"keys": [
|
||||
"bareConsole"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDebugLog.js",
|
||||
"keys": [
|
||||
"bareDebugLog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareConsole.js",
|
||||
"keys": [
|
||||
"bareConsole"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareChannel.js",
|
||||
"keys": [
|
||||
@@ -199,12 +205,6 @@
|
||||
"bareDelta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDaemon.js",
|
||||
"keys": [
|
||||
"bareDaemon"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDiagnosticsChannel.js",
|
||||
"keys": [
|
||||
@@ -218,15 +218,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareEnv.js",
|
||||
"path": "/lib/bare/bundles/bareCov.js",
|
||||
"keys": [
|
||||
"bareEnv"
|
||||
"bareCov"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareExif.js",
|
||||
"path": "/lib/bare/bundles/bareEnv.js",
|
||||
"keys": [
|
||||
"bareExif"
|
||||
"bareEnv"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -236,9 +236,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareCov.js",
|
||||
"path": "/lib/bare/bundles/bareExif.js",
|
||||
"keys": [
|
||||
"bareCov"
|
||||
"bareExif"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -253,12 +253,6 @@
|
||||
"bareFfmpegEncodings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"keys": [
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFormat.js",
|
||||
"keys": [
|
||||
@@ -272,9 +266,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHrtime.js",
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"keys": [
|
||||
"bareHrtime"
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFileLogger.js",
|
||||
"keys": [
|
||||
"bareFileLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -290,15 +290,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFileLogger.js",
|
||||
"path": "/lib/bare/bundles/bareHrtime.js",
|
||||
"keys": [
|
||||
"bareFileLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
"bareHrtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -307,6 +301,12 @@
|
||||
"bareHttpParser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareIco.js",
|
||||
"keys": [
|
||||
@@ -355,12 +355,6 @@
|
||||
"bareIpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareInspector"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLief.js",
|
||||
"keys": [
|
||||
@@ -368,9 +362,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareLogger"
|
||||
"bareInspector"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -380,15 +374,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModule.js",
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"keys": [
|
||||
"bareModule"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareMake.js",
|
||||
"keys": [
|
||||
"bareMake"
|
||||
"bareLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -398,9 +386,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNdk.js",
|
||||
"path": "/lib/bare/bundles/bareMake.js",
|
||||
"keys": [
|
||||
"bareNdk"
|
||||
"bareMake"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModule.js",
|
||||
"keys": [
|
||||
"bareModule"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -416,9 +410,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareMedia.js",
|
||||
"path": "/lib/bare/bundles/bareNdk.js",
|
||||
"keys": [
|
||||
"bareMedia"
|
||||
"bareNdk"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -434,9 +428,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareOs.js",
|
||||
"path": "/lib/bare/bundles/bareMedia.js",
|
||||
"keys": [
|
||||
"bareOs"
|
||||
"bareMedia"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -445,6 +439,12 @@
|
||||
"bareOpen"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareOs.js",
|
||||
"keys": [
|
||||
"bareOs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNet.js",
|
||||
"keys": [
|
||||
@@ -469,30 +469,12 @@
|
||||
"barePackDrive"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"keys": [
|
||||
"barePipe"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePng.js",
|
||||
"keys": [
|
||||
"barePng"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"keys": [
|
||||
"bareNodeRuntime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"keys": [
|
||||
"barePrebuild"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDev.js",
|
||||
"keys": [
|
||||
@@ -500,15 +482,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePunycode.js",
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"keys": [
|
||||
"barePunycode"
|
||||
"barePipe"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareProcess.js",
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"keys": [
|
||||
"bareProcess"
|
||||
"barePrebuild"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"keys": [
|
||||
"bareNodeRuntime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePunycode.js",
|
||||
"keys": [
|
||||
"barePunycode"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -517,48 +511,54 @@
|
||||
"bareQuerystring"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRealm.js",
|
||||
"keys": [
|
||||
"bareRealm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRuntime.js",
|
||||
"keys": [
|
||||
"bareRuntime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareProcess.js",
|
||||
"keys": [
|
||||
"bareProcess"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSdl.js",
|
||||
"keys": [
|
||||
"bareSdl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"keys": [
|
||||
"bareRun"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSemver.js",
|
||||
"keys": [
|
||||
"bareSemver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSidecar.js",
|
||||
"keys": [
|
||||
"bareSidecar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRepl.js",
|
||||
"keys": [
|
||||
@@ -566,9 +566,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePromClient.js",
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"keys": [
|
||||
"barePromClient"
|
||||
"bareRun"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -578,9 +578,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSidecar.js",
|
||||
"path": "/lib/bare/bundles/barePromClient.js",
|
||||
"keys": [
|
||||
"bareSidecar"
|
||||
"barePromClient"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -595,24 +595,18 @@
|
||||
"bareStream"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStorage.js",
|
||||
"keys": [
|
||||
"bareStorage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStdio.js",
|
||||
"keys": [
|
||||
"bareStdio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStorage.js",
|
||||
"keys": [
|
||||
"bareStorage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSvg.js",
|
||||
"keys": [
|
||||
@@ -620,21 +614,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTiff.js",
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareTiff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -644,9 +626,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTpl.js",
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareTpl"
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTiff.js",
|
||||
"keys": [
|
||||
"bareTiff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTimers.js",
|
||||
"keys": [
|
||||
"bareTimers"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -656,15 +656,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"path": "/lib/bare/bundles/bareTpl.js",
|
||||
"keys": [
|
||||
"bareThread"
|
||||
"bareTpl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTimers.js",
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"keys": [
|
||||
"bareTimers"
|
||||
"bareThread"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -679,12 +679,6 @@
|
||||
"bareTls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTty.js",
|
||||
"keys": [
|
||||
"bareTty"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUnpack.js",
|
||||
"keys": [
|
||||
@@ -692,9 +686,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareV8.js",
|
||||
"path": "/lib/bare/bundles/bareTty.js",
|
||||
"keys": [
|
||||
"bareV8"
|
||||
"bareTty"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -704,15 +698,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWalkHandles.js",
|
||||
"path": "/lib/bare/bundles/bareV8.js",
|
||||
"keys": [
|
||||
"bareWalkHandles"
|
||||
"bareV8"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUnionBundle.js",
|
||||
"path": "/lib/bare/bundles/bareWalkHandles.js",
|
||||
"keys": [
|
||||
"bareUnionBundle"
|
||||
"bareWalkHandles"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -722,15 +716,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"path": "/lib/bare/bundles/bareUnionBundle.js",
|
||||
"keys": [
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUtils.js",
|
||||
"keys": [
|
||||
"bareUtils"
|
||||
"bareUnionBundle"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -740,9 +728,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWhich.js",
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"keys": [
|
||||
"bareWhich"
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -752,15 +740,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWinUi.js",
|
||||
"path": "/lib/bare/bundles/bareWhich.js",
|
||||
"keys": [
|
||||
"bareWinUi"
|
||||
"bareWhich"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"path": "/lib/bare/bundles/bareWinUi.js",
|
||||
"keys": [
|
||||
"bareXdiff"
|
||||
"bareWinUi"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -770,9 +758,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"keys": [
|
||||
"bareWs"
|
||||
"bareXdiff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUtils.js",
|
||||
"keys": [
|
||||
"bareUtils"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -781,6 +775,12 @@
|
||||
"bareZlib"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWorker.js",
|
||||
"keys": [
|
||||
"bareWorker"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZmq.js",
|
||||
"keys": [
|
||||
@@ -788,9 +788,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWorker.js",
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"keys": [
|
||||
"bareWorker"
|
||||
"bareWs"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1595,8 +1595,8 @@
|
||||
],
|
||||
"bundleProvenance": {
|
||||
"schemaVersion": 1,
|
||||
"generatedAt": "2026-04-05T03:03:09.352Z",
|
||||
"gitCommit": "985eadfda39fa8a847791ff5c7f8f40d4434d9ac",
|
||||
"generatedAt": "2026-04-05T03:18:48.742Z",
|
||||
"gitCommit": "48f973634aaf87862ed811b0dc66683bcde0898a",
|
||||
"nodeVersion": "v22.22.0",
|
||||
"bundleTier": "all",
|
||||
"normativeManifest": "packages/bare-os-booter/lib/bare-module-manifest.json",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1775358188597,
|
||||
"atMs": 1775359127851,
|
||||
"commands": [
|
||||
"arch",
|
||||
"awk",
|
||||
@@ -65,6 +65,7 @@
|
||||
"kernel-preflight",
|
||||
"kernel-triage",
|
||||
"kill",
|
||||
"link",
|
||||
"ln",
|
||||
"logger",
|
||||
"login",
|
||||
|
||||
+421
-77
@@ -149,6 +149,52 @@ function bootGuestOutLine(ctx, step, text) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer **`ctx.console`** for boot-policy and boot-stage messages; when **`BARE_OS_BOOT_TRACE`**
|
||||
* is **`json`** or **`ndjson`**, also emit **`type":"bootLog"`** on stderr for structured parsers.
|
||||
* @param {'error'|'warn'} severity
|
||||
* @param {string} code Stable machine-readable code (policy field name, **`boot.allow`**, etc.).
|
||||
* @param {string} humanLine Operator-visible line (keep **`[boot-policy]`** / **`[boot]`** prefixes).
|
||||
*/
|
||||
function bootStructuredLog(ctx, severity, code, humanLine) {
|
||||
const out = ctx.console
|
||||
const line = String(humanLine)
|
||||
if (severity === 'warn') {
|
||||
if (out && typeof out.warn === 'function') out.warn(line)
|
||||
else if (globalThis.console && typeof globalThis.console.warn === 'function') {
|
||||
globalThis.console.warn(line)
|
||||
}
|
||||
} else {
|
||||
if (out && typeof out.error === 'function') out.error(line)
|
||||
else if (globalThis.console && typeof globalThis.console.error === 'function') {
|
||||
globalThis.console.error(line)
|
||||
}
|
||||
}
|
||||
if (!wantBootTrace(ctx)) return
|
||||
const errFn =
|
||||
out && typeof out.error === 'function'
|
||||
? out.error.bind(out)
|
||||
: globalThis.console && typeof globalThis.console.error === 'function'
|
||||
? globalThis.console.error.bind(globalThis.console)
|
||||
: null
|
||||
if (!errFn) return
|
||||
const msg = line.length > 600 ? line.slice(0, 600) + '\u2026' : line
|
||||
const payload = {
|
||||
type: 'bootLog',
|
||||
bootTraceSchemaVersion: 2,
|
||||
severity,
|
||||
code: String(code),
|
||||
message: msg,
|
||||
ts: Date.now(),
|
||||
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
|
||||
}
|
||||
if (isBootTraceNdjson(ctx)) {
|
||||
errFn(JSON.stringify(payload))
|
||||
} else if (isBootTraceJson(ctx)) {
|
||||
errFn(JSON.stringify({ ...payload, step: 'bootLog' }))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
*/
|
||||
@@ -537,7 +583,7 @@ async function applyBootPolicyFile(ctx) {
|
||||
? ctx.bareOsBootPolicySkipStages
|
||||
: ctx.bareOsBootPolicySkipPhases
|
||||
if (!(merge instanceof Set)) return true
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
const strictPol =
|
||||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
|
||||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
|
||||
@@ -569,7 +615,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
(Array.isArray(pol.skipBootStages) && pol.skipBootStages.length > 0) ||
|
||||
(Array.isArray(pol.denyBootStages) && pol.denyBootStages.length > 0)
|
||||
if (legacySkip && !modernSkip) {
|
||||
console.warn(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'warn',
|
||||
'deprecatedSkipPhases',
|
||||
'[boot-policy] deprecated: skipPhases/denyBootPhases in boot.policy.json — prefer skipBootStages/denyBootStages'
|
||||
)
|
||||
}
|
||||
@@ -584,7 +633,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const pol2 = JSON.parse(b4a.toString(fb))
|
||||
mergeBootPolicySkipStagesIntoSet(merge, pol2)
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'policyFallbackPaths',
|
||||
'[boot-policy] policyFallbackPaths ' +
|
||||
p2 +
|
||||
': ' +
|
||||
@@ -602,7 +654,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
if (!have || have !== need) {
|
||||
console.error('[boot-policy] requireBootBundleSha256Hex not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBootBundleSha256Hex',
|
||||
'[boot-policy] requireBootBundleSha256Hex not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -638,7 +695,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
if (typeof adv === 'number') {
|
||||
const ok = ((adv >>> 0) & need) === need
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] minKernelCapabilitiesPrimary not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'minKernelCapabilitiesPrimary',
|
||||
'[boot-policy] minKernelCapabilitiesPrimary not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -653,7 +715,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need = pol.requireSeedCaps >>> 0
|
||||
const ok = typeof seed === 'number' && ((seed >>> 0) & need) === need
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireSeedCaps not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireSeedCaps',
|
||||
'[boot-policy] requireSeedCaps not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -670,7 +737,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need2 = pol.requireKernelCapabilitiesExtendedSeedingPlatform >>> 0
|
||||
const ok = typeof adv2 === 'number' && ((adv2 >>> 0) & need2) === need2
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesExtendedSeedingPlatform not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesExtendedSeedingPlatform',
|
||||
'[boot-policy] requireKernelCapabilitiesExtendedSeedingPlatform not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -687,7 +759,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need3 = pol.requireKernelCapabilitiesRlimitsDelegatesShell >>> 0
|
||||
const ok = typeof adv3 === 'number' && ((adv3 >>> 0) & need3) === need3
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesRlimitsDelegatesShell not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesRlimitsDelegatesShell',
|
||||
'[boot-policy] requireKernelCapabilitiesRlimitsDelegatesShell not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -704,7 +781,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need4 = pol.requireKernelCapabilitiesOfflineNetExtensions >>> 0
|
||||
const ok = typeof adv4 === 'number' && ((adv4 >>> 0) & need4) === need4
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesOfflineNetExtensions not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesOfflineNetExtensions',
|
||||
'[boot-policy] requireKernelCapabilitiesOfflineNetExtensions not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -721,7 +803,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need5 = pol.requireKernelCapabilitiesHostTransportDelegates >>> 0
|
||||
const ok = typeof adv5 === 'number' && ((adv5 >>> 0) & need5) === need5
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesHostTransportDelegates not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesHostTransportDelegates',
|
||||
'[boot-policy] requireKernelCapabilitiesHostTransportDelegates not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -738,7 +825,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need6 = pol.requireKernelCapabilitiesReplicationOperatorSurface >>> 0
|
||||
const ok = typeof adv6 === 'number' && ((adv6 >>> 0) & need6) === need6
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesReplicationOperatorSurface not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesReplicationOperatorSurface',
|
||||
'[boot-policy] requireKernelCapabilitiesReplicationOperatorSurface not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -755,7 +847,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need7 = pol.requireKernelCapabilitiesPearCorestoreHrpc >>> 0
|
||||
const ok = typeof adv7 === 'number' && ((adv7 >>> 0) & need7) === need7
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesPearCorestoreHrpc not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesPearCorestoreHrpc',
|
||||
'[boot-policy] requireKernelCapabilitiesPearCorestoreHrpc not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -772,7 +869,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need8 = pol.requireKernelCapabilitiesBareRuntimeProtoMux >>> 0
|
||||
const ok = typeof adv8 === 'number' && ((adv8 >>> 0) & need8) === need8
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesBareRuntimeProtoMux not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesBareRuntimeProtoMux',
|
||||
'[boot-policy] requireKernelCapabilitiesBareRuntimeProtoMux not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -789,7 +891,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const need9 = pol.requireKernelCapabilitiesBareModuleCryptoStaging >>> 0
|
||||
const ok = typeof adv9 === 'number' && ((adv9 >>> 0) & need9) === need9
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesBareModuleCryptoStaging not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesBareModuleCryptoStaging',
|
||||
'[boot-policy] requireKernelCapabilitiesBareModuleCryptoStaging not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -807,7 +914,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const ok =
|
||||
typeof adv10 === 'number' && ((adv10 >>> 0) & need10) === need10
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesPearInspectLoggerTls not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesPearInspectLoggerTls',
|
||||
'[boot-policy] requireKernelCapabilitiesPearInspectLoggerTls not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -825,7 +937,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
const ok =
|
||||
typeof adv11 === 'number' && ((adv11 >>> 0) & need11) === need11
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireKernelCapabilitiesHypercorePackHrpcLifecycle not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireKernelCapabilitiesHypercorePackHrpcLifecycle',
|
||||
'[boot-policy] requireKernelCapabilitiesHypercorePackHrpcLifecycle not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -849,7 +966,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
if (ok && minS) ok = semverGte(haveS, minS)
|
||||
if (ok && maxS) ok = semverLte(haveS, maxS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearRuntimeRange not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearRuntimeRange',
|
||||
'[boot-policy] requirePearRuntimeRange not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -869,7 +991,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareRuntimeMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareRuntimeMin',
|
||||
'[boot-policy] requireBareRuntimeMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -889,7 +1016,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearRuntimeMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearRuntimeMin',
|
||||
'[boot-policy] requirePearRuntimeMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -909,7 +1041,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireProtocolPackageMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireProtocolPackageMin',
|
||||
'[boot-policy] requireProtocolPackageMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -929,7 +1066,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: ''
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBooterSemver not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBooterSemver',
|
||||
'[boot-policy] requireBooterSemver not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -949,7 +1091,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
: String(ctx.bareOsCtxApiVersion || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireCtxApiMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireCtxApiMin',
|
||||
'[boot-policy] requireCtxApiMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -989,7 +1136,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const buf = await drive.get('/boot/init.js')
|
||||
const hashFn = ctx.bareOsBootFileSha256Hex
|
||||
if (typeof hashFn !== 'function') {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireInitJsSha256MissingHasher',
|
||||
'[boot-policy] requireInitJsSha256 needs ctx.bareOsBootFileSha256Hex'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1001,7 +1151,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
} else {
|
||||
const hex = hashFn(buf || new Uint8Array())
|
||||
if (hex !== need) {
|
||||
console.error('[boot-policy] requireInitJsSha256 mismatch for /boot/init.js')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireInitJsSha256Mismatch',
|
||||
'[boot-policy] requireInitJsSha256 mismatch for /boot/init.js'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1095,7 +1250,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_CRYPTO_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareCryptoMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareCryptoMin',
|
||||
'[boot-policy] requireBareCryptoMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1113,7 +1273,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_PEAR_IPC_PACKAGE_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requirePearIpcMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requirePearIpcMin',
|
||||
'[boot-policy] requirePearIpcMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1179,7 +1344,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_BOOT_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareBootMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareBootMin',
|
||||
'[boot-policy] requireBareBootMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1226,7 +1396,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_LOGGER_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareLoggerMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareLoggerMin',
|
||||
'[boot-policy] requireBareLoggerMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1255,7 +1430,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_TLS_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareTlsMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareTlsMin',
|
||||
'[boot-policy] requireBareTlsMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1273,7 +1453,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.env && String(ctx.env.BARE_OS_BARE_PACK_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBarePackMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBarePackMin',
|
||||
'[boot-policy] requireBarePackMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1292,7 +1477,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
String(ctx.env.BARE_OS_BARE_ADDON_POLICY_VERSION || '').trim()
|
||||
const ok = haveS && semverGte(haveS, needS)
|
||||
if (!ok) {
|
||||
console.error('[boot-policy] requireBareAddonPolicyMin not satisfied')
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireBareAddonPolicyMin',
|
||||
'[boot-policy] requireBareAddonPolicyMin not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1379,7 +1569,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
const haveSch = Number.parseInt(raw, 10)
|
||||
const ok = Number.isFinite(haveSch) && haveSch >= needSch
|
||||
if (!ok) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootStagesRequireLifecycleMinSchema',
|
||||
'[boot-policy] bootStagesRequireLifecycleMinSchema not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1415,7 +1608,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
: 0
|
||||
if (sch < needSch) throw new Error('proc_index schema too old')
|
||||
} catch {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootStagesRequireProcIndexMinSchema',
|
||||
'[boot-policy] bootStagesRequireProcIndexMinSchema not satisfied'
|
||||
)
|
||||
if (strictPol) {
|
||||
@@ -1444,7 +1640,12 @@ async function applyBootPolicyFile(ctx) {
|
||||
ctx.b4a.from(b).length === 0)
|
||||
if (empty) throw new Error('empty or missing')
|
||||
} catch {
|
||||
console.error('[boot-policy] requireProcNodes not satisfied: ' + p)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'requireProcNodes',
|
||||
'[boot-policy] requireProcNodes not satisfied: ' + p
|
||||
)
|
||||
if (strictPol) {
|
||||
if (typeof ctx.requestBooterExit === 'function') {
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1456,7 +1657,10 @@ async function applyBootPolicyFile(ctx) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootPolicyParse',
|
||||
'[boot-policy] boot.policy.json: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
@@ -1703,7 +1907,7 @@ async function loadBootManifest(ctx) {
|
||||
const v = ctx.env && ctx.env.BARE_OS_BOOT_MANIFEST
|
||||
if (v !== '1' && v !== 'true') return null
|
||||
if (bootManifestMemo !== undefined) return bootManifestMemo
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
const buf = await drive.get('/etc/bare-os/boot.manifest.json')
|
||||
if (!buf) {
|
||||
@@ -1722,14 +1926,20 @@ async function loadBootManifest(ctx) {
|
||||
: ''
|
||||
const verifyFn = ctx.bareOsVerifyBootManifestSignature
|
||||
if (typeof verifyFn !== 'function' || !pub) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSignMissingVerifier',
|
||||
'[boot] signed manifest requires ctx.bareOsVerifyBootManifestSignature and BARE_OS_BOOT_MANIFEST_PUBKEY_HEX'
|
||||
)
|
||||
bootManifestMemo = null
|
||||
return null
|
||||
}
|
||||
if (!verifyFn(buf, sigBuf, pub)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSignFailed',
|
||||
'[boot] boot.manifest.json Ed25519 signature verification failed'
|
||||
)
|
||||
bootManifestMemo = null
|
||||
@@ -1739,7 +1949,10 @@ async function loadBootManifest(ctx) {
|
||||
bootManifestMemo = JSON.parse(b4a.toString(buf))
|
||||
return bootManifestMemo
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestParse',
|
||||
'[boot] boot.manifest.json: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
bootManifestMemo = null
|
||||
@@ -1759,7 +1972,10 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
const exp = /** @type {Record<string, string>} */ (sha)[drivePath]
|
||||
if (exp == null || exp === '') return true
|
||||
if (typeof ctx.bareOsBootFileSha256Hex !== 'function') {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestMissingHasher',
|
||||
'[boot] manifest present but bareOsBootFileSha256Hex missing'
|
||||
)
|
||||
return false
|
||||
@@ -1768,7 +1984,12 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
typeof content === 'string' ? ctx.b4a.from(content, 'utf8') : content
|
||||
const hex = ctx.bareOsBootFileSha256Hex(buf)
|
||||
if (hex !== String(exp).trim().toLowerCase()) {
|
||||
ctx.console.error('[boot] manifest sha256 mismatch: ' + drivePath)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootManifestSha256Mismatch',
|
||||
'[boot] manifest sha256 mismatch: ' + drivePath
|
||||
)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -1780,7 +2001,7 @@ async function bootManifestDigestOk(ctx, drivePath, content) {
|
||||
* @returns {Promise<boolean>} false if BARE_OS_BOOT_STRICT and a line threw
|
||||
*/
|
||||
async function runRcLines(ctx, text) {
|
||||
const { execLine, console } = ctx
|
||||
const { execLine } = ctx
|
||||
const strict = bootStrict(ctx)
|
||||
const allow = await loadBootAllowSet(ctx)
|
||||
const dry = bootDryRun(ctx)
|
||||
@@ -1788,7 +2009,12 @@ async function runRcLines(ctx, text) {
|
||||
const t = line.trim()
|
||||
if (!t || t.startsWith('#')) continue
|
||||
if (allow && !bootLineAllowed(t, allow)) {
|
||||
console.error('[boot] command not in boot.allow: ' + t.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootAllowDenied',
|
||||
'[boot] command not in boot.allow: ' + t.slice(0, 120)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1797,13 +2023,23 @@ async function runRcLines(ctx, text) {
|
||||
continue
|
||||
}
|
||||
if (dry) {
|
||||
console.error('[boot-dry-run] skip execLine: ' + t.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunExecLine',
|
||||
'[boot-dry-run] skip execLine: ' + t.slice(0, 120)
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await execLine(t)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'execLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1873,7 +2109,10 @@ async function runProfileRc(ctx, profileName) {
|
||||
if (!profileName) return true
|
||||
const safe = profileName.replace(/[^a-zA-Z0-9._-]/g, '')
|
||||
if (safe !== profileName) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootProfileInvalidChars',
|
||||
'[boot] profile name contains unsupported characters; skipping rc.profile'
|
||||
)
|
||||
return true
|
||||
@@ -1892,7 +2131,7 @@ async function runProfileRc(ctx, profileName) {
|
||||
*/
|
||||
async function runOnboot(ctx) {
|
||||
if (!ctx.bareOsSkipRepl) return true
|
||||
const { execLine, console, drive, b4a, env } = ctx
|
||||
const { execLine, drive, b4a, env } = ctx
|
||||
const strict = bootStrict(ctx)
|
||||
const allow = await loadBootAllowSet(ctx)
|
||||
/** @type {string[]} */
|
||||
@@ -1915,13 +2154,21 @@ async function runOnboot(ctx) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('onboot: ' + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootRead',
|
||||
'onboot: ' + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
const dry = bootDryRun(ctx)
|
||||
for (const line of lines) {
|
||||
if (allow && !bootLineAllowed(line, allow)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootBootAllowDenied',
|
||||
'[boot] onboot command not in boot.allow: ' + line.slice(0, 120)
|
||||
)
|
||||
if (strict) {
|
||||
@@ -1932,13 +2179,23 @@ async function runOnboot(ctx) {
|
||||
continue
|
||||
}
|
||||
if (dry) {
|
||||
console.error('[boot-dry-run] skip onboot: ' + line.slice(0, 120))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunOnboot',
|
||||
'[boot-dry-run] skip onboot: ' + line.slice(0, 120)
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await execLine(line)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'onbootExecLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
if (strict) {
|
||||
if (typeof ctx.requestBooterExit === 'function')
|
||||
ctx.requestBooterExit(1)
|
||||
@@ -1956,7 +2213,7 @@ async function runOnboot(ctx) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runRcFileAt(ctx, drivePath, label) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
const buf = await drive.get(drivePath)
|
||||
if (!buf) return true
|
||||
@@ -1971,7 +2228,12 @@ async function runRcFileAt(ctx, drivePath, label) {
|
||||
}
|
||||
return await runRcLines(ctx, text)
|
||||
} catch (e) {
|
||||
console.error(`${label}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rcFileRead',
|
||||
`${label}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1994,7 +2256,7 @@ function isBareOsRcSnippetFile(name) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runBareOsKernelDir(ctx) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
try {
|
||||
/** @type {string[]} */
|
||||
const names = []
|
||||
@@ -2042,17 +2304,32 @@ async function runBareOsKernelDir(ctx) {
|
||||
if (!buf) continue
|
||||
const txt = b4a.toString(buf)
|
||||
if (!kernelSnippetEnvGuardsOk(ctx, txt)) {
|
||||
console.error(`[boot] kernel.d/${name}: ConditionEnvironment / AssertEnvironment not met; skip`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.envGuardSkip',
|
||||
`[boot] kernel.d/${name}: ConditionEnvironment / AssertEnvironment not met; skip`
|
||||
)
|
||||
continue
|
||||
}
|
||||
const cont = await runRcLines(ctx, txt)
|
||||
if (!cont) return false
|
||||
} catch (e) {
|
||||
console.error(`kernel.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.exec',
|
||||
`kernel.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernel.d.outer',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -2151,7 +2428,7 @@ function kernelExtDependencyDepth(entries) {
|
||||
async function runKernelExtDropins(ctx, opts = {}) {
|
||||
const incremental = opts.incremental === true
|
||||
const ranScripts = opts.ranScripts
|
||||
const { drive, console } = ctx
|
||||
const { drive } = ctx
|
||||
const run = ctx.bareOsRunImageScript
|
||||
if (typeof run !== 'function') return true
|
||||
if (!ctx.bareOsLoadedKernelExtScripts) {
|
||||
@@ -2202,7 +2479,12 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
? String(pol.id).trim()
|
||||
: name.replace(/\.json$/i, '')
|
||||
if (deny.has(extId)) {
|
||||
console.error(`[kernel.ext.d] denied by policy id: ${extId}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.denyId',
|
||||
`[kernel.ext.d] denied by policy id: ${extId}`
|
||||
)
|
||||
continue
|
||||
}
|
||||
const scripts = pol.scripts
|
||||
@@ -2238,7 +2520,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
? ctx.bareOsCtxApiVersion.trim()
|
||||
: String(ctx.bareOsCtxApiVersion || '').trim()
|
||||
if (!haveS || !semverGte(haveS, minExtCtx)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.minCtxApiVersion',
|
||||
`[kernel.ext.d] ${name}: minCtxApiVersion ${minExtCtx} not satisfied (have ${haveS || 'none'})`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2258,7 +2543,12 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
signaturePointer: sig || undefined
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(`kernel.ext.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.dropinParse',
|
||||
`kernel.ext.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
const idToCollected = new Map(collected.map((e) => [e.extId, e]))
|
||||
@@ -2279,7 +2569,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
for (const e of collected) {
|
||||
for (const c of e.conflictsWith) {
|
||||
if (idSet.has(c)) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.conflict',
|
||||
`[kernel.ext.d] conflict: extension "${e.extId}" conflictsWith "${c}"`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2289,7 +2582,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
if (maxDepthCap > 0) {
|
||||
const d = kernelExtDependencyDepth(collected)
|
||||
if (d > maxDepthCap) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.maxDepth',
|
||||
`[kernel.ext.d] maxKernelExtensionDepth exceeded (${d} > ${maxDepthCap})`
|
||||
)
|
||||
if (strictPol) return false
|
||||
@@ -2299,7 +2595,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
/** @type {typeof collected} */
|
||||
let ordered
|
||||
if (!topo.ok) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.cycle',
|
||||
'[kernel.ext.d] dependency cycle in extension drop-ins; ext ids: ' +
|
||||
topo.cycleExtIds.join(', ')
|
||||
)
|
||||
@@ -2372,14 +2671,24 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
for (const sp of ent.scripts) {
|
||||
const imgPath = String(sp).trim()
|
||||
if (!imgPath.startsWith('/lib/bare-os/extensions/')) {
|
||||
console.error(`[kernel.ext.d] rejected script path: ${imgPath}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.rejectedPath',
|
||||
`[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}`)
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootDryRunKernelExt',
|
||||
`[boot-dry-run] skip kernel.ext.d script: ${imgPath}`
|
||||
)
|
||||
continue
|
||||
}
|
||||
try {
|
||||
@@ -2396,7 +2705,10 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'kernelExt.scriptThrown',
|
||||
`[kernel.ext.d] ${ent.file}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
@@ -2411,7 +2723,7 @@ async function runKernelExtDropins(ctx, opts = {}) {
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function runBareOsRcDir(ctx) {
|
||||
const { drive, b4a, console } = ctx
|
||||
const { drive, b4a } = ctx
|
||||
const skip = parseRcDSkipPatterns(ctx)
|
||||
try {
|
||||
/** @type {string[]} */
|
||||
@@ -2461,11 +2773,21 @@ async function runBareOsRcDir(ctx) {
|
||||
const cont = await runRcLines(ctx, b4a.toString(buf))
|
||||
if (!cont) return false
|
||||
} catch (e) {
|
||||
console.error(`rc.d/${name}: ` + ((e && e.message) || String(e)))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rc.d.exec',
|
||||
`rc.d/${name}: ` + ((e && e.message) || String(e))
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'rc.d.outer',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -2783,7 +3105,10 @@ function mergeBootCapabilityContract(ctx) {
|
||||
const ap = /** @type {{ primary?: number }} */ (adv).primary
|
||||
const sp = /** @type {{ primary?: number }} */ (seed).primary
|
||||
if (typeof ap === 'number' && typeof sp === 'number' && ap !== sp) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCapabilityPrimaryMismatch',
|
||||
'[boot] strict: primary kernel capability word mismatch (advertised vs seed)'
|
||||
)
|
||||
if (typeof ctx.requestBooterExit === 'function') ctx.requestBooterExit(1)
|
||||
@@ -2793,8 +3118,11 @@ function mergeBootCapabilityContract(ctx) {
|
||||
const dbg =
|
||||
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === '1' ||
|
||||
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === 'true'
|
||||
if (dbg && ctx.console) {
|
||||
ctx.console.error(
|
||||
if (dbg) {
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCapabilityContractDebug',
|
||||
'[boot] capability contract debug: advertised=' +
|
||||
(adv ? 'yes' : 'no') +
|
||||
' seed=' +
|
||||
@@ -2816,7 +3144,10 @@ function enforceBootCtxApiMin(ctx) {
|
||||
? ctx.bareOsCtxApiVersion.trim()
|
||||
: ''
|
||||
if (!have || !semverGte(have, need)) {
|
||||
ctx.console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootCtxApiMin',
|
||||
'[boot] BARE_OS_REQUIRE_CTX_API_MIN not satisfied (need ' +
|
||||
need +
|
||||
', have ' +
|
||||
@@ -2838,7 +3169,7 @@ function enforceBootCtxApiMin(ctx) {
|
||||
|
||||
async function start(ctx) {
|
||||
const bootT0 = Date.now()
|
||||
const { readLine, execLine, console } = ctx
|
||||
const { readLine, execLine } = ctx
|
||||
/** @type {string[]} */
|
||||
const stageLog = []
|
||||
const bootPolicySkipSet = new Set()
|
||||
@@ -3010,9 +3341,17 @@ async function start(ctx) {
|
||||
if (Number.isFinite(budget) && budget > 0) {
|
||||
const wall = Date.now() - bootT0
|
||||
if (wall > budget) {
|
||||
console.error(
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'bootBudgetColdExceeded',
|
||||
`[boot] cold wall ${wall}ms exceeds BARE_OS_BOOT_BUDGET_MS_COLD=${budget}ms`
|
||||
)
|
||||
if (ctx.env) {
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_EXCEEDED = '1'
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_WALL_MS = String(wall)
|
||||
ctx.env.BARE_OS_BOOT_BUDGET_COLD_LIMIT_MS = String(budget)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3025,7 +3364,12 @@ async function start(ctx) {
|
||||
try {
|
||||
status = await execLine(t)
|
||||
} catch (e) {
|
||||
console.error((e && e.message) || String(e))
|
||||
bootStructuredLog(
|
||||
ctx,
|
||||
'error',
|
||||
'replExecLineThrown',
|
||||
(e && e.message) || String(e)
|
||||
)
|
||||
}
|
||||
if (status === 'exit') break
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user