// #1873 proxy setup: host facts that `mosaic proxy` and the Console page share. Never reads a // key, proxy setting or bus record; labels only, never an absolute path. import net from 'node:net'; import { hostStatus } from './host.mjs'; import { socketPath, orgPaths } from './config.mjs'; import { devOwnerInstance } from './dev-local-owner.mjs'; import { listOrgs } from '../../organization/src/org-registry.mjs'; // A socket that accepts a connection, or fails other than "absent"/"refused", counts as running. function socketLive(file, timeout = 1000) { return new Promise(resolve => { const socket = net.connect(file); const done = value => { socket.destroy(); resolve(value); }; socket.setTimeout(timeout, () => done(true)); socket.once('connect', () => done(true)); socket.once('error', error => done(!['ENOENT', 'ECONNREFUSED'].includes(error.code))); }); } async function rootRunning(root, socket) { try { const status = hostStatus(root); if (status.host?.live || status.writerLock?.live) return true; } catch { return true; } return socketLive(socket); } // The init-lock README condition "the bus is stopped", proved for the instance's own bus and // every registered organization's bus. Anything that cannot be examined counts as running. // `listOrgsFn` and `running` are for tests. export async function busesStopped({ dataRoot, configDir, listOrgsFn = listOrgs, running = rootRunning }) { const out = []; if (await running(dataRoot, socketPath(dataRoot))) out.push('the instance bus'); let orgs; try { orgs = await listOrgsFn({ configDir }); } catch { return { stopped: false, running: [...out, 'organization registry unreadable'] }; } for (const org of orgs) { const label = `organization ${typeof org?.id === 'string' ? org.id : '?'}`; let paths; try { paths = orgPaths(org.root); } catch { out.push(label); continue; } if (await running(org.root, paths.socket)) out.push(label); } return { stopped: out.length === 0, running: out }; } // The named instance MOSAIC_CONFIG selects, or null for the default (dev) instance. export function instanceFromConfig(env = process.env) { try { return devOwnerInstance(env); } catch { return null; } }