@outerlayer/cli 0.7.0 → 0.8.1
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 +30 -0
- package/README.md +5 -5
- package/dist/{agent-setup-TXLDY5RV.js → agent-setup-K6RD2Z4P.js} +4 -4
- package/dist/{build-JF5UOWKJ.js → build-MS34XEGN.js} +2 -1
- package/dist/build-info.json +1 -1
- package/dist/builder-IG6FNA54.js +13 -0
- package/dist/{check-ASZL5BEO.js → check-GX5ND6RO.js} +26 -22
- package/dist/chunk-2BRSMBBB.js +264 -0
- package/dist/{chunk-PUN7LMNS.js → chunk-4ACZCY4I.js} +2 -2
- package/dist/{chunk-2VO25HHO.js → chunk-4FPWKV7L.js} +3 -3
- package/dist/{chunk-AII7CKTH.js → chunk-5ODHQP6O.js} +68 -145
- package/dist/chunk-7RQ73DLO.js +23 -0
- package/dist/{chunk-7FTNIAHS.js → chunk-AX23QKHS.js} +7 -3
- package/dist/{chunk-6ZZHWY2Z.js → chunk-BF4KKEFY.js} +4 -4
- package/dist/{chunk-5FWNEQNZ.js → chunk-BQFNZOMQ.js} +1 -1
- package/dist/chunk-CX22S5BA.js +45 -0
- package/dist/{chunk-D6FXM5OW.js → chunk-GAYWY4GI.js} +8 -8
- package/dist/{chunk-MQPRB5K7.js → chunk-HSN5QNS5.js} +8 -8
- package/dist/chunk-I2UOAV7X.js +133 -0
- package/dist/chunk-I7CJIRMM.js +93 -0
- package/dist/{chunk-SSU747O6.js → chunk-ILEA3YHM.js} +1 -1
- package/dist/{chunk-OUUINEYB.js → chunk-JKIWMRFH.js} +1 -1
- package/dist/{chunk-JPR2WHHF.js → chunk-KSLNQOOS.js} +1 -1
- package/dist/{chunk-DGAIVMMN.js → chunk-KV47VQJZ.js} +5 -5
- package/dist/{chunk-E4PIFIC3.js → chunk-M4ERCYDB.js} +133 -159
- package/dist/chunk-PTW6W5NR.js +127 -0
- package/dist/{chunk-DTXOJDEH.js → chunk-PWBILI5P.js} +3 -2
- package/dist/{chunk-X2FSFU4C.js → chunk-PXFEYBDE.js} +3 -3
- package/dist/{chunk-6IYLDODX.js → chunk-Q4432IZT.js} +5 -5
- package/dist/{chunk-AJKEHABI.js → chunk-QB5JQH5V.js} +255 -54
- package/dist/{chunk-AQ54MKSQ.js → chunk-QNRSFEGY.js} +2 -2
- package/dist/{chunk-774HEQL6.js → chunk-TEKZRTM3.js} +91 -8
- package/dist/{chunk-CEBIA5FD.js → chunk-TTNFGMHO.js} +42 -50
- package/dist/{chunk-F6GFZXZ3.js → chunk-UXYLWVTQ.js} +1 -18
- package/dist/{chunk-M5POMKKW.js → chunk-V7NIVOFD.js} +5 -5
- package/dist/{chunk-BCLJSQCV.js → chunk-YO4PSLVB.js} +1 -1
- package/dist/{chunk-6QWV3YDJ.js → chunk-Z2THOHPP.js} +2 -2
- package/dist/{cli-LEVCGAQV.js → cli-X5ONGYNY.js} +128 -78
- package/dist/{command-FLSYCGIB.js → command-7NFU3IPO.js} +38 -20
- package/dist/{config-I3TVFYLH.js → config-Z3USDBLU.js} +3 -2
- package/dist/{connect-cmd-MJMUONDY.js → connect-cmd-PNZ6IJLJ.js} +2 -2
- package/dist/{context-adopt-CE4KDXS3.js → context-adopt-D2Z7F7PB.js} +3 -3
- package/dist/{context-materialize-QL33HDJN.js → context-materialize-4PMTDS6K.js} +3 -3
- package/dist/{dist-PXBSA7QX.js → dist-3ZTZF2TP.js} +1 -1
- package/dist/docker-PRHRSJM5.js +15 -0
- package/dist/{doctor-FVDT3KJZ.js → doctor-KALLPCRB.js} +39 -16
- package/dist/{emit-artifact-cmd-7RPMRSVP.js → emit-artifact-cmd-D5GMVWNC.js} +7 -7
- package/dist/{emit-criteria-cmd-MKI7WETO.js → emit-criteria-cmd-IE7VIM64.js} +5 -5
- package/dist/{emit-finding-cmd-RMLGZASB.js → emit-finding-cmd-46PTPN3A.js} +5 -5
- package/dist/{emit-result-cmd-MTXAZ2GV.js → emit-result-cmd-KXHHP6HX.js} +7 -7
- package/dist/{hook-fast-XBOZ3N6L.js → hook-fast-5H5QBJKT.js} +1 -1
- package/dist/{host-key-KDYZ5ECC.js → host-key-YMLXY6QB.js} +1 -1
- package/dist/index.js +3 -3
- package/dist/{init-VLW7H6RW.js → init-B4CECVOX.js} +25 -18
- package/dist/{init-BACXESVV.js → init-S4DH6PWW.js} +16 -13
- package/dist/{init-cmd-VJFB5L7X.js → init-cmd-P4MVCBCZ.js} +8 -8
- package/dist/{install-NMAPLLBQ.js → install-FHTVJZS6.js} +5 -4
- package/dist/{install-cmd-B5SEU3G7.js → install-cmd-BEC7XTNG.js} +3 -1
- package/dist/{loop-D3243JKT.js → loop-ODMRE3CW.js} +26 -22
- package/dist/{machine-EB3GEVI4.js → machine-J4SAB3Z2.js} +15 -12
- package/dist/{mcp-serve-cmd-N6UD2KBX.js → mcp-serve-cmd-CT47P4YQ.js} +2 -2
- package/dist/{session-sender-LMACEJJS.js → session-sender-V46VPWQ5.js} +6 -6
- package/dist/{status-F4THTJJK.js → status-QBKSH3QE.js} +19 -16
- package/dist/{sync-cmd-M6JA3OEE.js → sync-cmd-RJR77V4O.js} +5 -5
- package/dist/{watch-NB5TGPEZ.js → watch-YNZTFLEY.js} +5 -5
- package/dist/{work-claim-cmd-UHMWOS3G.js → work-claim-cmd-KAD3ZAH7.js} +10 -9
- package/dist/{work-cmd-6UMCFTAW.js → work-cmd-CNWPTH7W.js} +6 -6
- package/dist/{work-comment-cmd-E4LEUIXZ.js → work-comment-cmd-HH45S6UE.js} +6 -6
- package/dist/{work-open-pr-cmd-OPZWGSEQ.js → work-open-pr-cmd-5KR3KFCN.js} +7 -7
- package/dist/{work-pr-cmd-IDIAFFRU.js → work-pr-cmd-TTEGCP76.js} +6 -6
- package/package.json +2 -2
- package/skill-pack/maintained/amend/SKILL.md +22 -6
- package/dist/chunk-Q5G2ODUZ.js +0 -54
- package/dist/docker-NEGDLU6D.js +0 -7
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { RecipeError } from './chunk-QOZKPLVJ.js';
|
|
4
|
+
import { trackImageBuild, isOutOfMemory, ensureBuilder } from './chunk-2BRSMBBB.js';
|
|
4
5
|
import { spawn } from 'child_process';
|
|
5
|
-
import { existsSync, mkdirSync, createWriteStream, readFileSync } from 'fs';
|
|
6
|
+
import { existsSync, mkdirSync, createWriteStream, rmSync, readFileSync } from 'fs';
|
|
6
7
|
import { join, dirname } from 'path';
|
|
7
8
|
import { createRequire as createRequire$1 } from 'module';
|
|
8
9
|
import { fileURLToPath } from 'url';
|
|
@@ -48,7 +49,9 @@ function devcontainerBuildInvocation(cli, req) {
|
|
|
48
49
|
req.imageName,
|
|
49
50
|
...Object.entries(req.labels).flatMap(([key, value]) => ["--label", `${key}=${value}`]),
|
|
50
51
|
"--log-format",
|
|
51
|
-
"text"
|
|
52
|
+
"text",
|
|
53
|
+
// Written as an OCI layout instead of loaded into Docker: the runner's builder cannot read Docker's image store, so the next layer starts FROM the layout.
|
|
54
|
+
...req.layoutOut === void 0 ? [] : ["--output", `type=oci,dest=${req.layoutOut},tar=false`]
|
|
52
55
|
]
|
|
53
56
|
};
|
|
54
57
|
}
|
|
@@ -69,6 +72,14 @@ var CHILD_ENVIRONMENT_NAMES = [
|
|
|
69
72
|
"DOCKER_TLS_VERIFY",
|
|
70
73
|
"DOCKER_API_VERSION",
|
|
71
74
|
"DOCKER_BUILDKIT",
|
|
75
|
+
// `docker buildx build` fetches registry tokens in the client and hands them to the builder, so a host that reaches
|
|
76
|
+
// registries through a proxy needs it here as well as in the builder.
|
|
77
|
+
"HTTP_PROXY",
|
|
78
|
+
"HTTPS_PROXY",
|
|
79
|
+
"NO_PROXY",
|
|
80
|
+
"http_proxy",
|
|
81
|
+
"https_proxy",
|
|
82
|
+
"no_proxy",
|
|
72
83
|
"XDG_RUNTIME_DIR",
|
|
73
84
|
"XDG_CONFIG_HOME",
|
|
74
85
|
"XDG_DATA_HOME",
|
|
@@ -103,6 +114,7 @@ var spawnRun = (command, args, opts = {}) => new Promise((resolve) => {
|
|
|
103
114
|
if (extra) log.write(extra);
|
|
104
115
|
log.end(() => resolve(result));
|
|
105
116
|
};
|
|
117
|
+
let timer;
|
|
106
118
|
const child = spawn(command, args, {
|
|
107
119
|
env: { ...childEnvironment(process.env), ...opts.env },
|
|
108
120
|
stdio: [opts.input === void 0 ? "ignore" : "pipe", "pipe", "pipe"]
|
|
@@ -115,9 +127,20 @@ var spawnRun = (command, args, opts = {}) => new Promise((resolve) => {
|
|
|
115
127
|
stderr += chunk.toString();
|
|
116
128
|
log?.write(chunk);
|
|
117
129
|
});
|
|
130
|
+
if (opts.timeoutMs !== void 0) {
|
|
131
|
+
timer = setTimeout(() => {
|
|
132
|
+
child.kill("SIGKILL");
|
|
133
|
+
finish(124, `${command}: no answer within ${Math.round(opts.timeoutMs / 1e3)}s
|
|
134
|
+
`);
|
|
135
|
+
}, opts.timeoutMs);
|
|
136
|
+
timer.unref();
|
|
137
|
+
}
|
|
118
138
|
child.on("error", (err) => finish(127, `${command}: ${err.message}
|
|
119
139
|
`));
|
|
120
|
-
child.on("close", (code, signal) =>
|
|
140
|
+
child.on("close", (code, signal) => {
|
|
141
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
142
|
+
finish(code ?? (signal ? 128 : 1));
|
|
143
|
+
});
|
|
121
144
|
if (opts.input !== void 0) {
|
|
122
145
|
child.stdin.on("error", () => void 0);
|
|
123
146
|
child.stdin.end(opts.input);
|
|
@@ -127,9 +150,28 @@ function toInfo(row) {
|
|
|
127
150
|
return { id: row.Id, createdAt: row.Created, labels: row.Config?.Labels ?? {} };
|
|
128
151
|
}
|
|
129
152
|
var lines = (text) => [...new Set(text.split("\n").map((l) => l.trim()).filter(Boolean))];
|
|
153
|
+
function layoutDigest(layout) {
|
|
154
|
+
const index = JSON.parse(readFileSync(join(layout, "index.json"), "utf8"));
|
|
155
|
+
const digest = index.manifests?.[0]?.digest;
|
|
156
|
+
if (digest === void 0) throw new Error(`${join(layout, "index.json")} lists no image`);
|
|
157
|
+
return digest;
|
|
158
|
+
}
|
|
159
|
+
function outOfMemory(builder, logPath) {
|
|
160
|
+
return new RecipeError(
|
|
161
|
+
"image_build_out_of_memory",
|
|
162
|
+
`the image build ran out of memory: the kernel stopped a build step at the limit of runner.build.memory (${builder.memory}). Raise runner.build.memory, or lower what the recipe's build steps use; the build log is at ${logPath}`,
|
|
163
|
+
logPath
|
|
164
|
+
);
|
|
165
|
+
}
|
|
130
166
|
function createDockerHost(deps = {}) {
|
|
131
167
|
const run = deps.run ?? spawnRun;
|
|
132
168
|
const cli = deps.cli ?? resolveDevcontainerCli;
|
|
169
|
+
const builderFor = () => {
|
|
170
|
+
if (deps.builder === void 0) {
|
|
171
|
+
throw new Error("no image builder is configured, so the image build was not started: every image build runs in the runner's builder, which carries runner.build.memory");
|
|
172
|
+
}
|
|
173
|
+
return deps.builder;
|
|
174
|
+
};
|
|
133
175
|
const inspectMany = async (refs) => {
|
|
134
176
|
const result = await run("docker", ["image", "inspect", ...refs]);
|
|
135
177
|
return result.status === 0 ? JSON.parse(result.stdout).map(toInfo) : [];
|
|
@@ -156,17 +198,58 @@ function createDockerHost(deps = {}) {
|
|
|
156
198
|
if (containers.length === 0) return [];
|
|
157
199
|
return lines((await run("docker", ["inspect", "--format", "{{.Image}}", ...containers])).stdout);
|
|
158
200
|
},
|
|
201
|
+
async ensureBuilder() {
|
|
202
|
+
const builder = builderFor();
|
|
203
|
+
const result = await ensureBuilder(run, builder, { waitForIdle: true, replaceStale: deps.replaceStaleBuilder });
|
|
204
|
+
if (!result.ok) throw new RecipeError("image_builder_unavailable", `the image builder is unavailable: ${result.problem}`);
|
|
205
|
+
return { name: builder.name, memory: builder.memory };
|
|
206
|
+
},
|
|
207
|
+
async exportLayout(ref, dir) {
|
|
208
|
+
rmSync(dir, { recursive: true, force: true });
|
|
209
|
+
mkdirSync(dir, { recursive: true });
|
|
210
|
+
const archive = join(dir, ".image.tar");
|
|
211
|
+
const saved = await run("docker", ["save", "--output", archive, ref]);
|
|
212
|
+
if (saved.status !== 0) throw new Error(saved.stderr.trim() || `docker save ${ref} exited ${saved.status}`);
|
|
213
|
+
const unpacked = await run("tar", ["-xf", archive, "-C", dir]);
|
|
214
|
+
rmSync(archive, { force: true });
|
|
215
|
+
if (unpacked.status !== 0) throw new Error(unpacked.stderr.trim() || `tar exited ${unpacked.status}`);
|
|
216
|
+
},
|
|
159
217
|
async buildDockerfile(req) {
|
|
218
|
+
const builder = builderFor();
|
|
219
|
+
if (req.layoutOut !== void 0) {
|
|
220
|
+
rmSync(req.layoutOut, { recursive: true, force: true });
|
|
221
|
+
}
|
|
160
222
|
const labels = Object.entries(req.labels).flatMap(([key, value]) => ["--label", `${key}=${value}`]);
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
223
|
+
const args = [
|
|
224
|
+
"buildx",
|
|
225
|
+
"build",
|
|
226
|
+
"--builder",
|
|
227
|
+
builder.name,
|
|
228
|
+
"--load",
|
|
229
|
+
...req.layoutOut === void 0 ? [] : ["--output", `type=oci,dest=${req.layoutOut},tar=false`],
|
|
230
|
+
...req.base === void 0 ? [] : ["--build-context", `${req.base.ref}=oci-layout://${req.base.layout}@${layoutDigest(req.base.layout)}`],
|
|
231
|
+
"--tag",
|
|
232
|
+
req.tag,
|
|
233
|
+
...labels,
|
|
234
|
+
"--file",
|
|
235
|
+
"-",
|
|
236
|
+
req.context
|
|
237
|
+
];
|
|
238
|
+
const result = await trackImageBuild(() => run("docker", args, { logPath: req.logPath, input: req.dockerfile }));
|
|
239
|
+
if (result.status !== 0 && isOutOfMemory(`${result.stdout}
|
|
240
|
+
${result.stderr}`)) throw outOfMemory(builder, req.logPath);
|
|
165
241
|
return result.status;
|
|
166
242
|
},
|
|
167
243
|
async devcontainerBuild(req) {
|
|
244
|
+
const builder = builderFor();
|
|
168
245
|
const { command, args } = devcontainerBuildInvocation(cli(), req);
|
|
169
|
-
|
|
246
|
+
if (req.layoutOut !== void 0) {
|
|
247
|
+
rmSync(req.layoutOut, { recursive: true, force: true });
|
|
248
|
+
}
|
|
249
|
+
const result = await trackImageBuild(() => run(command, args, { logPath: req.logPath, env: { BUILDX_BUILDER: builder.name } }));
|
|
250
|
+
if (result.status !== 0 && isOutOfMemory(`${result.stdout}
|
|
251
|
+
${result.stderr}`)) throw outOfMemory(builder, req.logPath);
|
|
252
|
+
return result.status;
|
|
170
253
|
},
|
|
171
254
|
async remove(id) {
|
|
172
255
|
const result = await run("docker", ["rmi", id]);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { startTimeOf, claimPidFile, RunnerAlreadyRunningError, releasePidFile } from './chunk-N5FOE5PS.js';
|
|
4
4
|
import { RecipeError, locateRecipe, readRecipe, assertBuildable, writeSanitizedRecipe, classifyProperties, SANITIZED_NAME } from './chunk-QOZKPLVJ.js';
|
|
5
|
+
import { CLAUDE_CODE_VERSION, NODE_IMAGE, DEFAULT_BASE_IMAGE, TINI_VERSION, GH_VERSION, GH_SHA256, TINI_SHA256 } from './chunk-CX22S5BA.js';
|
|
5
6
|
import { withGitConfig } from './chunk-HKMPVPO7.js';
|
|
6
7
|
import { RUNNER_DIR_MODE, repoCacheDir, imagesDir, attemptStamp, runnerDir, rootfsPathFor, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
|
|
7
8
|
import { mkdirSync, rmSync, existsSync, mkdtempSync, cpSync, readFileSync, writeFileSync, readdirSync, lstatSync, readlinkSync } from 'fs';
|
|
@@ -123,44 +124,6 @@ async function cloneRepository(remote, dest, timeoutMs = CLONE_TIMEOUT_MS) {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
// src/runner/image/pins.ts
|
|
127
|
-
var CLAUDE_CODE_VERSION = "2.1.284";
|
|
128
|
-
var DEFAULT_BASE_IMAGE = "ubuntu:24.04@sha256:008173c23f95b170204355c12626cb5a965d779a7e1283b09e9cffbb1bf33ca3";
|
|
129
|
-
var NODE_IMAGE = "node:22-bookworm-slim@sha256:43ac6c60b8f89723f746e8a92ce91abd5017e627ce1ddfe4238355d3a30b772c";
|
|
130
|
-
var GH_VERSION = "2.101.0";
|
|
131
|
-
var GH_SHA256 = {
|
|
132
|
-
amd64: "9bca2d1c16825f109907a23307628a2f0698fbf99662b73a5cf0b020293072b8",
|
|
133
|
-
arm64: "b57e8063f18862647c9d22727c32e9da1b963f8bf9db648fe123a6975695640f"
|
|
134
|
-
};
|
|
135
|
-
var TINI_VERSION = "0.19.0";
|
|
136
|
-
var TINI_SHA256 = {
|
|
137
|
-
amd64: "c5b0666b4cb676901f90dfcb37106783c5fe2077b04590973b885950611b30ee",
|
|
138
|
-
arm64: "eae1d3aa50c48fb23b8cbdf4e369d0910dfc538566bfd09df89a774aa84a48b9"
|
|
139
|
-
};
|
|
140
|
-
var MICROVM_ARCHES = ["x86_64"];
|
|
141
|
-
function firecrackerArch(nodeArch) {
|
|
142
|
-
return nodeArch === "x64" ? "x86_64" : nodeArch === "arm64" ? "aarch64" : nodeArch;
|
|
143
|
-
}
|
|
144
|
-
var FIRECRACKER_VERSION = "1.13.1";
|
|
145
|
-
var FIRECRACKER_SHA256 = {
|
|
146
|
-
x86_64: "59450b9171ff2ebdf2f9a25be3a248a7ba79fb6371aec51a9d6d8eefca7b4faf"
|
|
147
|
-
};
|
|
148
|
-
var FIRECRACKER_BINARY_SHA256 = {
|
|
149
|
-
x86_64: "7d3924e0c8761edafbf85cb2a94c268ffad249644a40fd02d4e15cde4c206f6e"
|
|
150
|
-
};
|
|
151
|
-
var GUEST_ASSETS_VERSION = "1";
|
|
152
|
-
var GUEST_ASSETS_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${GUEST_ASSETS_VERSION}`;
|
|
153
|
-
var GUEST_KERNEL_SHA256 = {
|
|
154
|
-
x86_64: "5a2d716d301615c69fefc2f9574954e838269f14d5e8b0d1bad88b680cd372ee"
|
|
155
|
-
};
|
|
156
|
-
var GUEST_HELPER_SHA256 = {
|
|
157
|
-
x86_64: "4175e89ae8cb633113b5f69ef8b6e206093954411fe53edf86357bc1b7e822f9"
|
|
158
|
-
};
|
|
159
|
-
function guestAssetsPinned(arch) {
|
|
160
|
-
const zero = "0".repeat(64);
|
|
161
|
-
return GUEST_KERNEL_SHA256[arch] !== zero && GUEST_HELPER_SHA256[arch] !== zero;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
127
|
// src/runner/image/dockerfiles.ts
|
|
165
128
|
function plain(name, value, allowed) {
|
|
166
129
|
if (!allowed.test(value)) throw new Error(`${name} holds a character a Dockerfile line cannot carry safely: ${JSON.stringify(value)}`);
|
|
@@ -307,6 +270,7 @@ var KEEP_BUILD_IMAGES = 3;
|
|
|
307
270
|
var TAG_HOST = "outerlayer.invalid";
|
|
308
271
|
var KEY_PREFIX = 12;
|
|
309
272
|
var LOCK_NAME = "build.lock";
|
|
273
|
+
var LAYOUTS_DIR = "layouts";
|
|
310
274
|
function splitRepository(repository) {
|
|
311
275
|
const full = repository.toLowerCase();
|
|
312
276
|
const parts = full.split("/");
|
|
@@ -388,33 +352,56 @@ async function buildRepositoryImage(opts, ports) {
|
|
|
388
352
|
(i) => i.labels[KIND2] === "build" && i.labels[RECIPE_KEY2] === rKey && i.labels[TOOLS_KEY] === tKey
|
|
389
353
|
);
|
|
390
354
|
const failed = (what, status) => new RecipeError("build_failed", `${what} failed (exit ${status}); the build log is at ${logPath}`, logPath);
|
|
355
|
+
let builderReady = false;
|
|
356
|
+
const ensureBuilder = async () => {
|
|
357
|
+
if (builderReady) return;
|
|
358
|
+
const builder = await host.ensureBuilder();
|
|
359
|
+
opts.log?.(`image build in builder ${builder.name} at ${builder.memory}`);
|
|
360
|
+
builderReady = true;
|
|
361
|
+
};
|
|
362
|
+
const keptLayout = join(repoRecords, LAYOUTS_DIR, rKey.slice(0, KEY_PREFIX));
|
|
363
|
+
const layoutKept = () => existsSync(join(keptLayout, "index.json"));
|
|
391
364
|
let recipeImage = recipeImageBefore;
|
|
392
365
|
let recipeBuilt = false;
|
|
393
366
|
if (recipeImage === void 0 && buildImageBefore === void 0) {
|
|
367
|
+
await ensureBuilder();
|
|
368
|
+
mkdirSync(join(repoRecords, LAYOUTS_DIR), { recursive: true, mode: RUNNER_DIR_MODE });
|
|
394
369
|
const labels = { [REPOSITORY]: repository, [KIND2]: "recipe", [RECIPE_KEY2]: rKey };
|
|
395
370
|
if (location.kind === "default") {
|
|
396
371
|
const context = mkdtempSync(join(scratchRoot, "ol-image-default-"));
|
|
397
372
|
try {
|
|
398
|
-
const status = await host.buildDockerfile({ dockerfile: defaultText, context, tag: recipeTag, labels, logPath });
|
|
373
|
+
const status = await host.buildDockerfile({ dockerfile: defaultText, context, tag: recipeTag, labels, logPath, layoutOut: keptLayout });
|
|
399
374
|
if (status !== 0) throw failed("the docker build of the default image", status);
|
|
400
375
|
} finally {
|
|
401
376
|
rmSync(context, { recursive: true, force: true });
|
|
402
377
|
}
|
|
403
378
|
} else {
|
|
404
379
|
const config = writeSanitizedRecipe(checkout.dir, location, recipe);
|
|
380
|
+
const scratchLayouts = mkdtempSync(join(scratchRoot, "ol-image-layout-"));
|
|
381
|
+
const scratchLayout = join(scratchLayouts, "layout");
|
|
405
382
|
try {
|
|
406
|
-
const status = await host.devcontainerBuild({ workspace: checkout.dir, config, imageName: recipeTag, labels, logPath });
|
|
383
|
+
const status = await host.devcontainerBuild({ workspace: checkout.dir, config, imageName: recipeTag, labels, logPath, layoutOut: scratchLayout });
|
|
407
384
|
if (status !== 0) throw failed("devcontainer build", status);
|
|
385
|
+
if (!existsSync(join(scratchLayout, "index.json"))) throw failed("devcontainer build, which left no image to label,", 0);
|
|
386
|
+
const context = mkdtempSync(join(scratchRoot, "ol-image-label-"));
|
|
387
|
+
try {
|
|
388
|
+
const relabel = await host.buildDockerfile({
|
|
389
|
+
dockerfile: `FROM ${recipeTag}
|
|
390
|
+
`,
|
|
391
|
+
context,
|
|
392
|
+
tag: recipeTag,
|
|
393
|
+
labels,
|
|
394
|
+
logPath,
|
|
395
|
+
base: { ref: recipeTag, layout: scratchLayout },
|
|
396
|
+
layoutOut: keptLayout
|
|
397
|
+
});
|
|
398
|
+
if (relabel !== 0) throw failed("labelling the recipe image", relabel);
|
|
399
|
+
} finally {
|
|
400
|
+
rmSync(context, { recursive: true, force: true });
|
|
401
|
+
}
|
|
408
402
|
} finally {
|
|
409
403
|
rmSync(config, { force: true });
|
|
410
|
-
|
|
411
|
-
const context = mkdtempSync(join(scratchRoot, "ol-image-label-"));
|
|
412
|
-
try {
|
|
413
|
-
const status = await host.buildDockerfile({ dockerfile: `FROM ${recipeTag}
|
|
414
|
-
`, context, tag: recipeTag, labels, logPath });
|
|
415
|
-
if (status !== 0) throw failed("labelling the recipe image", status);
|
|
416
|
-
} finally {
|
|
417
|
-
rmSync(context, { recursive: true, force: true });
|
|
404
|
+
rmSync(scratchLayouts, { recursive: true, force: true });
|
|
418
405
|
}
|
|
419
406
|
}
|
|
420
407
|
recipeImage = await host.inspect(recipeTag) ?? void 0;
|
|
@@ -423,6 +410,8 @@ async function buildRepositoryImage(opts, ports) {
|
|
|
423
410
|
}
|
|
424
411
|
let buildImage = buildImageBefore;
|
|
425
412
|
if (buildImage === void 0) {
|
|
413
|
+
await ensureBuilder();
|
|
414
|
+
if (!layoutKept()) await host.exportLayout(recipeTag, keptLayout);
|
|
426
415
|
const context = mkdtempSync(join(scratchRoot, "ol-image-tools-"));
|
|
427
416
|
try {
|
|
428
417
|
cpSync(opts.cli.distDir, join(context, "dist"), { recursive: true });
|
|
@@ -433,7 +422,7 @@ async function buildRepositoryImage(opts, ports) {
|
|
|
433
422
|
}
|
|
434
423
|
const dockerfile = toolsDockerfile({ recipeImage: recipeTag, nodeImage, claudeCodeVersion, buildId: opts.cli.buildId, guestHelper: opts.guestHelper !== void 0 });
|
|
435
424
|
const labels = { [REPOSITORY]: repository, [KIND2]: "build", [RECIPE_KEY2]: rKey, [TOOLS_KEY]: tKey };
|
|
436
|
-
const status = await host.buildDockerfile({ dockerfile, context, tag: buildTag, labels, logPath });
|
|
425
|
+
const status = await host.buildDockerfile({ dockerfile, context, tag: buildTag, labels, logPath, base: { ref: recipeTag, layout: keptLayout } });
|
|
437
426
|
if (status !== 0) throw failed("the docker build of the tools layer", status);
|
|
438
427
|
} finally {
|
|
439
428
|
rmSync(context, { recursive: true, force: true });
|
|
@@ -486,6 +475,9 @@ async function prune(host, repository, repoRecords, keep, runnerDirPath) {
|
|
|
486
475
|
rmSync(rootfsPathFor(runnerDirPath, image.id), { force: true });
|
|
487
476
|
const recipeKeyLabel = image.labels[RECIPE_KEY2];
|
|
488
477
|
const toolsKeyLabel = image.labels[TOOLS_KEY];
|
|
478
|
+
if (image.labels[KIND2] === "recipe" && recipeKeyLabel !== void 0) {
|
|
479
|
+
rmSync(join(repoRecords, LAYOUTS_DIR, recipeKeyLabel.slice(0, KEY_PREFIX)), { recursive: true, force: true });
|
|
480
|
+
}
|
|
489
481
|
if (image.labels[KIND2] === "build" && recipeKeyLabel !== void 0 && toolsKeyLabel !== void 0) {
|
|
490
482
|
rmSync(join(repoRecords, `${recipeKeyLabel.slice(0, KEY_PREFIX)}-${toolsKeyLabel.slice(0, KEY_PREFIX)}`), { recursive: true, force: true });
|
|
491
483
|
}
|
|
@@ -493,4 +485,4 @@ async function prune(host, repository, repoRecords, keep, runnerDirPath) {
|
|
|
493
485
|
return removed;
|
|
494
486
|
}
|
|
495
487
|
|
|
496
|
-
export {
|
|
488
|
+
export { buildRepositoryImage, cloneRepository, fetchCommit, readBranchHead, readDefaultBranchHead };
|
|
@@ -3,23 +3,6 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
|
|
4
4
|
createRequire(import.meta.url);
|
|
5
5
|
|
|
6
|
-
// src/runner/container/disk.ts
|
|
7
|
-
var UNITS = { "": 1, k: 1024, m: 1024 ** 2, g: 1024 ** 3 };
|
|
8
|
-
function parseSize(text) {
|
|
9
|
-
const match = /^(\d+(?:\.\d+)?)([kKmMgG]?)$/.exec(text);
|
|
10
|
-
if (match === null) return void 0;
|
|
11
|
-
const bytes = Number(match[1]) * UNITS[match[2].toLowerCase()];
|
|
12
|
-
return bytes > 0 ? bytes : void 0;
|
|
13
|
-
}
|
|
14
|
-
function parseDuKilobytes(output) {
|
|
15
|
-
const match = /^(\d+)\s/.exec(output);
|
|
16
|
-
return match === null ? void 0 : Number(match[1]);
|
|
17
|
-
}
|
|
18
|
-
function exceedsDisk(usedKilobytes, limit) {
|
|
19
|
-
const bytes = parseSize(limit);
|
|
20
|
-
return usedKilobytes * 1024 > (bytes ?? Number.POSITIVE_INFINITY);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
6
|
// src/runner/allow-hosts.ts
|
|
24
7
|
var MAX_ALLOW_HOSTS = 500;
|
|
25
8
|
var LABEL = /^(?!-)[a-z0-9-]{1,63}(?<!-)$/;
|
|
@@ -57,4 +40,4 @@ function hostAllowed(host, allowHosts) {
|
|
|
57
40
|
});
|
|
58
41
|
}
|
|
59
42
|
|
|
60
|
-
export { MAX_ALLOW_HOSTS, allowHostProblem,
|
|
43
|
+
export { MAX_ALLOW_HOSTS, allowHostProblem, hostAllowed };
|
|
@@ -6,7 +6,7 @@ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
|
6
6
|
|
|
7
7
|
createRequire(import.meta.url);
|
|
8
8
|
|
|
9
|
-
// ../../node_modules/structured-headers/dist/util.js
|
|
9
|
+
// ../../node_modules/http-message-sig/node_modules/structured-headers/dist/util.js
|
|
10
10
|
var asciiRe = /^[\x20-\x7E]*$/;
|
|
11
11
|
var tokenRe = /^[a-zA-Z*][:/!#$%&'*+\-.^_`|~A-Za-z0-9]*$/;
|
|
12
12
|
var keyRe = /^[a-z*][*\-_.a-z0-9]*$/;
|
|
@@ -40,7 +40,7 @@ function base64ToArrayBuffer(b64) {
|
|
|
40
40
|
return bytes.buffer;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// ../../node_modules/structured-headers/dist/token.js
|
|
43
|
+
// ../../node_modules/http-message-sig/node_modules/structured-headers/dist/token.js
|
|
44
44
|
var Token = class {
|
|
45
45
|
constructor(value) {
|
|
46
46
|
if (!isValidTokenStr(value)) {
|
|
@@ -53,7 +53,7 @@ var Token = class {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
// ../../node_modules/structured-headers/dist/displaystring.js
|
|
56
|
+
// ../../node_modules/http-message-sig/node_modules/structured-headers/dist/displaystring.js
|
|
57
57
|
var DisplayString = class {
|
|
58
58
|
constructor(value) {
|
|
59
59
|
this.value = value;
|
|
@@ -63,7 +63,7 @@ var DisplayString = class {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
// ../../node_modules/structured-headers/dist/serializer.js
|
|
66
|
+
// ../../node_modules/http-message-sig/node_modules/structured-headers/dist/serializer.js
|
|
67
67
|
var SerializeError = class extends Error {
|
|
68
68
|
};
|
|
69
69
|
function serializeDictionary(input) {
|
|
@@ -186,7 +186,7 @@ function serializeKey(input) {
|
|
|
186
186
|
return input;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
// ../../node_modules/structured-headers/dist/parser.js
|
|
189
|
+
// ../../node_modules/http-message-sig/node_modules/structured-headers/dist/parser.js
|
|
190
190
|
function parseDictionary(input) {
|
|
191
191
|
const parser = new Parser(input);
|
|
192
192
|
return parser.parseDictionary();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { readCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
|
|
4
|
-
import { signRunnerRequest, signerFor } from './chunk-
|
|
4
|
+
import { signRunnerRequest, signerFor } from './chunk-V7NIVOFD.js';
|
|
5
5
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
6
|
|
|
7
7
|
createRequire(import.meta.url);
|
|
@@ -1,7 +1,7 @@
|
|
|
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-
|
|
3
|
+
import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-QNRSFEGY.js';
|
|
4
|
+
import { MIN_ENGINE_MAJOR } from './chunk-M4ERCYDB.js';
|
|
5
5
|
import { RUNNER_DIR_MODE, runnerDir, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
|
|
6
6
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
7
7
|
import { dirname } from 'path';
|