Skip to content

Commit 5bdf731

Browse files
Dietmar Rietschclaude
andcommitted
feat(container): exec catalog-installed busybox/node from the guest VFS
run()/node() fall back to loading /bin/busybox and /usr/bin/node from the guest VFS when the binary isn't embedded — so the catalog-distributed apps run on a bare emulator. Verified on bare nano.min.wasm: busybox echo + node --version. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d44f22e commit 5bdf731

1 file changed

Lines changed: 15 additions & 4 deletions

File tree

container/nanovm.mjs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,18 @@ class NanoVM {
431431
* @returns {Promise<{exitCode: number, stdout: string}>}
432432
*/
433433
async run(command, opts = {}) {
434-
if (!this._busyboxElf) throw new Error("No busybox ELF loaded");
434+
// Prefer the embedded busybox; otherwise exec a catalog-installed
435+
// /bin/busybox from the guest VFS (the migration distributes it via the catalog).
436+
const elf = this._busyboxElf || this._readElfFromVfs("/bin/busybox");
437+
if (!elf) throw new Error("No busybox ELF loaded (embed it or install the busybox catalog app)");
435438
const argv = command.trim().split(/\s+/);
436-
return this._execute(this._busyboxElf, argv, [], opts);
439+
return this._execute(elf, argv, [], opts);
440+
}
441+
442+
/** Read an installed ELF from the guest VFS (follows symlinks), or null. */
443+
_readElfFromVfs(path) {
444+
const node = this._memfs.resolve(path);
445+
return node && node.isFile && node.data && node.data.length ? node.data : null;
437446
}
438447

439448
/**
@@ -442,7 +451,9 @@ class NanoVM {
442451
* @returns {Promise<{exitCode: number, stdout: string}>}
443452
*/
444453
async node(...argsAndOpts) {
445-
if (!this._nodeElf) throw new Error("No node ELF loaded");
454+
// Embedded node, else a catalog-installed /usr/bin/node from the guest VFS.
455+
const nodeElf = this._nodeElf || this._readElfFromVfs("/usr/bin/node");
456+
if (!nodeElf) throw new Error("No node ELF loaded (install the node catalog app)");
446457
let opts = {};
447458
let args;
448459
const last = argsAndOpts[argsAndOpts.length - 1];
@@ -453,7 +464,7 @@ class NanoVM {
453464
args = ["node", ...argsAndOpts];
454465
}
455466
const envVars = ["UV_THREADPOOL_SIZE=0"];
456-
return this._execute(this._nodeElf, args, envVars, opts);
467+
return this._execute(nodeElf, args, envVars, opts);
457468
}
458469

459470
/** Cancel the currently running execution loop. */

0 commit comments

Comments
 (0)