@proagentstore/cli 0.4.150 → 0.4.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +135 -90
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2395,6 +2395,101 @@ function releaseTrial(version2, cell, log, env = process.env, root = payloadRoot
|
|
|
2395
2395
|
};
|
|
2396
2396
|
}
|
|
2397
2397
|
|
|
2398
|
+
// src/commands/up-restart.ts
|
|
2399
|
+
import { spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "child_process";
|
|
2400
|
+
var UP_LAUNCHER_ENV = "PAGS_UP_LAUNCHER";
|
|
2401
|
+
var UP_LAUNCHER_PID_ENV = "PAGS_UP_LAUNCHER_PID";
|
|
2402
|
+
var RUNNER_DIED_EXIT_CODE = 76;
|
|
2403
|
+
function upRestartMode(env, parent = { pid: process.ppid, alive: pidAlive }) {
|
|
2404
|
+
if (env[SERVICE_ENV] === "1") return "service";
|
|
2405
|
+
if (env[RESTART_COMMAND_ENV]?.trim()) return "command";
|
|
2406
|
+
const launcher = Number(env[UP_LAUNCHER_PID_ENV]);
|
|
2407
|
+
if (env[UP_LAUNCHER_ENV] === "1" && launcher === parent.pid && parent.alive(launcher)) return "launcher-child";
|
|
2408
|
+
return "launcher";
|
|
2409
|
+
}
|
|
2410
|
+
function runnerExitAction(code, stopping) {
|
|
2411
|
+
if (code === RUNNER_RESTART_EXIT_CODE) return "restart";
|
|
2412
|
+
if (stopping) return "ignore";
|
|
2413
|
+
return code === 0 ? "stop" : "died";
|
|
2414
|
+
}
|
|
2415
|
+
function restartOwner(env = process.env, alive = pidAlive) {
|
|
2416
|
+
if (env[SERVICE_ENV] === "1") return "service";
|
|
2417
|
+
return env[UP_LAUNCHER_ENV] === "1" && alive(Number(env[UP_LAUNCHER_PID_ENV])) ? "launcher" : "none";
|
|
2418
|
+
}
|
|
2419
|
+
function relaunchDelayMs(failures) {
|
|
2420
|
+
return Math.min(5 * 6e4, 1e4 * 2 ** Math.max(0, failures - 1));
|
|
2421
|
+
}
|
|
2422
|
+
var RAN_MS = 6e4;
|
|
2423
|
+
var RESET_MS = 10 * 6e4;
|
|
2424
|
+
function processRestartDeps() {
|
|
2425
|
+
return {
|
|
2426
|
+
env: process.env,
|
|
2427
|
+
execPath: process.execPath,
|
|
2428
|
+
execArgv: process.execArgv,
|
|
2429
|
+
script: process.argv[1],
|
|
2430
|
+
spawn: nodeSpawn,
|
|
2431
|
+
spawnSync: nodeSpawnSync,
|
|
2432
|
+
exit: (code) => process.exit(code),
|
|
2433
|
+
log: () => {
|
|
2434
|
+
},
|
|
2435
|
+
sleep: (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms),
|
|
2436
|
+
step: (line) => logUpdateStep(line),
|
|
2437
|
+
parent: { pid: process.ppid, alive: pidAlive },
|
|
2438
|
+
pid: process.pid,
|
|
2439
|
+
now: Date.now
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2442
|
+
function restartPagsUp(args, extraEnv, deps, opts = {}) {
|
|
2443
|
+
const env = { ...deps.env, ...extraEnv };
|
|
2444
|
+
const argv = [...deps.execArgv, deps.script, ...args];
|
|
2445
|
+
const exitCode = opts.exitCode ?? RUNNER_RESTART_EXIT_CODE;
|
|
2446
|
+
const mode = upRestartMode(env, deps.parent);
|
|
2447
|
+
deps.step(`${opts.initial ? "start" : "restart"}: pags ${args.join(" ")} \u2014 ${opts.initial ? "as" : "leaving via"} ${mode}${exitCode === RUNNER_DIED_EXIT_CODE ? " (the runner died)" : ""}`);
|
|
2448
|
+
if (mode === "service") {
|
|
2449
|
+
deps.exit(exitCode);
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
if (mode === "command") {
|
|
2453
|
+
leaveForRestart(mode, { spawn: deps.spawn, exit: deps.exit });
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
if (mode === "launcher-child") {
|
|
2457
|
+
deps.exit(exitCode);
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
const childEnv = { ...env, [UP_LAUNCHER_ENV]: "1", [UP_LAUNCHER_PID_ENV]: String(deps.pid) };
|
|
2461
|
+
let failures = 0;
|
|
2462
|
+
for (let first = true; ; first = false) {
|
|
2463
|
+
const unattended = !first || env.PAGS_NO_PROMPT === "1";
|
|
2464
|
+
deps.step(`launcher: starting pags up${unattended ? " (unattended)" : ""}`);
|
|
2465
|
+
const startedAt = deps.now();
|
|
2466
|
+
const r = deps.spawnSync(deps.execPath, argv, { stdio: "inherit", env: first ? childEnv : { ...childEnv, PAGS_NO_PROMPT: "1" } });
|
|
2467
|
+
const ran = deps.now() - startedAt;
|
|
2468
|
+
const how = r.error ? `could not start (${r.error.message})` : r.signal ? `was killed by ${r.signal}` : `exited ${r.status}`;
|
|
2469
|
+
deps.step(`launcher: pags up ${how} after ${Math.round(ran / 1e3)}s`);
|
|
2470
|
+
if (ran >= RESET_MS) failures = 0;
|
|
2471
|
+
if (r.status === RUNNER_RESTART_EXIT_CODE) {
|
|
2472
|
+
failures = 0;
|
|
2473
|
+
continue;
|
|
2474
|
+
}
|
|
2475
|
+
if (!r.error && (r.status === 0 || r.signal === "SIGINT")) {
|
|
2476
|
+
deps.exit(0);
|
|
2477
|
+
return;
|
|
2478
|
+
}
|
|
2479
|
+
if (unattended || r.status === RUNNER_DIED_EXIT_CODE || ran >= RAN_MS) {
|
|
2480
|
+
failures++;
|
|
2481
|
+
const wait = relaunchDelayMs(failures);
|
|
2482
|
+
deps.log(`pags up ${how} \u2014 starting it again in ${Math.round(wait / 1e3)}s (attempt ${failures + 1}).`);
|
|
2483
|
+
deps.step(`launcher: retrying in ${Math.round(wait / 1e3)}s (failure ${failures})`);
|
|
2484
|
+
deps.sleep(wait);
|
|
2485
|
+
continue;
|
|
2486
|
+
}
|
|
2487
|
+
if (!opts.initial) deps.log(`Restart failed${typeof r.status === "number" ? ` (exit ${r.status})` : ""} \u2014 the runner is NOT running. Run 'pags up' again.`);
|
|
2488
|
+
deps.exit(typeof r.status === "number" && r.status !== 0 ? r.status : 1);
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2398
2493
|
// src/commands/runner/relay.ts
|
|
2399
2494
|
var MEMBERSHIP_SYNC_PATH = "/pags/membership/sync";
|
|
2400
2495
|
var CLI_CONTROL_PATHS = /* @__PURE__ */ new Set([MEMBERSHIP_SYNC_PATH, RUNNER_UPDATE_PATH, RUNNER_RESTART_PATH]);
|
|
@@ -2690,7 +2785,9 @@ async function connectViaRelay(instanceIds, localUrl, runnerToken, opts, force =
|
|
|
2690
2785
|
// #896: who is heartbeating. Set by `runner connect` from the lock it took.
|
|
2691
2786
|
...process.env.PAGS_RUNNER_RSID ? { rsid: process.env.PAGS_RUNNER_RSID } : {},
|
|
2692
2787
|
pid: process.pid,
|
|
2693
|
-
...process.env.PAGS_RUNNER_LAUNCH ? { launch: process.env.PAGS_RUNNER_LAUNCH } : {}
|
|
2788
|
+
...process.env.PAGS_RUNNER_LAUNCH ? { launch: process.env.PAGS_RUNNER_LAUNCH } : {},
|
|
2789
|
+
supervisor: restartOwner()
|
|
2790
|
+
// #1154: what starts it again if it dies
|
|
2694
2791
|
},
|
|
2695
2792
|
relayRttMs,
|
|
2696
2793
|
sessions: sessions ?? void 0
|
|
@@ -3257,6 +3354,8 @@ function createRunnerCommand() {
|
|
|
3257
3354
|
process.exit(1);
|
|
3258
3355
|
}
|
|
3259
3356
|
lockHeld = { path: taken.path, rsid: taken.lock.rsid, nonce: taken.lock.nonce, launch: taken.lock.launch };
|
|
3357
|
+
process.env.PAGS_RUNNER_RSID = taken.lock.rsid;
|
|
3358
|
+
process.env.PAGS_RUNNER_LAUNCH = taken.lock.launch;
|
|
3260
3359
|
writeLine(`STATUS runner-session=${taken.lock.rsid}`);
|
|
3261
3360
|
}
|
|
3262
3361
|
const releaseHeldLock = () => {
|
|
@@ -3453,7 +3552,7 @@ import { readFileSync as readFileSync11, statSync as statSync2, watchFile } from
|
|
|
3453
3552
|
import { Command as Command9 } from "commander";
|
|
3454
3553
|
|
|
3455
3554
|
// src/background.ts
|
|
3456
|
-
import { spawn as
|
|
3555
|
+
import { spawn as nodeSpawn2 } from "child_process";
|
|
3457
3556
|
import { closeSync as closeSync3, existsSync as existsSync10, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync10, renameSync as renameSync4, statSync, writeFileSync as writeFileSync6 } from "fs";
|
|
3458
3557
|
import { dirname as dirname5, join as join11 } from "path";
|
|
3459
3558
|
var BACKGROUND_ENV = "PAGS_BACKGROUND";
|
|
@@ -3492,7 +3591,7 @@ function backgroundRestartCommand(execPath, script, upArgs, platform = process.p
|
|
|
3492
3591
|
const argv = [execPath, script, ...upArgs, "--background"].map((a) => shellQuote(a, platform)).join(" ");
|
|
3493
3592
|
return platform === "win32" ? `set ${BACKGROUND_RESTART_ENV}=1&& ${argv}` : `${BACKGROUND_RESTART_ENV}=1 ${argv}`;
|
|
3494
3593
|
}
|
|
3495
|
-
function spawnDetached(command, args, env, logPath, spawn5 =
|
|
3594
|
+
function spawnDetached(command, args, env, logPath, spawn5 = nodeSpawn2) {
|
|
3496
3595
|
mkdirSync8(dirname5(logPath), { recursive: true });
|
|
3497
3596
|
rotateLog(logPath);
|
|
3498
3597
|
const fd = openSync3(logPath, "a", 384);
|
|
@@ -3709,75 +3808,6 @@ async function waitForKey(keys, onInterrupt) {
|
|
|
3709
3808
|
});
|
|
3710
3809
|
}
|
|
3711
3810
|
|
|
3712
|
-
// src/commands/up-restart.ts
|
|
3713
|
-
import { spawn as nodeSpawn2, spawnSync as nodeSpawnSync } from "child_process";
|
|
3714
|
-
var UP_LAUNCHER_ENV = "PAGS_UP_LAUNCHER";
|
|
3715
|
-
function upRestartMode(env) {
|
|
3716
|
-
if (env[SERVICE_ENV] === "1") return "service";
|
|
3717
|
-
if (env[RESTART_COMMAND_ENV]?.trim()) return "command";
|
|
3718
|
-
if (env[UP_LAUNCHER_ENV] === "1") return "launcher-child";
|
|
3719
|
-
return "launcher";
|
|
3720
|
-
}
|
|
3721
|
-
function relaunchDelayMs(failures) {
|
|
3722
|
-
return Math.min(5 * 6e4, 1e4 * 2 ** Math.max(0, failures - 1));
|
|
3723
|
-
}
|
|
3724
|
-
function processRestartDeps() {
|
|
3725
|
-
return {
|
|
3726
|
-
env: process.env,
|
|
3727
|
-
execPath: process.execPath,
|
|
3728
|
-
execArgv: process.execArgv,
|
|
3729
|
-
script: process.argv[1],
|
|
3730
|
-
spawn: nodeSpawn2,
|
|
3731
|
-
spawnSync: nodeSpawnSync,
|
|
3732
|
-
exit: (code) => process.exit(code),
|
|
3733
|
-
log: () => {
|
|
3734
|
-
},
|
|
3735
|
-
sleep: (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms),
|
|
3736
|
-
step: (line) => logUpdateStep(line)
|
|
3737
|
-
};
|
|
3738
|
-
}
|
|
3739
|
-
function restartPagsUp(args, extraEnv, deps) {
|
|
3740
|
-
const env = { ...deps.env, ...extraEnv };
|
|
3741
|
-
const argv = [...deps.execArgv, deps.script, ...args];
|
|
3742
|
-
const mode = upRestartMode(env);
|
|
3743
|
-
deps.step(`restart: pags ${args.join(" ")} \u2014 leaving via ${mode}`);
|
|
3744
|
-
if (mode === "service" || mode === "command") {
|
|
3745
|
-
leaveForRestart(mode, { spawn: deps.spawn, exit: deps.exit });
|
|
3746
|
-
return;
|
|
3747
|
-
}
|
|
3748
|
-
if (mode === "launcher-child") {
|
|
3749
|
-
deps.exit(RUNNER_RESTART_EXIT_CODE);
|
|
3750
|
-
return;
|
|
3751
|
-
}
|
|
3752
|
-
let failures = 0;
|
|
3753
|
-
for (let first = true; ; first = false) {
|
|
3754
|
-
const unattended = !first || env.PAGS_NO_PROMPT === "1";
|
|
3755
|
-
deps.step(`launcher: starting pags up${unattended ? " (unattended)" : ""}`);
|
|
3756
|
-
const r = deps.spawnSync(deps.execPath, argv, { stdio: "inherit", env: { ...env, [UP_LAUNCHER_ENV]: "1", ...first ? {} : { PAGS_NO_PROMPT: "1" } } });
|
|
3757
|
-
const how = r.error ? `could not start (${r.error.message})` : r.signal ? `was killed by ${r.signal}` : `exited ${r.status}`;
|
|
3758
|
-
deps.step(`launcher: pags up ${how}`);
|
|
3759
|
-
if (r.status === RUNNER_RESTART_EXIT_CODE) {
|
|
3760
|
-
failures = 0;
|
|
3761
|
-
continue;
|
|
3762
|
-
}
|
|
3763
|
-
if (!r.error && r.status === 0) {
|
|
3764
|
-
deps.exit(0);
|
|
3765
|
-
return;
|
|
3766
|
-
}
|
|
3767
|
-
if (unattended) {
|
|
3768
|
-
failures++;
|
|
3769
|
-
const wait = relaunchDelayMs(failures);
|
|
3770
|
-
deps.log(`pags up ${how} \u2014 starting it again in ${Math.round(wait / 1e3)}s (attempt ${failures + 1}).`);
|
|
3771
|
-
deps.step(`launcher: retrying in ${Math.round(wait / 1e3)}s (failure ${failures})`);
|
|
3772
|
-
deps.sleep(wait);
|
|
3773
|
-
continue;
|
|
3774
|
-
}
|
|
3775
|
-
deps.log(`Restart failed${typeof r.status === "number" ? ` (exit ${r.status})` : ""} \u2014 the runner is NOT running. Run 'pags up' again.`);
|
|
3776
|
-
deps.exit(typeof r.status === "number" && r.status !== 0 ? r.status : 1);
|
|
3777
|
-
return;
|
|
3778
|
-
}
|
|
3779
|
-
}
|
|
3780
|
-
|
|
3781
3811
|
// src/runner-replace.ts
|
|
3782
3812
|
var REPLACE_EXIT_TIMEOUT_MS = 3e4;
|
|
3783
3813
|
function describeWork(work) {
|
|
@@ -3987,6 +4017,15 @@ start();
|
|
|
3987
4017
|
var xml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
3988
4018
|
var unitWord = (s) => `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
3989
4019
|
var ps = (s) => `'${s.replace(/'/g, "''")}'`;
|
|
4020
|
+
function versionManagedNode(nodePath) {
|
|
4021
|
+
if (/[\\/]n[\\/]versions[\\/]/.test(nodePath)) return "n";
|
|
4022
|
+
const m = /[\\/]\.?(nvm|fnm|volta|asdf|nodenv)[\\/]/i.exec(nodePath);
|
|
4023
|
+
return m ? m[1].toLowerCase() : null;
|
|
4024
|
+
}
|
|
4025
|
+
var pinnedNodeNote = (ctx) => {
|
|
4026
|
+
const manager = versionManagedNode(ctx.nodePath);
|
|
4027
|
+
return manager ? [`It runs Node ${ctx.nodePath}, installed by ${manager}. Removing or switching away from that Node version stops the service; after changing Node, run \`pags up --install-service\` again.`] : [];
|
|
4028
|
+
};
|
|
3990
4029
|
function servicePlan(ctx) {
|
|
3991
4030
|
const supervisor = supervisorPath(ctx);
|
|
3992
4031
|
const log = serviceLogPath(ctx);
|
|
@@ -4010,6 +4049,7 @@ function servicePlan(ctx) {
|
|
|
4010
4049
|
<key>KeepAlive</key><true/>
|
|
4011
4050
|
<key>ThrottleInterval</key><integer>30</integer>
|
|
4012
4051
|
<key>ProcessType</key><string>Background</string>
|
|
4052
|
+
<key>WorkingDirectory</key><string>${xml(ctx.home)}</string>
|
|
4013
4053
|
<key>StandardOutPath</key><string>${xml(log)}</string>
|
|
4014
4054
|
<key>StandardErrorPath</key><string>${xml(log)}</string>
|
|
4015
4055
|
</dict>
|
|
@@ -4025,6 +4065,7 @@ function servicePlan(ctx) {
|
|
|
4025
4065
|
{ file: "launchctl", args: ["kickstart", "-k", `${domain}/${SERVICE_LABEL}`], why: "start it now" }
|
|
4026
4066
|
],
|
|
4027
4067
|
notes: [
|
|
4068
|
+
...pinnedNodeNote(ctx),
|
|
4028
4069
|
`LaunchAgent ${plist} \u2014 runs while this user is logged in. On a machine that must survive a reboot unattended, turn on automatic login for this user.`,
|
|
4029
4070
|
`Remove it with: pags up --uninstall-service`
|
|
4030
4071
|
]
|
|
@@ -4039,8 +4080,11 @@ function servicePlan(ctx) {
|
|
|
4039
4080
|
$ErrorActionPreference = 'Stop'
|
|
4040
4081
|
$action = New-ScheduledTaskAction -Execute ${ps(ctx.nodePath)} -Argument ${ps(`"${supervisor}"`)}
|
|
4041
4082
|
$trigger = New-ScheduledTaskTrigger -AtStartup
|
|
4083
|
+
# Task Scheduler restarts a task that failed to START; a supervisor killed later just ends. Re-trigger it every five
|
|
4084
|
+
# minutes, forever \u2014 MultipleInstances IgnoreNew makes a trigger that finds it running do nothing (#1154).
|
|
4085
|
+
$trigger.Repetition = (New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)).Repetition
|
|
4042
4086
|
$principal = New-ScheduledTaskPrincipal -UserId ${ps(principal)} -LogonType S4U -RunLevel Limited
|
|
4043
|
-
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
|
|
4087
|
+
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -MultipleInstances IgnoreNew
|
|
4044
4088
|
Unregister-ScheduledTask -TaskName ${ps(WINDOWS_TASK)} -Confirm:$false -ErrorAction SilentlyContinue
|
|
4045
4089
|
Register-ScheduledTask -TaskName ${ps(WINDOWS_TASK)} -Action $action -Trigger $trigger -Principal $principal -Settings $settings | Out-Null
|
|
4046
4090
|
Start-ScheduledTask -TaskName ${ps(WINDOWS_TASK)}
|
|
@@ -4051,6 +4095,7 @@ Start-ScheduledTask -TaskName ${ps(WINDOWS_TASK)}
|
|
|
4051
4095
|
files,
|
|
4052
4096
|
commands: [{ file: "powershell.exe", args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", task], why: "register and start the Scheduled Task" }],
|
|
4053
4097
|
notes: [
|
|
4098
|
+
...pinnedNodeNote(ctx),
|
|
4054
4099
|
`Scheduled Task "${WINDOWS_TASK}" \u2014 starts at boot as ${principal || "this user"}, with nobody logged in. Registering it needs an elevated PowerShell: if it was refused, run ${task} from one.`,
|
|
4055
4100
|
`Remove it with: pags up --uninstall-service`
|
|
4056
4101
|
]
|
|
@@ -4085,7 +4130,7 @@ WantedBy=default.target
|
|
|
4085
4130
|
{ file: "systemctl", args: ["--user", "enable", "--now", SYSTEMD_UNIT], why: "enable and start it" },
|
|
4086
4131
|
{ file: "loginctl", args: ["enable-linger", ...ctx.user ? [ctx.user] : []], optional: true, why: "keep it running with nobody logged in" }
|
|
4087
4132
|
],
|
|
4088
|
-
notes: [`systemd user unit ${unit}. Logs: ${log} (and journalctl --user -u ${SYSTEMD_UNIT}).`, `Remove it with: pags up --uninstall-service`]
|
|
4133
|
+
notes: [...pinnedNodeNote(ctx), `systemd user unit ${unit}. Logs: ${log} (and journalctl --user -u ${SYSTEMD_UNIT}).`, `Remove it with: pags up --uninstall-service`]
|
|
4089
4134
|
};
|
|
4090
4135
|
}
|
|
4091
4136
|
function serviceRemovalPlan(ctx) {
|
|
@@ -4149,6 +4194,10 @@ var upCommand = new Command10("up").description("Start the browser runner for al
|
|
|
4149
4194
|
for (const line of uninstallService(serviceContext()).lines) writeLine(line);
|
|
4150
4195
|
return;
|
|
4151
4196
|
}
|
|
4197
|
+
if (!opts.background && !opts.installService && upRestartMode(process.env) === "launcher") {
|
|
4198
|
+
restartPagsUp(process.argv.slice(2), {}, { ...processRestartDeps(), log: (line) => writeLine(` ${line}`) }, { initial: true });
|
|
4199
|
+
return;
|
|
4200
|
+
}
|
|
4152
4201
|
const session = requireSession();
|
|
4153
4202
|
if (opts.installService) {
|
|
4154
4203
|
const result = installService(serviceContext());
|
|
@@ -4355,33 +4404,29 @@ var upCommand = new Command10("up").description("Start the browser runner for al
|
|
|
4355
4404
|
void deliverCrashReports({ apiBase: API_BASE3, token: session.token, account: session.user.login, paths: crashes }).catch(() => void 0);
|
|
4356
4405
|
};
|
|
4357
4406
|
child.on("exit", (code, signal) => {
|
|
4358
|
-
|
|
4407
|
+
const action = runnerExitAction(code, stopping);
|
|
4408
|
+
if (action === "restart") {
|
|
4359
4409
|
logUpdateStep("restart: runner connect asked for a restart (exit 75)");
|
|
4360
4410
|
restartUp("Runner updated remotely \u2014 restarting pags up on the new version\u2026", { PAGS_NO_PROMPT: "1" });
|
|
4361
4411
|
return;
|
|
4362
4412
|
}
|
|
4363
4413
|
childDead = true;
|
|
4364
4414
|
logUpdateStep(`runner connect ${signal ? `was killed by ${signal}` : `exited ${code}`}${stopping ? " (stopping)" : ""}`);
|
|
4365
|
-
if (
|
|
4366
|
-
if (
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
return;
|
|
4371
|
-
}
|
|
4372
|
-
if (code !== 0) {
|
|
4373
|
-
state.runner = "error";
|
|
4374
|
-
state.lastEvent = `Runner exited (code ${code})`;
|
|
4375
|
-
const recent = logs.slice(-5);
|
|
4376
|
-
if (recent.length) state.lastEvent += ": " + recent[recent.length - 1].slice(0, 60);
|
|
4377
|
-
printStatus(state);
|
|
4415
|
+
if (action === "ignore") return;
|
|
4416
|
+
if (action === "stop") {
|
|
4417
|
+
clearScreen();
|
|
4418
|
+
writeLine(" Runner stopped (pags down, or replaced by another pags up).");
|
|
4419
|
+
process.exit(0);
|
|
4378
4420
|
}
|
|
4421
|
+
recordConnectExit(code, signal ?? null, logs.slice(-20));
|
|
4422
|
+
const recent = logs.slice(-5).at(-1);
|
|
4423
|
+
restartUp(`Runner ${signal ? `was killed by ${signal}` : `exited (code ${code})`}${recent ? `: ${recent.slice(0, 60)}` : ""} \u2014 starting it again\u2026`, { PAGS_NO_PROMPT: "1" }, RUNNER_DIED_EXIT_CODE);
|
|
4379
4424
|
});
|
|
4380
|
-
function restartUp(why, env = {}) {
|
|
4425
|
+
function restartUp(why, env = {}, exitCode) {
|
|
4381
4426
|
writeLine(` ${why}`);
|
|
4382
4427
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
4383
4428
|
process.stdin.pause();
|
|
4384
|
-
restartPagsUp(restartUpArgs(opts), env, { ...processRestartDeps(), log: (line) => writeLine(` ${line}`) });
|
|
4429
|
+
restartPagsUp(restartUpArgs(opts), env, { ...processRestartDeps(), log: (line) => writeLine(` ${line}`) }, { exitCode });
|
|
4385
4430
|
process.exit(1);
|
|
4386
4431
|
}
|
|
4387
4432
|
const shutdown = () => {
|