MCPcopy Create free account
hub / github.com/cloudflare/computer / main

Function main

packages/computerd/src/cli/computerd.ts:448–615  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

446}
447
448async function main(): Promise<void> {
449 // Install logging + crash handlers first thing so any early throws
450 // (parsePort, parseMountPoint, resolveFuseBackend) still land in
451 // LOG_FILE when set.
452 const teardownLogging = installLogging(process.env.LOG_FILE);
453
454 rejectLegacyFuseEnv(process.env);
455
456 const port = parsePort(process.env.PORT);
457 const mountPoint = parseMountPoint(process.env.MOUNT_POINT);
458 // FUSE_MOUNT picks the backend. auto (default) probes /dev/fuse
459 // or macFUSE and falls back to the userspace shim. fuse / macfuse
460 // require their respective real backend. shim forces the userspace
461 // polling shim. none skips the mount entirely; HTTP + /api + /ws
462 // still come up so tests and tooling can talk to computerd's RPC surface.
463 const fuseMountMode = parseFuseMountMode(process.env.FUSE_MOUNT);
464 const backend: FUSEBackend = await resolveFuseBackend(fuseMountMode);
465 console.log(`[info] FUSE_MOUNT=${fuseMountMode} resolved to backend=${backend.kind}`);
466
467 const upstreamUrl = process.env.UPSTREAM_URL?.trim();
468 let upstreamClient: WorkspaceClient | undefined;
469 if (upstreamUrl !== undefined && upstreamUrl.length > 0) {
470 // Use the `ws` package's WebSocket (not Node's built-in
471 // global) so the dial negotiates permessage-deflate against
472 // the upstream's WebSocketServer. Node 22's built-in
473 // WebSocket doesn't advertise the deflate extension.
474 upstreamClient = createWorkspaceClient({
475 url: upstreamUrl,
476 WebSocketImpl: WebSocket as unknown as typeof globalThis.WebSocket,
477 });
478 }
479 const { vfs, db, stopSync } = await createNodeVirtualFileSystem({
480 upstream: upstreamClient?.sync,
481 });
482 const info: ComputerdInfo = { backend, mountPoint, port };
483
484 let fuse: FuseMount | undefined;
485 // When running on the userspace shim, capture the typed handle
486 // so we can wire `flush()` and `reconcileNow()` into the SyncRPC
487 // afterApply / beforeFetch hooks below. A real FUSE mount serves
488 // reads straight from the VFS, so it doesn't need either settle.
489 let shim: ShimMount | undefined;
490 if (backend.kind !== "none") {
491 // The VFS stores everything under `mountPoint` so capnweb pulls,
492 // shim materialisation, and shell `exec` agree on absolute
493 // paths. Pre-create the mount directory in the VFS so FUSE's
494 // first getattr on "/" can stat the mount root.
495 vfs.mkdirSync(mountPoint, { recursive: true });
496 await mkdir(mountPoint, { recursive: true });
497
498 if (backend.kind === "shim") {
499 shim = await mountShim({ vfs, mountPoint });
500 fuse = shim;
501 } else {
502 fuse = await mountFuse({
503 backend,
504 mountPoint,
505 vfs,

Callers 1

computerd.tsFile · 0.70

Calls 15

createWorkspaceClientFunction · 0.90
createWorkspaceServerFunction · 0.90
installLoggingFunction · 0.85
rejectLegacyFuseEnvFunction · 0.85
parsePortFunction · 0.85
parseMountPointFunction · 0.85
parseFuseMountModeFunction · 0.85
resolveFuseBackendFunction · 0.85
mountShimFunction · 0.85
mountFuseFunction · 0.85
createHTTPServerFunction · 0.85

Tested by

no test coverage detected