Control remote fleet workers over SSH with user, host, and key path
Some checks are pending
offline / test (push) Waiting to run

NS1 is marchon@70.88.205.138 using ~/.ssh/id_ed25519. Private key
bytes stay off git. Spawn, health, and kill go through ssh; remote
workers bind loopback only.
This commit is contained in:
George Lambert 2026-09-11 13:31:21 -04:00
parent b325f6f697
commit e89e006542
12 changed files with 425 additions and 34 deletions

View file

@ -32,15 +32,29 @@ export function loadMachines(root, overlayPath) {
const incoming = Array.isArray(extra) ? extra : extra.machines || [];
for (const m of incoming) upsertMachine(list, m);
}
const secretsPath = path.join(root, 'machines.secrets.json');
if (fs.existsSync(secretsPath)) {
const secrets = JSON.parse(fs.readFileSync(secretsPath, 'utf8'));
const byId = secrets.machines || secrets;
for (const m of list) {
const extra = byId[m.id];
if (extra && typeof extra === 'object') Object.assign(m, extra);
}
}
return list.map(normalizeMachine);
}
export function normalizeMachine(m) {
const kind = m.kind === 'agent' || m.kind === 'ssh' ? m.kind : 'local';
return {
id: String(m.id || '').trim(),
title: m.title || m.id,
kind: m.kind === 'agent' ? 'agent' : 'local',
kind,
host: m.host || '127.0.0.1',
user: m.user || (kind === 'ssh' ? 'marchon' : ''),
sshPort: Number(m.sshPort || 22),
identityFile: m.identityFile || (kind === 'ssh' ? '~/.ssh/id_ed25519' : ''),
remoteDir: m.remoteDir || '~/verae-fleet-runtime',
agentPort: Number(m.agentPort || 3851),
enabled: m.enabled !== false,
capacity: Number(m.capacity || 8),
@ -72,8 +86,9 @@ export function canHost(machine, serviceId, role) {
* @param {string} serviceId
* @param {string} [role]
*/
export function pickMachine(machines, instances, serviceId, role) {
const eligible = machines.filter((m) => canHost(m, serviceId, role));
export function pickMachine(machines, instances, serviceId, role, exclude = []) {
const skip = new Set(exclude);
const eligible = machines.filter((m) => canHost(m, serviceId, role) && !skip.has(m.id));
if (!eligible.length) return null;
const scored = eligible.map((m) => {
const running = instances.filter((i) => i.machine === m.id && i.pid).length;