fix(proxy): installer — no prompts during dry-run; never pin service to agent-bundled node
- askConfirm short-circuits non-interactively in --dry-run (prints what would be asked) - systemd node resolution order: existing unit's pinned binary > newest nvm node > PATH lookup excluding hermes-agent runtimes > process.execPath. On the live box this keeps the unit byte-identical (true idempotency for the service section).
This commit is contained in:
1 parent
3f9be30784
commit
753fac9fe9
1 file changed
+25
-1
@@ -94,6 +94,7 @@ function askSecret(question) {
|
||||
}
|
||||
|
||||
async function askConfirm(question, defaultYes = true) {
|
||||
if (FLAGS.dryRun) { console.log(`(dry-run) would ask: ${question} -> default ${defaultYes ? 'y' : 'n'}`); return defaultYes; }
|
||||
if (FLAGS.nonInteractive) return defaultYes;
|
||||
const a = (await ask(`${question} (y/n)`, defaultYes ? 'y' : 'n')).toLowerCase();
|
||||
return a === 'y';
|
||||
@@ -399,7 +400,30 @@ function sectionUnit() {
|
||||
const S = 'systemd service';
|
||||
if (FLAGS.noSystemd) { report(S, 'SKIPPED', '--no-systemd'); return true; }
|
||||
const unitPath = path.join(SYSTEMD_USER_DIR, 'proxy-bridge.service');
|
||||
const nodeBin = process.execPath;
|
||||
// The service must not run on an agent-bundled runtime: prefer (1) the node
|
||||
// already pinned in an existing unit (stable, known-good), (2) the newest
|
||||
// nvm-installed node, (3) PATH lookup that does NOT resolve into the hermes
|
||||
// agent dir, (4) process.execPath as a last resort.
|
||||
let nodeBin = null;
|
||||
try {
|
||||
const existing = fs.readFileSync(unitPath, 'utf8');
|
||||
const m = existing.match(/^ExecStart=(\S+)\s+/m);
|
||||
if (m && fs.existsSync(m[1])) nodeBin = m[1];
|
||||
} catch {}
|
||||
if (!nodeBin) {
|
||||
const nvmRoot = path.join(os.homedir(), '.nvm', 'versions', 'node');
|
||||
try {
|
||||
const versions = fs.readdirSync(nvmRoot).filter(v => /^v\d+/.test(v)).sort((a, b) =>
|
||||
a.localeCompare(b, undefined, { numeric: true }));
|
||||
if (versions.length > 0) nodeBin = path.join(nvmRoot, versions[versions.length - 1], 'bin', 'node');
|
||||
} catch {}
|
||||
}
|
||||
if (!nodeBin) {
|
||||
const loginNode = run('bash', ['--noprofile', '--norc', '-c', 'command -v node'], { readOnly: true });
|
||||
const cand = loginNode.status === 0 ? loginNode.stdout.trim() : '';
|
||||
if (cand && !fs.realpathSync(cand).includes('/.hermes/')) nodeBin = cand;
|
||||
}
|
||||
if (!nodeBin) nodeBin = process.execPath;
|
||||
const want = `[Unit]\nDescription=Local Proxy Bridge (Keyring Auth)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${nodeBin} ${BRIDGE_DIR}/bridge.js\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;
|
||||
let current = null;
|
||||
try { current = fs.readFileSync(unitPath, 'utf8'); } catch {}
|
||||
|
||||
Reference in new issue
Block a user