@outerlayer/cli 0.24.0 → 0.25.0
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/CHANGELOG.md +15 -0
- package/README.md +9 -0
- package/dist/{agent-setup-QQYRBPK2.js → agent-setup-PDIIGMKE.js} +7 -7
- package/dist/{bridge-4ZARDVGS.js → bridge-5KZ36YDG.js} +3 -3
- package/dist/build-Q2OBF77R.js +12 -0
- package/dist/build-info.json +1 -1
- package/dist/{builder-MECDEKXX.js → builder-PRSCX5AH.js} +6 -6
- package/dist/{check-YYKNYFNI.js → check-EPYRTE3R.js} +38 -37
- package/dist/{chunk-BN3CSI7S.js → chunk-2K3TCQHW.js} +1 -1
- package/dist/{chunk-A62QFN2M.js → chunk-2N72GPS2.js} +3 -3
- package/dist/{chunk-W7O4LA4E.js → chunk-34ANPNVB.js} +2 -2
- package/dist/{chunk-6GSA2SKT.js → chunk-3I44PQ26.js} +205 -56
- package/dist/{chunk-WH2QV3UL.js → chunk-4S4VBDSO.js} +1 -1
- package/dist/{chunk-IDSHLKQA.js → chunk-5222PA6S.js} +1 -1
- package/dist/{chunk-V5Q3S4NM.js → chunk-6CNHXHI2.js} +1 -1
- package/dist/{chunk-LY2L3O2O.js → chunk-7OWPLRJR.js} +1 -1
- package/dist/{chunk-HHXBOTRO.js → chunk-ATGHVEU4.js} +1 -1
- package/dist/{chunk-TTLVQZSH.js → chunk-AXPCGD46.js} +5 -5
- package/dist/{chunk-FWEWFW3F.js → chunk-DEBOL6ON.js} +1 -1
- package/dist/{chunk-E4OUL7ZP.js → chunk-FXUVXSY2.js} +2 -2
- package/dist/{chunk-BUBCPP3F.js → chunk-HBLLZLOH.js} +2 -2
- package/dist/{chunk-F2W2IYNP.js → chunk-HWEIFHSW.js} +2 -2
- package/dist/{chunk-F7Y2USIM.js → chunk-IDJIWKTY.js} +2 -2
- package/dist/{chunk-DG2ULWM6.js → chunk-IGRRD7PX.js} +11 -7
- package/dist/{chunk-GISNHSYL.js → chunk-JGD5TWQ2.js} +4 -2
- package/dist/{chunk-BOQY756V.js → chunk-JKILLWZF.js} +8 -7
- package/dist/{chunk-D7X5ITVT.js → chunk-JWRX5ZTT.js} +6 -2
- package/dist/{chunk-755WXDBI.js → chunk-K5WVK7IC.js} +1 -1
- package/dist/{chunk-H6IUKXXI.js → chunk-L2FZLBF7.js} +207 -35
- package/dist/{chunk-FKXGQOF5.js → chunk-M4B6QKNZ.js} +1 -1
- package/dist/{chunk-NTQTDCYR.js → chunk-O2WYUIK7.js} +1 -1
- package/dist/{chunk-VV7ZD5LR.js → chunk-QMQC6JCO.js} +1 -1
- package/dist/{chunk-5XCAPBE2.js → chunk-QUGYGO6L.js} +5 -5
- package/dist/{chunk-FQPN5S4Q.js → chunk-QXNJWSTM.js} +4 -4
- package/dist/{chunk-3W333NFO.js → chunk-RGW7ERF3.js} +15 -4
- package/dist/{chunk-CZUH2SLQ.js → chunk-UNF7MWEL.js} +1 -1
- package/dist/{chunk-ZFLOFAUG.js → chunk-VMF5LK3D.js} +7 -7
- package/dist/{chunk-VBEXKEBV.js → chunk-VNGENFOG.js} +19 -6
- package/dist/{chunk-5ECUMU53.js → chunk-VPUNOGXO.js} +6 -6
- package/dist/{chunk-RVYOOYOA.js → chunk-X5LNCIZT.js} +18 -9
- package/dist/{chunk-PDIM5T65.js → chunk-XGJUNNXL.js} +1 -1
- package/dist/{chunk-GU4PKXN7.js → chunk-XHXDCYSK.js} +184 -37
- package/dist/{chunk-NGZID7UI.js → chunk-XRYUJTAT.js} +8 -1
- package/dist/{chunk-TQ6Y7YV6.js → chunk-YMKQVCKC.js} +5 -5
- package/dist/{chunk-D7K446H6.js → chunk-YTTHDPWF.js} +4 -4
- package/dist/{chunk-LBCZXXOX.js → chunk-ZGMQQWCV.js} +2 -2
- package/dist/{chunk-KF37SUDM.js → chunk-ZI2ZVWKT.js} +1 -1
- package/dist/{chunk-PVRBE7S4.js → chunk-ZODVSFI4.js} +1 -1
- package/dist/chunk-ZVB57WI6.js +19 -0
- package/dist/{claude-launcher-JCPSHDZQ.js → claude-launcher-WGOCLTG6.js} +1 -1
- package/dist/{cli-ZTBH3FBG.js → cli-2LGSPAYZ.js} +105 -100
- package/dist/command-ITLPJ5XU.js +533 -0
- package/dist/{config-7Z5DHSGY.js → config-JJ3EO7SB.js} +3 -3
- package/dist/{connect-cmd-NY5LIKVC.js → connect-cmd-JFDZKPND.js} +6 -6
- package/dist/{container-start-OHBUZEJJ.js → container-start-X22OXY6E.js} +44 -35
- package/dist/{control-plane-launch-GKGI6HJA.js → control-plane-launch-ZFT6SI4N.js} +6 -6
- package/dist/{docker-RKGBJESN.js → docker-PQHWAY5J.js} +6 -6
- package/dist/{doctor-DOAFZV4O.js → doctor-73GNT4VV.js} +78 -32
- package/dist/{emit-artifact-cmd-VZHIDPXQ.js → emit-artifact-cmd-AIOTX6YT.js} +10 -10
- package/dist/{emit-criteria-cmd-SYLBCWHW.js → emit-criteria-cmd-7PJINOHA.js} +7 -7
- package/dist/{emit-finding-cmd-52M43NPC.js → emit-finding-cmd-JRDSZ4DR.js} +7 -7
- package/dist/{emit-result-cmd-BTMTGDAV.js → emit-result-cmd-ZGF6Q6OP.js} +10 -10
- package/dist/{emit-step-cmd-6XTJITZT.js → emit-step-cmd-DUR34STQ.js} +8 -8
- package/dist/{exec-client-CKPK62K2.js → exec-client-S5IA7JRG.js} +4 -4
- package/dist/{governing-source-GWN7GVEN.js → governing-source-DKJABQAT.js} +10 -10
- package/dist/{guest-init-ZBL5CN7Y.js → guest-init-TOSKPGPF.js} +5 -5
- package/dist/{hook-fast-3JL4PXLG.js → hook-fast-NEELST6G.js} +1 -1
- package/dist/host-key-ICJEQBWH.js +9 -0
- package/dist/{image-tag-AO4RBAKW.js → image-tag-6KJOGBQK.js} +4 -4
- package/dist/index.js +4 -4
- package/dist/{init-EQTR7AEF.js → init-NE3VR3EY.js} +24 -22
- package/dist/{init-TSQ3EOQW.js → init-SKOXNJND.js} +24 -22
- package/dist/{init-cmd-AF2MH36A.js → init-cmd-UEDOJ7LG.js} +10 -10
- package/dist/{init-update-SHISHMXV.js → init-update-VKZ4S6HH.js} +8 -8
- package/dist/{install-ORQC26ZE.js → install-MPEJJ7X6.js} +5 -5
- package/dist/{install-cmd-4LA3UJZ4.js → install-cmd-SE6NCTJK.js} +6 -6
- package/dist/job-state-format-WJQGQB6F.js +6 -0
- package/dist/{logs-5EPHIPZB.js → logs-T4ERSOQ4.js} +3 -3
- package/dist/{loop-4WUCS5JP.js → loop-BPVEA5OC.js} +37 -36
- package/dist/{machine-6UNLIPLE.js → machine-G3GICXQN.js} +20 -18
- package/dist/{mcp-serve-cmd-KMWEKM7C.js → mcp-serve-cmd-7M4VLNI4.js} +5 -5
- package/dist/{paths-XY5ADO32.js → paths-2KGM2LZV.js} +3 -3
- package/dist/pending-BGLMTB5Q.js +9 -0
- package/dist/{pidfile-OJ7RP4Q2.js → pidfile-VYBH3IMN.js} +4 -4
- package/dist/{record-BEJB4J7N.js → record-GNOHDJ2O.js} +4 -4
- package/dist/{relay-PSZ4LGMW.js → relay-GFPPD6GF.js} +1 -1
- package/dist/relay-protocol-HELO5SNH.js +6 -0
- package/dist/{runner-env-ZJWJOJKQ.js → runner-env-GUFV544G.js} +6 -6
- package/dist/{runner-identity-2OOUJSFJ.js → runner-identity-J6DXJ6MF.js} +6 -6
- package/dist/{runner-key-WDFBSJRX.js → runner-key-L55O7Y7W.js} +24 -22
- package/dist/{session-sender-X3BBQZMF.js → session-sender-LXTASWBY.js} +11 -11
- package/dist/{spec-cmd-QRF5YXKK.js → spec-cmd-G2JNXKD7.js} +8 -8
- package/dist/{status-ZCAAF6MD.js → status-U6DXOR6C.js} +34 -28
- package/dist/{sync-cmd-UQK3RYAC.js → sync-cmd-VPNS5ITY.js} +10 -10
- package/dist/{watch-MOQ3GQTE.js → watch-ZOCYD2NE.js} +10 -10
- package/dist/{work-claim-cmd-RT343CLA.js → work-claim-cmd-BUMIPJNF.js} +11 -11
- package/dist/{work-cmd-APXSER2D.js → work-cmd-LRAXUOJV.js} +8 -8
- package/dist/{work-comment-cmd-AT5NUYUU.js → work-comment-cmd-4RDIBUYO.js} +8 -8
- package/dist/{work-logs-cmd-Z5DMNEJP.js → work-logs-cmd-YYN2CPJQ.js} +8 -8
- package/dist/{work-open-pr-cmd-ZTS6MJHL.js → work-open-pr-cmd-3MCND2LZ.js} +9 -9
- package/dist/{work-pr-cmd-IWZCC3WH.js → work-pr-cmd-BODEZAXN.js} +8 -8
- package/dist/{work-stop-cmd-DCAWFDZC.js → work-stop-cmd-P7HXVKEG.js} +8 -8
- package/package.json +2 -2
- package/skill-pack/maintained/outerlayer-build/SKILL.md +1 -1
- package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +3 -2
- package/skill-pack/maintained/outerlayer-build/references/review-briefs.md +3 -1
- package/dist/build-OVZIT2G2.js +0 -12
- package/dist/command-DO4TERRT.js +0 -208
- package/dist/host-key-W2DLZGZ7.js +0 -9
- package/dist/pending-35J3ZPLR.js +0 -9
- package/dist/relay-protocol-K7KP2SPI.js +0 -6
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-
|
|
4
|
-
import { MIN_ENGINE_MAJOR } from './chunk-
|
|
5
|
-
import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-
|
|
6
|
-
import { runnerCredentialProblem } from './chunk-
|
|
7
|
-
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-VNGENFOG.js';
|
|
4
|
+
import { MIN_ENGINE_MAJOR } from './chunk-XHXDCYSK.js';
|
|
5
|
+
import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-ZGMQQWCV.js';
|
|
6
|
+
import { runnerCredentialProblem } from './chunk-JWRX5ZTT.js';
|
|
7
|
+
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
|
|
8
8
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
9
9
|
import { dirname } from 'path';
|
|
10
10
|
|
|
@@ -22,7 +22,7 @@ function isolationNote(machine) {
|
|
|
22
22
|
}
|
|
23
23
|
function processRefusal(machine) {
|
|
24
24
|
const reach = reachDockerStep(machine);
|
|
25
|
-
const needs = machine.platform === "darwin" ? "Isolated builds on a Mac run in a Linux VM: run this again with --vm." : reach !== void 0 ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later: ${reach}, then run this again.` : machine.platform === "windows" ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later inside WSL2: install it there, then run this again from a WSL2 shell.` : `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later on Linux or WSL2: install it, then run this again.`;
|
|
25
|
+
const needs = machine.platform === "darwin" ? "Isolated builds on a Mac run in the runner image on Docker Desktop (https://docs.outerlayer.ai/run-the-runner-in-a-container) or in a Linux VM: run this again with --vm." : reach !== void 0 ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later: ${reach}, then run this again.` : machine.platform === "windows" ? `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later inside WSL2: install it there, then run this again from a WSL2 shell.` : `Isolated builds need Docker Engine ${MIN_ENGINE_MAJOR} or later on Linux or WSL2: install it, then run this again.`;
|
|
26
26
|
return `This machine has ${describeMachineDocker(machine)}, so it cannot isolate a build. ${needs} To run builds as processes under this user instead, where a build can read this user's files and the runner's Claude credential, run this again with --allow-process-builds.`;
|
|
27
27
|
}
|
|
28
28
|
function isPlaceholderCommand(command) {
|
|
@@ -130,11 +130,12 @@ function writeRunnerInit(prepared, runnerKey) {
|
|
|
130
130
|
amend: PLACEHOLDER_COMMAND
|
|
131
131
|
},
|
|
132
132
|
...carried,
|
|
133
|
-
...host === void 0 ? {} : { host },
|
|
133
|
+
...host === void 0 ? {} : { name: host },
|
|
134
134
|
// The agent was named on this command line, so its commands win over any the hand-off carried.
|
|
135
135
|
...agent === void 0 ? {} : { commands: { ...AGENT_COMMANDS[agent] } },
|
|
136
136
|
hooks: { provision: hooks, cleanup: hooks }
|
|
137
137
|
};
|
|
138
|
+
if (host !== void 0) delete config.runner.host;
|
|
138
139
|
mkdirSync(dirname(configPath), { recursive: true });
|
|
139
140
|
const stored = credential === void 0 ? void 0 : { variable: credential.variable, path: storeClaudeCredential(configPath, credential) };
|
|
140
141
|
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
@@ -3,7 +3,7 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
import { MAX_ALLOW_HOSTS, allowHostProblem } from './chunk-UXYLWVTQ.js';
|
|
4
4
|
import { parseSize } from './chunk-7RQ73DLO.js';
|
|
5
5
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
|
-
import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-
|
|
6
|
+
import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-2K3TCQHW.js';
|
|
7
7
|
import { existsSync, statSync, accessSync, constants, readFileSync } from 'fs';
|
|
8
8
|
import { hostname } from 'os';
|
|
9
9
|
import { join } from 'path';
|
|
@@ -92,6 +92,7 @@ function runnerVmOf(configPath) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
var RUNNER_KEYS = [
|
|
95
|
+
"name",
|
|
95
96
|
"host",
|
|
96
97
|
"queues",
|
|
97
98
|
"concurrency",
|
|
@@ -212,6 +213,9 @@ function loadRunnerConfig(configPath) {
|
|
|
212
213
|
if (runner.autoUpdate !== void 0 && typeof runner.autoUpdate !== "boolean") {
|
|
213
214
|
fail(configPath, "runner.autoUpdate", "must be true or false");
|
|
214
215
|
}
|
|
216
|
+
if (runner.name !== void 0 && runner.host !== void 0 && runner.name !== runner.host) {
|
|
217
|
+
fail(configPath, "runner.name", `is "${runner.name}" and runner.host is "${runner.host}"; set runner.name only, since runner.host is its earlier name`);
|
|
218
|
+
}
|
|
215
219
|
const queues = runner.queues && runner.queues.length > 0 ? runner.queues : [...RUNNER_QUEUES];
|
|
216
220
|
for (const queue of queues) {
|
|
217
221
|
if (!RUNNER_QUEUES.includes(queue)) {
|
|
@@ -241,7 +245,7 @@ function loadRunnerConfig(configPath) {
|
|
|
241
245
|
appId: config.appId,
|
|
242
246
|
repos: config.repos,
|
|
243
247
|
scrub: config.scrub,
|
|
244
|
-
host: runner.host ?? hostname(),
|
|
248
|
+
host: runner.name ?? runner.host ?? hostname(),
|
|
245
249
|
queues,
|
|
246
250
|
concurrency: runner.concurrency ?? DEFAULT_CONCURRENCY,
|
|
247
251
|
pollSeconds: runner.pollSeconds ?? DEFAULT_POLL_SECONDS,
|
|
@@ -628,7 +628,7 @@ async function missingControlPlane(cwd, sessionId, home, env) {
|
|
|
628
628
|
cleanupEarlierCopies(dirs);
|
|
629
629
|
}
|
|
630
630
|
if (!contextPossiblyGoverned(cwd, home)) return void 0;
|
|
631
|
-
const { governanceOf } = await import('./control-plane-launch-
|
|
631
|
+
const { governanceOf } = await import('./control-plane-launch-ZFT6SI4N.js');
|
|
632
632
|
if (await governanceOf({ cwd, env, home }) !== "governed") return void 0;
|
|
633
633
|
recordMissingContext(dirs, sessionId, home);
|
|
634
634
|
const launcher = `${cliInvocation()} claude`;
|
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, commandLogOffset, execCommandLine, startSender, startHostServices, finishJob, isContainerTracked, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, AttemptLogBook, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, ALREADY_RELEASED } from './chunk-
|
|
4
|
-
import { writePendingUpdate } from './chunk-
|
|
5
|
-
import {
|
|
3
|
+
import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, commandLogOffset, execCommandLine, startSender, startHostServices, finishJob, isContainerTracked, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listUnreadableJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, AttemptLogBook, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, ALREADY_RELEASED, inTeardown } from './chunk-3I44PQ26.js';
|
|
4
|
+
import { writePendingUpdate } from './chunk-XRYUJTAT.js';
|
|
5
|
+
import { JOB_STATE_FORMAT, readsJobState, jobStateFormatOf } from './chunk-ZVB57WI6.js';
|
|
6
|
+
import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-O2WYUIK7.js';
|
|
6
7
|
import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
|
|
7
8
|
import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-YETTWTAY.js';
|
|
8
9
|
import { RUNNER_PROTOCOL } from './chunk-TPKYTORP.js';
|
|
9
|
-
import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-
|
|
10
|
+
import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-VPUNOGXO.js';
|
|
11
|
+
import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, isInLayout, cleanVersions, stagingDir } from './chunk-QMQC6JCO.js';
|
|
10
12
|
import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
|
|
11
|
-
import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, cleanVersions, isInLayout, stagingDir } from './chunk-VV7ZD5LR.js';
|
|
12
13
|
import { RepoFilter } from './chunk-TBT347UY.js';
|
|
13
|
-
import { LEASE_SECONDS, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandExec, measureDisk, setUpRunnerCgroup, createContainerRuntime, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied } from './chunk-
|
|
14
|
-
import {
|
|
15
|
-
import { tagToPull, pullInstruction, imageTag, writeUpdateStatus } from './chunk-IDSHLKQA.js';
|
|
14
|
+
import { LEASE_SECONDS, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandExec, measureDisk, setUpRunnerCgroup, createContainerRuntime, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied } from './chunk-XHXDCYSK.js';
|
|
15
|
+
import { tagToPull, pullInstruction, imageTag, writeUpdateStatus } from './chunk-5222PA6S.js';
|
|
16
16
|
import { isVersion, compareVersions, satisfiesRange } from './chunk-TQMI335S.js';
|
|
17
|
-
import {
|
|
17
|
+
import { checkFit } from './chunk-IGRRD7PX.js';
|
|
18
|
+
import { claimPidFile, readPidFile, releasePidFile } from './chunk-DEBOL6ON.js';
|
|
18
19
|
import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
|
|
19
|
-
import { writeJobFile, ensureRunnerIdentity, readJobFile, builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, spawnRun, BUILD_LABEL, RUNNER_LABEL, readJobFileChecked } from './chunk-
|
|
20
|
-
import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-
|
|
21
|
-
import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-
|
|
22
|
-
import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-
|
|
20
|
+
import { writeJobFile, ensureRunnerIdentity, readJobFile, builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, spawnRun, BUILD_LABEL, RUNNER_LABEL, readJobFileChecked } from './chunk-QUGYGO6L.js';
|
|
21
|
+
import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-YMKQVCKC.js';
|
|
22
|
+
import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-X5LNCIZT.js';
|
|
23
|
+
import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-JWRX5ZTT.js';
|
|
23
24
|
import { exceedsDisk } from './chunk-7RQ73DLO.js';
|
|
24
25
|
import { resolveVersion } from './chunk-RA3O54FC.js';
|
|
25
|
-
import { loadHostKey, ensureHostKey, signerFor } from './chunk-
|
|
26
|
-
import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, RUNNER_FILE_MODE, jobsDir, pidFilePath, spoolDir, rootfsDir } from './chunk-
|
|
27
|
-
import { parseClaimIdentity, parseClaimedRepositories, parseUnreachable, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-
|
|
28
|
-
import { COMMAND_LOST_REASON, CONTAINER_STOPPED_REASON } from './chunk-
|
|
26
|
+
import { loadHostKey, ensureHostKey, signerFor } from './chunk-ZODVSFI4.js';
|
|
27
|
+
import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, RUNNER_FILE_MODE, jobsDir, pidFilePath, spoolDir, rootfsDir } from './chunk-ZI2ZVWKT.js';
|
|
28
|
+
import { parseClaimIdentity, parseClaimedRepositories, parseUnreachable, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-2K3TCQHW.js';
|
|
29
|
+
import { COMMAND_LOST_REASON, CONTAINER_STOPPED_REASON } from './chunk-JGD5TWQ2.js';
|
|
29
30
|
import { randomBytes } from 'crypto';
|
|
30
31
|
import { mkdirSync, existsSync, chmodSync, writeFileSync, renameSync, statSync, readdirSync, readFileSync, rmSync, closeSync, openSync, constants, lstatSync } from 'fs';
|
|
31
32
|
import { join, dirname } from 'path';
|
|
@@ -238,6 +239,61 @@ function writeLastUpdate(configPath, update) {
|
|
|
238
239
|
`, { mode: RUNNER_FILE_MODE });
|
|
239
240
|
renameSync(temporary, path);
|
|
240
241
|
}
|
|
242
|
+
|
|
243
|
+
// src/runner/update/ask-formats.ts
|
|
244
|
+
async function askJobStateFormats(runNode, entry, cwd) {
|
|
245
|
+
let result;
|
|
246
|
+
try {
|
|
247
|
+
result = await runNode([entry, "runner", "job-state-formats"], cwd);
|
|
248
|
+
} catch {
|
|
249
|
+
return void 0;
|
|
250
|
+
}
|
|
251
|
+
if (result.status !== 0) return void 0;
|
|
252
|
+
try {
|
|
253
|
+
const body = JSON.parse(result.stdout);
|
|
254
|
+
if (!Array.isArray(body.reads) || !body.reads.every((n) => Number.isInteger(n))) return void 0;
|
|
255
|
+
return body.reads;
|
|
256
|
+
} catch {
|
|
257
|
+
return void 0;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/runner/update/survives-restart.ts
|
|
262
|
+
function stageReason(job) {
|
|
263
|
+
if (job.stage === "command") return void 0;
|
|
264
|
+
if (!inTeardown(job)) return "is still in setup";
|
|
265
|
+
switch (job.stage) {
|
|
266
|
+
case "judge":
|
|
267
|
+
return "is running the criteria judge";
|
|
268
|
+
case "checks":
|
|
269
|
+
return "is running its checks";
|
|
270
|
+
default:
|
|
271
|
+
return `is finishing (${job.stage})`;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function ownReason({ job, ending }) {
|
|
275
|
+
if (job.microvm !== void 0) return "runs in a microVM, which does not carry on through a restart";
|
|
276
|
+
if (!isContainerTracked(job)) return "is not a container build tracked inside its container";
|
|
277
|
+
if (ending) return "is being ended";
|
|
278
|
+
return stageReason(job);
|
|
279
|
+
}
|
|
280
|
+
function buildBlockers(builds) {
|
|
281
|
+
return builds.flatMap((build) => {
|
|
282
|
+
const reason = ownReason(build);
|
|
283
|
+
return reason === void 0 ? [] : [{ item: build.job.item, reason }];
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function restartBlockers(builds, reads) {
|
|
287
|
+
return builds.flatMap((build) => {
|
|
288
|
+
const reason = ownReason(build);
|
|
289
|
+
if (reason !== void 0) return [{ item: build.job.item, reason }];
|
|
290
|
+
if (reads === void 0) return [{ item: build.job.item, reason: "has job state the new version may not read: it did not say which formats it reads" }];
|
|
291
|
+
if (!readsJobState(build.job, reads)) {
|
|
292
|
+
return [{ item: build.job.item, reason: `has job-state format ${jobStateFormatOf(build.job)}, which the new version does not read` }];
|
|
293
|
+
}
|
|
294
|
+
return [];
|
|
295
|
+
});
|
|
296
|
+
}
|
|
241
297
|
var RELEASE_REPOSITORY = "https://github.com/outerlayerai/outerlayer";
|
|
242
298
|
var RELEASE_WORKFLOW_PATH = ".github/workflows/outerlayer-release.yml";
|
|
243
299
|
var UpdateStepError = class extends Error {
|
|
@@ -411,8 +467,8 @@ async function preflightUpdate(args) {
|
|
|
411
467
|
const failure2 = await earlyFailure(args);
|
|
412
468
|
return failure2 === void 0 ? void 0 : finish(args, failure2);
|
|
413
469
|
}
|
|
414
|
-
async function
|
|
415
|
-
const { configPath,
|
|
470
|
+
async function prepareUpdate(args) {
|
|
471
|
+
const { configPath, version, deps } = args;
|
|
416
472
|
const early = await earlyFailure(args);
|
|
417
473
|
if (early !== void 0) return finish(args, early);
|
|
418
474
|
let verified;
|
|
@@ -424,24 +480,31 @@ async function performUpdate(args) {
|
|
|
424
480
|
if (!verified.ok) return finish(args, { outcome: verified.outcome, reason: verified.reason });
|
|
425
481
|
const staged = await deps.runNode([entryIn(verified.dir), "runner", "check", "--config", configPath], verified.dir);
|
|
426
482
|
if (staged.status !== 0) {
|
|
427
|
-
|
|
428
|
-
rmSync(verified.dir, { recursive: true, force: true });
|
|
429
|
-
} catch {
|
|
430
|
-
}
|
|
483
|
+
removeStaging(verified.dir);
|
|
431
484
|
return finish(args, {
|
|
432
485
|
outcome: "retrying",
|
|
433
486
|
reason: `${version} failed \`runner check\` on this host (exit ${staged.status})`,
|
|
434
487
|
detail: `${version} failed \`runner check\` on this host: ${(staged.stderr.trim() || staged.stdout.trim()).slice(0, 500)}`
|
|
435
488
|
});
|
|
436
489
|
}
|
|
490
|
+
return { kind: "prepared", dir: verified.dir };
|
|
491
|
+
}
|
|
492
|
+
function removeStaging(dir) {
|
|
493
|
+
try {
|
|
494
|
+
rmSync(dir, { recursive: true });
|
|
495
|
+
} catch {
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
function installPrepared(args, stagedDir) {
|
|
499
|
+
const { configPath, own, version } = args;
|
|
437
500
|
try {
|
|
438
501
|
if (version !== own) rmSync(versionDir(configPath, version), { recursive: true, force: true });
|
|
439
|
-
renameSync(
|
|
502
|
+
renameSync(stagedDir, versionDir(configPath, version));
|
|
440
503
|
writeMarker(configPath, { from: own, to: version, starts: 0 });
|
|
441
504
|
switchCurrent(configPath, version);
|
|
442
505
|
} catch (err) {
|
|
443
506
|
try {
|
|
444
|
-
rmSync(
|
|
507
|
+
rmSync(stagedDir, { recursive: true, force: true });
|
|
445
508
|
if (currentVersion(configPath) !== version) removeMarker(configPath);
|
|
446
509
|
} catch {
|
|
447
510
|
}
|
|
@@ -455,6 +518,10 @@ async function performUpdate(args) {
|
|
|
455
518
|
args.log.line(`updating ${own} -> ${version} \xB7 restarting`);
|
|
456
519
|
return { kind: "switched" };
|
|
457
520
|
}
|
|
521
|
+
async function performUpdate(args) {
|
|
522
|
+
const prepared = await prepareUpdate(args);
|
|
523
|
+
return prepared.kind === "prepared" ? installPrepared(args, prepared.dir) : prepared;
|
|
524
|
+
}
|
|
458
525
|
function rollBack(configPath, marker, reason, detail, now, log) {
|
|
459
526
|
try {
|
|
460
527
|
writeLastUpdate(configPath, { from: marker.from, to: marker.to, outcome: "rolled_back", reason, at: isoAt(now) });
|
|
@@ -1242,12 +1309,20 @@ function updateArgsOf(state, update, version) {
|
|
|
1242
1309
|
function dropPendingUpdate(state) {
|
|
1243
1310
|
state.pendingUpdate = void 0;
|
|
1244
1311
|
state.preflightedUpdate = void 0;
|
|
1312
|
+
discardPrepared(state);
|
|
1245
1313
|
clearUpdateWait(state);
|
|
1246
1314
|
}
|
|
1315
|
+
function discardPrepared(state) {
|
|
1316
|
+
if (state.preparedUpdate === void 0) return;
|
|
1317
|
+
removeStaging(state.preparedUpdate.dir);
|
|
1318
|
+
state.preparedUpdate = void 0;
|
|
1319
|
+
}
|
|
1247
1320
|
function clearUpdateWait(state) {
|
|
1248
1321
|
state.updateWait = void 0;
|
|
1249
1322
|
state.updateLogged = void 0;
|
|
1250
1323
|
state.upgradeRefused = false;
|
|
1324
|
+
if (state.installWait !== void 0) return;
|
|
1325
|
+
state.waitsLogged = void 0;
|
|
1251
1326
|
recordPendingUpdate(state, void 0);
|
|
1252
1327
|
}
|
|
1253
1328
|
function recordPendingUpdate(state, record) {
|
|
@@ -1271,7 +1346,7 @@ function runningItems(state) {
|
|
|
1271
1346
|
const numbers = [...state.jobs.values()].map((entry) => Number(entry.job.item)).filter((n) => Number.isFinite(n));
|
|
1272
1347
|
return numbers.sort((a, b) => a - b);
|
|
1273
1348
|
}
|
|
1274
|
-
function holdForUpdate(state, version, mayHold = true) {
|
|
1349
|
+
function holdForUpdate(state, version, mayHold = true, waits = []) {
|
|
1275
1350
|
const log = logOf(state);
|
|
1276
1351
|
const nowMs = nowOf(state).getTime();
|
|
1277
1352
|
const wait = adoptUpdateWait(state, version, nowMs);
|
|
@@ -1286,6 +1361,11 @@ function holdForUpdate(state, version, mayHold = true) {
|
|
|
1286
1361
|
const maxWaitMs = (state.config.update?.maxWaitHours ?? DEFAULT_UPDATE_MAX_WAIT_HOURS) * 60 * 6e4;
|
|
1287
1362
|
const holding = mayHold && (state.upgradeRefused === true || nowMs - wait.sinceMs >= maxWaitMs);
|
|
1288
1363
|
const record = { version, since: new Date(wait.sinceMs).toISOString() };
|
|
1364
|
+
if (waits.length > 0) {
|
|
1365
|
+
record.via = "self-update";
|
|
1366
|
+
record.waits = recordedWaits(waits);
|
|
1367
|
+
}
|
|
1368
|
+
noteWaits(state, version, waits);
|
|
1289
1369
|
if (holding) {
|
|
1290
1370
|
wait.holdSinceMs ??= nowMs;
|
|
1291
1371
|
const builds = runningItems(state);
|
|
@@ -1302,6 +1382,16 @@ function holdForUpdate(state, version, mayHold = true) {
|
|
|
1302
1382
|
recordPendingUpdate(state, record);
|
|
1303
1383
|
return holding;
|
|
1304
1384
|
}
|
|
1385
|
+
function recordedWaits(waits) {
|
|
1386
|
+
return waits.flatMap((wait) => Number.isFinite(Number(wait.item)) ? [{ item: Number(wait.item), reason: wait.reason }] : []);
|
|
1387
|
+
}
|
|
1388
|
+
function noteWaits(state, version, waits) {
|
|
1389
|
+
const phrase = waits.map((wait) => `#${wait.item} ${wait.reason}`).join("; ");
|
|
1390
|
+
const key = waits.length === 0 ? void 0 : `${version}:${phrase}`;
|
|
1391
|
+
if (state.waitsLogged === key) return;
|
|
1392
|
+
state.waitsLogged = key;
|
|
1393
|
+
if (key !== void 0) logOf(state).line(`update to ${version} waits: ${phrase}`);
|
|
1394
|
+
}
|
|
1305
1395
|
function buildsPhrase(builds) {
|
|
1306
1396
|
return builds.length === 0 ? "the running builds" : builds.map((n) => `#${n}`).join(", ");
|
|
1307
1397
|
}
|
|
@@ -1325,7 +1415,7 @@ function installedSwitchOf(state, update) {
|
|
|
1325
1415
|
installed: current !== void 0 && existsSync(entryIn(versionDir(configPath, current)))
|
|
1326
1416
|
});
|
|
1327
1417
|
}
|
|
1328
|
-
function restartOntoInstalled(state) {
|
|
1418
|
+
async function restartOntoInstalled(state) {
|
|
1329
1419
|
const update = state.deps.update;
|
|
1330
1420
|
if (update === void 0) return false;
|
|
1331
1421
|
const configPath = state.config.configPath;
|
|
@@ -1333,6 +1423,8 @@ function restartOntoInstalled(state) {
|
|
|
1333
1423
|
const decision = installedSwitchOf(state, update);
|
|
1334
1424
|
if (decision.kind === "none") {
|
|
1335
1425
|
state.installedSwitch = void 0;
|
|
1426
|
+
state.installedFormats = void 0;
|
|
1427
|
+
state.installWait = void 0;
|
|
1336
1428
|
return false;
|
|
1337
1429
|
}
|
|
1338
1430
|
const said = `${decision.kind}:${decision.to}`;
|
|
@@ -1348,8 +1440,14 @@ function restartOntoInstalled(state) {
|
|
|
1348
1440
|
return false;
|
|
1349
1441
|
}
|
|
1350
1442
|
if (state.jobs.size > 0) {
|
|
1351
|
-
|
|
1352
|
-
|
|
1443
|
+
const waits = await installBlockers(state, update, decision.to);
|
|
1444
|
+
if (waits.length > 0) {
|
|
1445
|
+
if (first) log.line(`${decision.to} is installed \xB7 taking no new work, restarting onto it once ${state.jobs.size} running build(s) finish`);
|
|
1446
|
+
const wait = state.installWait = state.installWait?.version === decision.to ? state.installWait : { version: decision.to, sinceMs: nowOf(state).getTime() };
|
|
1447
|
+
noteWaits(state, decision.to, waits);
|
|
1448
|
+
recordPendingUpdate(state, { version: decision.to, since: new Date(wait.sinceMs).toISOString(), via: "install", waits: recordedWaits(waits) });
|
|
1449
|
+
return true;
|
|
1450
|
+
}
|
|
1353
1451
|
}
|
|
1354
1452
|
try {
|
|
1355
1453
|
writeMarker(configPath, { from: own, to: decision.to, starts: 0 });
|
|
@@ -1360,10 +1458,66 @@ function restartOntoInstalled(state) {
|
|
|
1360
1458
|
(state.exitForUpdate ?? (() => update.exit(RESTART_EXIT_STATUS)))();
|
|
1361
1459
|
return true;
|
|
1362
1460
|
}
|
|
1461
|
+
function runningBuilds(state) {
|
|
1462
|
+
return [...state.jobs.values()].map((active) => ({ job: active.job, ending: active.ending }));
|
|
1463
|
+
}
|
|
1464
|
+
async function installBlockers(state, update, to) {
|
|
1465
|
+
const stage = buildBlockers(runningBuilds(state));
|
|
1466
|
+
if (stage.length > 0) return stage;
|
|
1467
|
+
if (state.installedFormats?.version !== to) {
|
|
1468
|
+
const dir = versionDir(state.config.configPath, to);
|
|
1469
|
+
state.installedFormats = { version: to, reads: await askJobStateFormats(update.runNode, entryIn(dir), dir) };
|
|
1470
|
+
}
|
|
1471
|
+
return restartBlockers(runningBuilds(state), state.installedFormats.reads);
|
|
1472
|
+
}
|
|
1473
|
+
function formatBlocked(builds, reads) {
|
|
1474
|
+
const byStage = new Set(buildBlockers(builds).map((blocker) => blocker.item));
|
|
1475
|
+
return restartBlockers(builds, reads).some((blocker) => !byStage.has(blocker.item));
|
|
1476
|
+
}
|
|
1477
|
+
async function restartNow(state, update, version) {
|
|
1478
|
+
const early = buildBlockers(runningBuilds(state));
|
|
1479
|
+
if (early.length > 0) return { kind: "waiting", waits: early };
|
|
1480
|
+
if (state.preparedUpdate !== void 0 && state.preparedUpdate.version !== version) discardPrepared(state);
|
|
1481
|
+
const args = updateArgsOf(state, update, version);
|
|
1482
|
+
let reads;
|
|
1483
|
+
const declined = state.declinedFormats?.has(version) === true;
|
|
1484
|
+
if (state.preparedUpdate !== void 0) {
|
|
1485
|
+
reads = state.preparedUpdate.reads;
|
|
1486
|
+
} else if (declined && restartBlockers(runningBuilds(state), state.declinedFormats.get(version)).length > 0) {
|
|
1487
|
+
reads = state.declinedFormats.get(version);
|
|
1488
|
+
} else {
|
|
1489
|
+
const prepared = await prepareUpdate(args);
|
|
1490
|
+
if (prepared.kind !== "prepared") {
|
|
1491
|
+
dropPendingUpdate(state);
|
|
1492
|
+
reportUpdateResult(state, version, prepared);
|
|
1493
|
+
return { kind: "failed" };
|
|
1494
|
+
}
|
|
1495
|
+
reads = await askJobStateFormats(update.runNode, entryIn(prepared.dir), prepared.dir);
|
|
1496
|
+
if (formatBlocked(runningBuilds(state), reads)) {
|
|
1497
|
+
removeStaging(prepared.dir);
|
|
1498
|
+
(state.declinedFormats ??= /* @__PURE__ */ new Map()).set(version, reads);
|
|
1499
|
+
} else {
|
|
1500
|
+
state.preparedUpdate = { version, dir: prepared.dir, reads };
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
const waits = restartBlockers(runningBuilds(state), reads);
|
|
1504
|
+
if (waits.length > 0) return { kind: "waiting", waits };
|
|
1505
|
+
const staged = state.preparedUpdate;
|
|
1506
|
+
state.preparedUpdate = void 0;
|
|
1507
|
+
dropPendingUpdate(state);
|
|
1508
|
+
const result = installPrepared(args, staged.dir);
|
|
1509
|
+
if (result.kind === "switched") {
|
|
1510
|
+
(state.exitForUpdate ?? (() => update.exit(RESTART_EXIT_STATUS)))();
|
|
1511
|
+
return { kind: "restarted" };
|
|
1512
|
+
}
|
|
1513
|
+
reportUpdateResult(state, version, result);
|
|
1514
|
+
return { kind: "failed" };
|
|
1515
|
+
}
|
|
1363
1516
|
async function updateWhenIdle(state) {
|
|
1364
1517
|
const update = state.deps.update;
|
|
1365
1518
|
const version = state.pendingUpdate;
|
|
1366
1519
|
if (update === void 0 || version === void 0) {
|
|
1520
|
+
discardPrepared(state);
|
|
1367
1521
|
recordPendingUpdate(state, void 0);
|
|
1368
1522
|
return false;
|
|
1369
1523
|
}
|
|
@@ -1389,6 +1543,12 @@ async function updateWhenIdle(state) {
|
|
|
1389
1543
|
}
|
|
1390
1544
|
state.preflightedUpdate = version;
|
|
1391
1545
|
}
|
|
1546
|
+
if (update.underService === true) {
|
|
1547
|
+
const outcome = await restartNow(state, update, version);
|
|
1548
|
+
if (outcome.kind === "restarted") return true;
|
|
1549
|
+
if (outcome.kind === "failed") return false;
|
|
1550
|
+
return holdForUpdate(state, version, true, outcome.waits);
|
|
1551
|
+
}
|
|
1392
1552
|
return holdForUpdate(state, version);
|
|
1393
1553
|
}
|
|
1394
1554
|
dropPendingUpdate(state);
|
|
@@ -1523,7 +1683,7 @@ async function runTick(state) {
|
|
|
1523
1683
|
state.holdingForUpdate = false;
|
|
1524
1684
|
if (state.draining === true) return;
|
|
1525
1685
|
reloadConfig(state);
|
|
1526
|
-
if (restartOntoInstalled(state)) {
|
|
1686
|
+
if (await restartOntoInstalled(state)) {
|
|
1527
1687
|
state.restarting = true;
|
|
1528
1688
|
return;
|
|
1529
1689
|
}
|
|
@@ -1586,7 +1746,7 @@ var CLAIM_REFUSAL_CODES = new Set(
|
|
|
1586
1746
|
"pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected repository_not_reachable branch_claimed_elsewhere".split(" ")
|
|
1587
1747
|
);
|
|
1588
1748
|
async function tryClaimAndStart(state, item, queue) {
|
|
1589
|
-
const { postJson: postJson2 } = await import('./work-cmd-
|
|
1749
|
+
const { postJson: postJson2 } = await import('./work-cmd-LRAXUOJV.js');
|
|
1590
1750
|
const log = logOf(state);
|
|
1591
1751
|
const hostKey = await loadHostKey(state.config.configPath);
|
|
1592
1752
|
const claim = await retrySend(
|
|
@@ -1646,7 +1806,7 @@ async function tryClaimAndStart(state, item, queue) {
|
|
|
1646
1806
|
}
|
|
1647
1807
|
if (wasExtended(data)) {
|
|
1648
1808
|
log.line(
|
|
1649
|
-
`#${item.number} skipped: the claim extended a live lease under
|
|
1809
|
+
`#${item.number} skipped: the claim extended a live lease under the runner name "${state.config.host}" \xB7 set a distinct runner.name per config file`
|
|
1650
1810
|
);
|
|
1651
1811
|
return { kind: "held" };
|
|
1652
1812
|
}
|
|
@@ -1736,6 +1896,7 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
|
|
|
1736
1896
|
const runnerRoot = runnerDir(state.config.configPath);
|
|
1737
1897
|
const jobFilePath = join(dirPath, "job.json");
|
|
1738
1898
|
let job = {
|
|
1899
|
+
stateFormat: state.deps.jobStateFormat ?? JOB_STATE_FORMAT,
|
|
1739
1900
|
item: item.number,
|
|
1740
1901
|
queue,
|
|
1741
1902
|
claimId,
|
|
@@ -2555,6 +2716,13 @@ async function finishTrackedWhileAway(state, dirPath, job, where) {
|
|
|
2555
2716
|
`recovered job ${finished.queue} #${finished.item} (claim ${shortClaim(finished.claimId)}) as ${outcome}: ${code === void 0 ? `its container ${where === "missing" ? "is gone" : "stopped"} and its volume ${read.readable ? "holds no exit code" : "could not be read"}` : `its command recorded exit ${code}`}`
|
|
2556
2717
|
);
|
|
2557
2718
|
}
|
|
2719
|
+
async function logUnusableHelper(config, runtime, log) {
|
|
2720
|
+
if (!isBuiltinVm(config.hooks.provision)) return;
|
|
2721
|
+
const helper = await runtime.vm.helper.probe();
|
|
2722
|
+
if (helper.ok) return;
|
|
2723
|
+
if (helper.reason === "unsupported") log.line(helper.detail);
|
|
2724
|
+
else if (helper.unreachable === true) log.line(`${helper.detail}, so microVM builds run without the jailer`);
|
|
2725
|
+
}
|
|
2558
2726
|
async function start(configPath, deps = { fetchImpl: fetch }) {
|
|
2559
2727
|
const log = deps.log ??= createRunnerLog(deps.now ?? (() => /* @__PURE__ */ new Date()));
|
|
2560
2728
|
const update = deps.update;
|
|
@@ -2562,7 +2730,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
|
|
|
2562
2730
|
const outcome = await onStartUnderMarker({
|
|
2563
2731
|
configPath,
|
|
2564
2732
|
own: ownVersionOf(deps),
|
|
2565
|
-
check: update.check ? () => update.check(configPath) : async () => (await import('./check-
|
|
2733
|
+
check: update.check ? () => update.check(configPath) : async () => (await import('./check-EPYRTE3R.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
|
|
2566
2734
|
now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
|
|
2567
2735
|
log
|
|
2568
2736
|
});
|
|
@@ -2601,12 +2769,16 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
|
|
|
2601
2769
|
const state = { config, jobs: /* @__PURE__ */ new Map(), deps, configMtimeMs };
|
|
2602
2770
|
log.line(`runner ${config.host} started \xB7 config ${configPath} \xB7 ${describeConfig(config)}`);
|
|
2603
2771
|
const nowMs = () => deps.now ? deps.now().getTime() : Date.now();
|
|
2604
|
-
|
|
2772
|
+
await logUnusableHelper(config, runtimeOf(state), log);
|
|
2773
|
+
const runningMicroVms = await stopOrphanedMicroVms({ jobs: unfinishedJobs(jobsDir(configPath)), runtime: runtimeOf(state), onError: (line) => log.error(line) }).catch((err) => {
|
|
2605
2774
|
log.error(`a microVM an earlier runner left could not be stopped: ${describeCallFailure(err)}`);
|
|
2606
2775
|
return [];
|
|
2607
2776
|
});
|
|
2608
2777
|
for (const buildId of runningMicroVms) log.line(`stopped microVM build ${buildId}, left running by an earlier runner`);
|
|
2609
2778
|
const attemptLogs = attemptLogsOf(state);
|
|
2779
|
+
for (const { job, format } of listUnreadableJobs(jobsDir(configPath))) {
|
|
2780
|
+
log.error(`leaving job ${job.queue} #${job.item} alone: its job-state format ${format} is not one this version reads`);
|
|
2781
|
+
}
|
|
2610
2782
|
for (const { dirPath, job } of listAdoptableJobs(jobsDir(configPath))) {
|
|
2611
2783
|
const adopted = { job, dirPath, lastRenewAtMs: nowMs(), cmd: null, cpuSample: null, ending: false };
|
|
2612
2784
|
state.jobs.set(dirPath, adopted);
|
|
@@ -2843,4 +3015,4 @@ function runnerProcessState(configPath) {
|
|
|
2843
3015
|
return isSameProcess(entry.pid, entry.start) ? { state: "running", pid: entry.pid } : { state: "stale", pid: entry.pid };
|
|
2844
3016
|
}
|
|
2845
3017
|
|
|
2846
|
-
export { RunnerStartError, listJobFiles, probeBuild, probeCredentials, requestStop, runnerProcessState, start, tick, watchTick };
|
|
3018
|
+
export { RunnerStartError, listJobFiles, logUnusableHelper, probeBuild, probeCredentials, requestStop, runnerProcessState, start, tick, watchTick };
|
|
@@ -5,7 +5,7 @@ import { readCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
|
|
|
5
5
|
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
6
6
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
7
7
|
import { resolvePackageVersion } from './chunk-RA3O54FC.js';
|
|
8
|
-
import { signRunnerRequest, signerFor } from './chunk-
|
|
8
|
+
import { signRunnerRequest, signerFor } from './chunk-ZODVSFI4.js';
|
|
9
9
|
|
|
10
10
|
createRequire(import.meta.url);
|
|
11
11
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
|
|
4
4
|
import { readFileSync, mkdirSync, writeFileSync, renameSync } from 'fs';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-
|
|
3
|
+
import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
|
|
4
4
|
import { readlinkSync, realpathSync, mkdirSync, unlinkSync, symlinkSync, renameSync, readFileSync, writeFileSync, rmSync, existsSync, readdirSync } from 'fs';
|
|
5
5
|
import { join, basename, sep, resolve } from 'path';
|
|
6
6
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { RecipeError, BUILDKIT_IMAGE } from './chunk-
|
|
3
|
+
import { RecipeError, BUILDKIT_IMAGE } from './chunk-RGW7ERF3.js';
|
|
4
4
|
import { parseSize } from './chunk-7RQ73DLO.js';
|
|
5
5
|
import { compareVersions } from './chunk-D4AMAEZ7.js';
|
|
6
|
-
import { ensureHostKey } from './chunk-
|
|
7
|
-
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-
|
|
8
|
-
import { CLAUDE_PORT, JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-
|
|
9
|
-
import { JOIN_DIR, RELAY_ID, JOIN_SOCKET, TARGET_GATEWAY, TARGET_CLAUDE, destinationTarget, RELAY_USER } from './chunk-
|
|
6
|
+
import { ensureHostKey } from './chunk-ZODVSFI4.js';
|
|
7
|
+
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-ZI2ZVWKT.js';
|
|
8
|
+
import { CLAUDE_PORT, JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-2K3TCQHW.js';
|
|
9
|
+
import { JOIN_DIR, RELAY_ID, JOIN_SOCKET, TARGET_GATEWAY, TARGET_CLAUDE, destinationTarget, RELAY_USER } from './chunk-JGD5TWQ2.js';
|
|
10
10
|
import { StringDecoder } from 'string_decoder';
|
|
11
11
|
import { spawn } from 'child_process';
|
|
12
12
|
import { existsSync, readFileSync, mkdirSync, createWriteStream, rmSync, chmodSync, writeFileSync, realpathSync, readdirSync, renameSync } from 'fs';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { launcherPath, writeLauncher, LauncherWriteError, pathNotes } from './chunk-
|
|
4
|
-
import { currentVersion, currentLink, isInLayout, packageRootIn, versionDir, switchCurrent, execStartLine } from './chunk-
|
|
3
|
+
import { launcherPath, writeLauncher, LauncherWriteError, pathNotes } from './chunk-ATGHVEU4.js';
|
|
4
|
+
import { currentVersion, currentLink, isInLayout, packageRootIn, versionDir, switchCurrent, execStartLine } from './chunk-QMQC6JCO.js';
|
|
5
5
|
import { compareVersions } from './chunk-TQMI335S.js';
|
|
6
|
-
import { RUNNER_DIR_MODE } from './chunk-
|
|
6
|
+
import { RUNNER_DIR_MODE } from './chunk-ZI2ZVWKT.js';
|
|
7
7
|
import { realpathSync, readFileSync, mkdirSync, rmSync, cpSync, existsSync } from 'fs';
|
|
8
8
|
import { dirname, sep, join } from 'path';
|
|
9
9
|
|
|
@@ -92,7 +92,7 @@ function launcherSummary(launcher) {
|
|
|
92
92
|
}
|
|
93
93
|
function restartNote(result) {
|
|
94
94
|
if (result.previous === void 0 || result.previous === result.version) return void 0;
|
|
95
|
-
return `current moved from ${result.previous} to ${result.version}: a runner its service started
|
|
95
|
+
return `current moved from ${result.previous} to ${result.version}: a runner its service started restarts on ${result.version} at once when its running builds are container builds that carry on through the restart. Otherwise it takes no new work and waits for them to finish. A runner started by hand keeps running until you restart it`;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
export { RunnerDowngradeError, RunnerInstallError, launcherSummary, restartNote, runRunnerInstall };
|
|
@@ -242,12 +242,12 @@ var MICROVM_ARCHES = ["x86_64"];
|
|
|
242
242
|
function firecrackerArch(nodeArch) {
|
|
243
243
|
return nodeArch === "x64" ? "x86_64" : nodeArch === "arm64" ? "aarch64" : nodeArch;
|
|
244
244
|
}
|
|
245
|
-
var FIRECRACKER_VERSION = "1.
|
|
245
|
+
var FIRECRACKER_VERSION = "1.16.2";
|
|
246
246
|
var FIRECRACKER_SHA256 = {
|
|
247
|
-
x86_64: "
|
|
247
|
+
x86_64: "32e3cdcd4081f91fe2b024a266f57dcb3b4e5fec5033e0cb22467ad7f7820bda"
|
|
248
248
|
};
|
|
249
249
|
var FIRECRACKER_BINARY_SHA256 = {
|
|
250
|
-
x86_64: "
|
|
250
|
+
x86_64: "8227875ceda44177a4d501052dae4a2f9d7837362f5399f02cf0748e68418377"
|
|
251
251
|
};
|
|
252
252
|
var GUEST_ASSETS_VERSION = "1";
|
|
253
253
|
var GUEST_ASSETS_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${GUEST_ASSETS_VERSION}`;
|
|
@@ -261,5 +261,16 @@ function guestAssetsPinned(arch) {
|
|
|
261
261
|
const zero = "0".repeat(64);
|
|
262
262
|
return GUEST_KERNEL_SHA256[arch] !== zero && GUEST_HELPER_SHA256[arch] !== zero;
|
|
263
263
|
}
|
|
264
|
+
var JAILER_BINARY_SHA256 = {
|
|
265
|
+
x86_64: "99832d2270741af67ffacd46da716b4b016338541af5a742907ab965b2e9ac9e"
|
|
266
|
+
};
|
|
267
|
+
var HOST_HELPER_ASSETS_VERSION = "2";
|
|
268
|
+
var HOST_HELPER_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${HOST_HELPER_ASSETS_VERSION}`;
|
|
269
|
+
var HOST_HELPER_SHA256 = {
|
|
270
|
+
x86_64: "0000000000000000000000000000000000000000000000000000000000000000"
|
|
271
|
+
};
|
|
272
|
+
function hostHelperPinned(arch = "x86_64", hashes = HOST_HELPER_SHA256) {
|
|
273
|
+
return hashes[arch] !== "0".repeat(64);
|
|
274
|
+
}
|
|
264
275
|
|
|
265
|
-
export { BUILDKIT_IMAGE, CLAUDE_CODE_VERSION, DEFAULT_BASE_IMAGE, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, FIRECRACKER_VERSION, GH_SHA256, GH_VERSION, GUEST_ASSETS_BASE_URL, GUEST_ASSETS_VERSION, GUEST_HELPER_SHA256, GUEST_KERNEL_SHA256, MICROVM_ARCHES, NODE_IMAGE, RecipeError, SANITIZED_NAME, TINI_SHA256, TINI_VERSION, assertBuildable, classifyProperties, firecrackerArch, guestAssetsPinned, locateRecipe, readRecipe, writeSanitizedRecipe };
|
|
276
|
+
export { BUILDKIT_IMAGE, CLAUDE_CODE_VERSION, DEFAULT_BASE_IMAGE, DOCKER_FEATURE, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, FIRECRACKER_VERSION, GH_SHA256, GH_VERSION, GUEST_ASSETS_BASE_URL, GUEST_ASSETS_VERSION, GUEST_HELPER_SHA256, GUEST_KERNEL_SHA256, HOST_HELPER_ASSETS_VERSION, HOST_HELPER_BASE_URL, HOST_HELPER_SHA256, JAILER_BINARY_SHA256, MICROVM_ARCHES, NODE_IMAGE, RecipeError, SANITIZED_NAME, TINI_SHA256, TINI_VERSION, assertBuildable, classifyProperties, firecrackerArch, guestAssetsPinned, hostHelperPinned, locateRecipe, readRecipe, writeSanitizedRecipe };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { RELAY_PORT, BUILD_HOME } from './chunk-
|
|
3
|
+
import { RELAY_PORT, BUILD_HOME } from './chunk-2K3TCQHW.js';
|
|
4
4
|
import { createServer, connect } from 'net';
|
|
5
5
|
|
|
6
6
|
createRequire(import.meta.url);
|