Clean prepaid SoT, identity mailbox, public access planes, leaf policy, fleet spawn
Some checks are pending
offline / test (push) Waiting to run

Persist account-balance books; edge caches prepaid from books. Add zappier-identity, verae-nats-accounts, verae-jobs-events, verae-access-staff, zapier-decisions. Edge binds loopback; lan-134 stays off; HTTP services prefer local spawn.
This commit is contained in:
George Lambert 2026-09-11 17:15:16 -04:00
parent 345aeeead9
commit ddf772454b
153 changed files with 2236 additions and 116 deletions

View file

@ -92,15 +92,15 @@ async function main() {
}
if (cmd === 'serve' || cmd === 'monitor') {
const sup = new Supervisor({ loaded });
const mon = new Monitor(sup);
startControlServer(sup, mon);
print(`fleet ${cmd} pid=${process.pid}\nUI http://${loaded.control.bind || '0.0.0.0'}:${loaded.control.port}/\nSIGINT stops all managed replicas`);
for (const id of Object.keys(loaded.services)) {
const s = loaded.services[id];
if (s.managed && s.enabled && s.min > 0) await sup.startService(id);
}
const mon = new Monitor(sup);
await mon.tick();
mon.start();
startControlServer(sup, mon);
print(`fleet ${cmd} pid=${process.pid}\nUI ${BASE}/\nSIGINT stops all managed replicas`);
process.on('SIGINT', async () => {
mon.stop();
await sup.stopAll();

View file

@ -41,7 +41,11 @@ export function loadMachines(root, overlayPath) {
if (extra && typeof extra === 'object') Object.assign(m, extra);
}
}
return list.map(normalizeMachine);
return list.map((m) => {
const n = normalizeMachine(m);
if (n.id === 'lan-134' && process.env.FLEET_ENABLE_LAN134 !== '1') n.enabled = false;
return n;
});
}
export function normalizeMachine(m) {
@ -86,9 +90,13 @@ export function canHost(machine, serviceId, role) {
* @param {string} serviceId
* @param {string} [role]
*/
export function pickMachine(machines, instances, serviceId, role, exclude = []) {
export function pickMachine(machines, instances, serviceId, role, exclude = [], opts = {}) {
const skip = new Set(exclude);
const eligible = machines.filter((m) => canHost(m, serviceId, role) && !skip.has(m.id));
let eligible = machines.filter((m) => canHost(m, serviceId, role) && !skip.has(m.id));
if (opts.preferLocal) {
const local = eligible.filter((m) => m.kind === 'local');
if (local.length) eligible = local;
}
if (!eligible.length) return null;
const scored = eligible.map((m) => {
const running = instances.filter((i) => i.machine === m.id && i.pid).length;

View file

@ -1,6 +1,6 @@
/**
* Operator HTTP: list, status, pause/resume/stop/start/restart.
* Binds 127.0.0.1 only.
* HTTP bind from fleet.json control.bind (default 0.0.0.0).
* @module server
*/
@ -23,7 +23,7 @@ function json(res, code, obj) {
* @param {import('./monitor.js').Monitor} [mon]
*/
export function startControlServer(sup, mon) {
const bind = sup.loaded.control?.bind || '127.0.0.1';
const bind = process.env.FLEET_BIND || sup.loaded.control?.bind || '0.0.0.0';
const port = Number(sup.loaded.control?.port || 3850);
const sim = new Simulator();

View file

@ -57,7 +57,7 @@ export function scpBaseArgs(machine) {
return args;
}
export function sshExec(machine, remoteCommand, { timeoutMs = 20000 } = {}) {
export function sshExec(machine, remoteCommand, { timeoutMs = 8000 } = {}) {
return new Promise((resolve, reject) => {
const args = [...sshBaseArgs(machine), sshTarget(machine), remoteCommand];
const child = spawn('ssh', args, { stdio: ['ignore', 'pipe', 'pipe'] });
@ -96,7 +96,7 @@ export function scpTo(machine, localFiles, remoteDir) {
const t = setTimeout(() => {
child.kill('SIGKILL');
reject(new Error('scp timeout'));
}, 30000);
}, 8000);
child.on('close', (code) => {
clearTimeout(t);
if (code !== 0) reject(new Error(Buffer.concat(err).toString('utf8') || `scp exit ${code}`));

View file

@ -153,6 +153,7 @@ export class Supervisor {
serviceId,
spec.role || serviceId,
opts.excludeMachines || [],
{ preferLocal: Boolean(spec.spawn?.command) },
);
if (!machine) {
this.log('skip', { service: serviceId, reason: 'no-machine-capacity' });