@kitman-sh/cli 0.10.54 → 0.10.56
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/{chunk-mtgkvbk4.js → chunk-2md3k83r.js} +3 -3
- package/dist/{chunk-dkpqwk0q.js → chunk-2t06f3vz.js} +4 -4
- package/dist/{chunk-148mjppg.js → chunk-338c1c1x.js} +2 -2
- package/dist/{chunk-c0wrcam4.js → chunk-48dn3enn.js} +482 -80
- package/dist/{chunk-eerh2t20.js → chunk-7kernadf.js} +5 -5
- package/dist/{chunk-19aqk325.js → chunk-99ver3za.js} +1 -1
- package/dist/{chunk-twp7aprz.js → chunk-bdxhb63t.js} +5 -5
- package/dist/{chunk-xgwjcq4z.js → chunk-emabyaj0.js} +7 -4
- package/dist/{chunk-q0yna8sw.js → chunk-hma82ban.js} +3 -3
- package/dist/{chunk-m32wb6t0.js → chunk-jb9dcsfn.js} +12 -12
- package/dist/{chunk-mmetyep8.js → chunk-kdyzndvx.js} +1 -1
- package/dist/{chunk-5j3cxsnp.js → chunk-pvkwhesj.js} +3 -3
- package/dist/{chunk-5y5axze6.js → chunk-s97jvqxb.js} +3 -3
- package/dist/{chunk-wczs5vrq.js → chunk-st9mym1j.js} +3 -1
- package/dist/{chunk-vtn088tq.js → chunk-vn3x7bzf.js} +2 -2
- package/dist/{chunk-y48wz1sa.js → chunk-w9kg1784.js} +41 -21
- package/dist/{chunk-g7vk5tjp.js → chunk-wbrv4705.js} +2 -2
- package/dist/{chunk-rjfxnk05.js → chunk-yfdktxzg.js} +3 -3
- package/dist/{chunk-my987gxf.js → chunk-zf3vq701.js} +15 -11
- package/dist/egress-proxy.ts +138 -21
- package/dist/half-close-relay.ts +125 -0
- package/dist/index.js +4 -4
- package/dist/tcp-forwarder.ts +29 -0
- package/package.json +1 -1
- /package/dist/{chunk-3d6abgjh.js → chunk-g53wn1q8.js} +0 -0
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
makeUnsafe6,
|
|
52
52
|
provide,
|
|
53
53
|
effect,
|
|
54
|
+
mergeAll,
|
|
54
55
|
die2,
|
|
55
56
|
findErrorOption,
|
|
56
57
|
pretty,
|
|
@@ -163,6 +164,8 @@ import {
|
|
|
163
164
|
currentTimeMillis,
|
|
164
165
|
SecureRandom,
|
|
165
166
|
layerWebCrypto,
|
|
167
|
+
layer,
|
|
168
|
+
layer2,
|
|
166
169
|
toDate,
|
|
167
170
|
toIso,
|
|
168
171
|
wallClockMillis,
|
|
@@ -221,7 +224,7 @@ import {
|
|
|
221
224
|
installCommand,
|
|
222
225
|
checkServicesFile,
|
|
223
226
|
checkServices
|
|
224
|
-
} from "./chunk-
|
|
227
|
+
} from "./chunk-jb9dcsfn.js";
|
|
225
228
|
import {
|
|
226
229
|
join,
|
|
227
230
|
interrupt,
|
|
@@ -243,12 +246,15 @@ import {
|
|
|
243
246
|
runForEach,
|
|
244
247
|
FileSystem,
|
|
245
248
|
Path,
|
|
249
|
+
embeddedFile,
|
|
250
|
+
extractEmbeddedFile,
|
|
246
251
|
optionalEnv,
|
|
247
252
|
harnessesUnsupportedInSrt2,
|
|
248
253
|
compiled2,
|
|
249
254
|
pinnedSrtCommand2,
|
|
250
255
|
pinnedSrtStepCommand2,
|
|
251
256
|
runSrtCli2,
|
|
257
|
+
kitmanCacheDirectory2,
|
|
252
258
|
srtSettings2,
|
|
253
259
|
srtCacheEnvironment2,
|
|
254
260
|
srtInheritedEnv2,
|
|
@@ -257,7 +263,7 @@ import {
|
|
|
257
263
|
writeSrtSettings2,
|
|
258
264
|
srtStepArgv2,
|
|
259
265
|
srtArgv2
|
|
260
|
-
} from "./chunk-
|
|
266
|
+
} from "./chunk-emabyaj0.js";
|
|
261
267
|
import {
|
|
262
268
|
writeAgentEnvironmentConfigFile2,
|
|
263
269
|
readManifestSkillPaths2,
|
|
@@ -273,8 +279,8 @@ import {
|
|
|
273
279
|
applyAgentEnvironmentMaterialization2,
|
|
274
280
|
isPathWithin2,
|
|
275
281
|
skillIdentity2
|
|
276
|
-
} from "./chunk-
|
|
277
|
-
import"./chunk-
|
|
282
|
+
} from "./chunk-s97jvqxb.js";
|
|
283
|
+
import"./chunk-bdxhb63t.js";
|
|
278
284
|
import {
|
|
279
285
|
sliceBytes2,
|
|
280
286
|
maxLineBytes2,
|
|
@@ -282,28 +288,28 @@ import {
|
|
|
282
288
|
decodedOption2,
|
|
283
289
|
decoded2,
|
|
284
290
|
readOpencode2
|
|
285
|
-
} from "./chunk-
|
|
291
|
+
} from "./chunk-vn3x7bzf.js";
|
|
286
292
|
import {
|
|
287
293
|
writeSecretRegistry,
|
|
288
294
|
secretRefusalLog,
|
|
289
295
|
parseSecretRefusals
|
|
290
|
-
} from "./chunk-
|
|
296
|
+
} from "./chunk-g53wn1q8.js";
|
|
291
297
|
import {
|
|
292
298
|
uploadRunFile,
|
|
293
299
|
programLease,
|
|
294
300
|
rpcRunFiles,
|
|
295
301
|
programHostsEnv,
|
|
296
302
|
undeclaredHostsEnv
|
|
297
|
-
} from "./chunk-
|
|
298
|
-
import"./chunk-
|
|
303
|
+
} from "./chunk-wbrv4705.js";
|
|
304
|
+
import"./chunk-pvkwhesj.js";
|
|
299
305
|
import {
|
|
300
306
|
nextInt
|
|
301
307
|
} from "./chunk-gwcqz1bj.js";
|
|
302
308
|
import {
|
|
303
309
|
ChildProcessSpawner,
|
|
304
310
|
make3
|
|
305
|
-
} from "./chunk-
|
|
306
|
-
import"./chunk-
|
|
311
|
+
} from "./chunk-kdyzndvx.js";
|
|
312
|
+
import"./chunk-338c1c1x.js";
|
|
307
313
|
|
|
308
314
|
// packages/core/src/sync-kit.ts
|
|
309
315
|
import { createHash } from "crypto";
|
|
@@ -2577,8 +2583,19 @@ var prepareDockerHome = (input) => gen(function* () {
|
|
|
2577
2583
|
}
|
|
2578
2584
|
});
|
|
2579
2585
|
|
|
2580
|
-
// packages/agent-runtime/src/
|
|
2586
|
+
// packages/agent-runtime/src/helper-scripts.ts
|
|
2581
2587
|
import { fileURLToPath } from "url";
|
|
2588
|
+
var helperScriptPath = (name) => gen(function* () {
|
|
2589
|
+
if (!compiled2)
|
|
2590
|
+
return fileURLToPath(import.meta.resolve(`./${name}`));
|
|
2591
|
+
const path = yield* Path;
|
|
2592
|
+
const file = embeddedFile(Bun.embeddedFiles, name.replace(/\.ts$/, ""));
|
|
2593
|
+
if (file === undefined)
|
|
2594
|
+
return yield* die3(new Error(`This Runner was compiled without ${name}`));
|
|
2595
|
+
return yield* extractEmbeddedFile(path.join(yield* kitmanCacheDirectory2, "helper-scripts"), file, name);
|
|
2596
|
+
}).pipe(orDie, provide3(mergeAll(layer, layer2)));
|
|
2597
|
+
|
|
2598
|
+
// packages/agent-runtime/src/docker-sandbox.ts
|
|
2582
2599
|
var RunnerLabel = "kitman.runner";
|
|
2583
2600
|
var StepAttemptLabel = "kitman.step-attempt";
|
|
2584
2601
|
var EgressProxyImage = "oven/bun@sha256:4cf82f5686b196504fe119db3fcd9185b191f82ece82c40680e597228ec6070a";
|
|
@@ -2661,7 +2678,7 @@ var startDockerSandbox = (input) => gen(function* () {
|
|
|
2661
2678
|
labels,
|
|
2662
2679
|
mounts: [
|
|
2663
2680
|
{
|
|
2664
|
-
source:
|
|
2681
|
+
source: yield* helperScriptPath("egress-proxy.ts"),
|
|
2665
2682
|
target: "/kitman/egress-proxy.ts",
|
|
2666
2683
|
readOnly: true
|
|
2667
2684
|
}
|
|
@@ -5310,8 +5327,68 @@ var harnessesInSrt = (input) => gen(function* () {
|
|
|
5310
5327
|
binaries: Object.fromEntries(probed.flatMap((entry) => entry.binary === undefined ? [] : [[entry.harness, entry.binary]]))
|
|
5311
5328
|
};
|
|
5312
5329
|
});
|
|
5313
|
-
// packages/agent-runtime/src/
|
|
5330
|
+
// packages/agent-runtime/src/loopback-tunnel.ts
|
|
5314
5331
|
import * as net from "net";
|
|
5332
|
+
|
|
5333
|
+
class LoopbackTunnelUnavailable extends TaggedError("LoopbackTunnelUnavailable") {
|
|
5334
|
+
}
|
|
5335
|
+
var srtLoopbackTunnel = (tunnel) => [
|
|
5336
|
+
"proxy=${HTTP_PROXY:?srt set no HTTP_PROXY}",
|
|
5337
|
+
"proxy=${proxy#*://}",
|
|
5338
|
+
"proxy=${proxy%%/*}",
|
|
5339
|
+
"auth=",
|
|
5340
|
+
"case $proxy in *@*)",
|
|
5341
|
+
` auth=$(printf %s "\${proxy%@*}" | awk 'BEGIN { for (i = 1; i < 256; i++) hex[sprintf("%02X", i)] = sprintf("%c", i) }
|
|
5342
|
+
{ out = ""; while (match($0, /%[0-9A-Fa-f][0-9A-Fa-f]/)) { out = out substr($0, 1, RSTART - 1) hex[toupper(substr($0, RSTART + 1, 2))]; $0 = substr($0, RSTART + 3) } printf "%s", out $0 }')`,
|
|
5343
|
+
" proxy=${proxy##*@} ;;",
|
|
5344
|
+
"esac",
|
|
5345
|
+
"log=$(mktemp)",
|
|
5346
|
+
`${tunnel.listener ?? `socat -t 86400 TCP-LISTEN:${tunnel.listenPort},bind=127.0.0.1,fork,reuseaddr "PROXY:\${proxy%:*}:127.0.0.1:${tunnel.hostPort},proxyport=\${proxy##*:}\${auth:+,proxyauth=$auth}"`} 2>"$log" &`,
|
|
5347
|
+
"tunnel=$!",
|
|
5348
|
+
`fail() { echo "Kitman: the ${tunnel.service} tunnel did not open: $1" >&2; cat "$log" >&2; kill $tunnel 2>/dev/null; rm -f "$log"; exit 1; }`,
|
|
5349
|
+
"tries=0",
|
|
5350
|
+
"while :; do",
|
|
5351
|
+
' kill -0 $tunnel 2>/dev/null || fail "its listener stopped"',
|
|
5352
|
+
` answer=$( (${tunnel.probe}; sleep 1) | socat - TCP:127.0.0.1:${tunnel.listenPort} 2>/dev/null | ${tunnel.read})`,
|
|
5353
|
+
` case $answer in ${tunnel.answers}) break ;; esac`,
|
|
5354
|
+
" tries=$((tries + 1))",
|
|
5355
|
+
` [ $tries -lt 30 ] || fail "${tunnel.service} did not answer through it"`,
|
|
5356
|
+
" sleep 0.2",
|
|
5357
|
+
"done",
|
|
5358
|
+
'kill -0 $tunnel 2>/dev/null || fail "its listener stopped"',
|
|
5359
|
+
'sh -c "$1"',
|
|
5360
|
+
"status=$?",
|
|
5361
|
+
"kill $tunnel 2>/dev/null",
|
|
5362
|
+
'rm -f "$log"',
|
|
5363
|
+
"exit $status"
|
|
5364
|
+
].join(`
|
|
5365
|
+
`);
|
|
5366
|
+
var loopbackSocketForwarder = (hostPort, socket) => gen(function* () {
|
|
5367
|
+
const fs = yield* FileSystem;
|
|
5368
|
+
const dir = yield* flatMap3(fs.makeTempDirectoryScoped({ prefix: "kitman-lo-" }), fs.realPath).pipe(mapError2((error) => new LoopbackTunnelUnavailable({ reason: error.message })));
|
|
5369
|
+
yield* acquireRelease(callback3((resume) => {
|
|
5370
|
+
const open = new Set;
|
|
5371
|
+
const server = net.createServer({ allowHalfOpen: true }, (client) => {
|
|
5372
|
+
const upstream = net.connect({ port: hostPort, host: "127.0.0.1", allowHalfOpen: true });
|
|
5373
|
+
for (const connection of [client, upstream]) {
|
|
5374
|
+
open.add(connection);
|
|
5375
|
+
connection.on("close", () => open.delete(connection));
|
|
5376
|
+
}
|
|
5377
|
+
client.pipe(upstream);
|
|
5378
|
+
upstream.pipe(client);
|
|
5379
|
+
client.on("error", () => upstream.destroy());
|
|
5380
|
+
upstream.on("error", () => client.destroy());
|
|
5381
|
+
});
|
|
5382
|
+
server.once("error", (error) => resume(fail7(new LoopbackTunnelUnavailable({ reason: error.message }))));
|
|
5383
|
+
server.listen(`${dir}/${socket}`, () => resume(succeed6({ server, open })));
|
|
5384
|
+
}), ({ server, open }) => callback3((resume) => {
|
|
5385
|
+
server.close(() => resume(void_3));
|
|
5386
|
+
open.forEach((connection) => connection.destroy());
|
|
5387
|
+
}));
|
|
5388
|
+
return dir;
|
|
5389
|
+
});
|
|
5390
|
+
|
|
5391
|
+
// packages/agent-runtime/src/check-postgres.ts
|
|
5315
5392
|
var CheckPostgresImage = "pgvector/pgvector:0.8.7-pg16@sha256:7b822b0aac60967beb1ea5e576b8602c94c300a157d187f385ae3e0da199b90a";
|
|
5316
5393
|
var checkPostgresSandboxPort = 5432;
|
|
5317
5394
|
var checkPostgresAlias = "kitman-postgres";
|
|
@@ -5411,60 +5488,202 @@ var dockerCheckPostgres = (runnerId, replicaId) => (id) => gen(function* () {
|
|
|
5411
5488
|
return { container, hostPort, user, password };
|
|
5412
5489
|
});
|
|
5413
5490
|
var sslRequestOctal = String.raw`\000\000\000\010\004\322\026\057`;
|
|
5414
|
-
var srtPostgresTunnel = (hostPort, listenPort = checkPostgresSandboxPort) =>
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
"
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5491
|
+
var srtPostgresTunnel = (hostPort, listenPort = checkPostgresSandboxPort) => srtLoopbackTunnel({
|
|
5492
|
+
service: "Postgres",
|
|
5493
|
+
hostPort,
|
|
5494
|
+
listenPort,
|
|
5495
|
+
probe: `printf '${sslRequestOctal}'`,
|
|
5496
|
+
read: "head -c 1",
|
|
5497
|
+
answers: "N|S"
|
|
5498
|
+
});
|
|
5499
|
+
var postgresSocketForwarder = (hostPort) => loopbackSocketForwarder(hostPort, `.s.PGSQL.${checkPostgresSandboxPort}`).pipe(mapError2((error) => new CheckPostgresUnavailable({ reason: error.reason })));
|
|
5500
|
+
|
|
5501
|
+
// packages/agent-runtime/src/check-docker.ts
|
|
5502
|
+
var checkDockerPort = 2375;
|
|
5503
|
+
var checkDockerAlias = "kitman-docker";
|
|
5504
|
+
var DockerHubRegistry = "https://registry-1.docker.io";
|
|
5505
|
+
var CheckDockerLabel = "kitman.check-docker";
|
|
5506
|
+
var CheckDockerReplicaLabel = "kitman.check-docker-replica";
|
|
5507
|
+
var rootlessDataRoot = "/home/rootless/.local/share/docker";
|
|
5508
|
+
var registryDataRoot = "/var/lib/registry";
|
|
5509
|
+
var registryMirrorPort = 5000;
|
|
5510
|
+
var egressProxyPort = 3128;
|
|
5511
|
+
|
|
5512
|
+
class CheckDockerUnavailable extends TaggedError("CheckDockerUnavailable") {
|
|
5513
|
+
get message() {
|
|
5514
|
+
return `A pipeline check runs with a Docker daemon of its own, which this Runner could not start: ${this.reason}`;
|
|
5515
|
+
}
|
|
5516
|
+
}
|
|
5517
|
+
var dockerName2 = (id) => id.replaceAll(/[^a-zA-Z0-9_.-]/g, "-");
|
|
5518
|
+
var checkRegistryCacheVolume = (runnerId) => `kitman-check-registry-cache-${dockerName2(runnerId)}`;
|
|
5519
|
+
var checkDockerProxyEnvironment = (proxy, mirror) => {
|
|
5520
|
+
const direct = `localhost,127.0.0.1,${new URL(mirror).hostname}`;
|
|
5521
|
+
return {
|
|
5522
|
+
HTTP_PROXY: proxy,
|
|
5523
|
+
HTTPS_PROXY: proxy,
|
|
5524
|
+
http_proxy: proxy,
|
|
5525
|
+
https_proxy: proxy,
|
|
5526
|
+
NO_PROXY: direct,
|
|
5527
|
+
no_proxy: direct
|
|
5528
|
+
};
|
|
5529
|
+
};
|
|
5530
|
+
var checkDockerDaemonArgs = (input) => [
|
|
5531
|
+
"run",
|
|
5532
|
+
"--detach",
|
|
5533
|
+
"--name",
|
|
5534
|
+
input.name,
|
|
5535
|
+
...input.labels.flatMap(([key, value]) => ["--label", `${key}=${value}`]),
|
|
5536
|
+
"--network",
|
|
5537
|
+
input.network,
|
|
5538
|
+
"--network-alias",
|
|
5539
|
+
checkDockerAlias,
|
|
5540
|
+
"--security-opt",
|
|
5541
|
+
"seccomp=unconfined",
|
|
5542
|
+
"--security-opt",
|
|
5543
|
+
"apparmor=unconfined",
|
|
5544
|
+
"--security-opt",
|
|
5545
|
+
"systempaths=unconfined",
|
|
5546
|
+
"--device",
|
|
5547
|
+
"/dev/net/tun",
|
|
5548
|
+
"--volume",
|
|
5549
|
+
rootlessDataRoot,
|
|
5550
|
+
"--env",
|
|
5551
|
+
"DOCKER_TLS_CERTDIR=",
|
|
5552
|
+
...Object.entries(input.proxy === undefined ? {} : checkDockerProxyEnvironment(input.proxy, input.mirror)).flatMap(([key, value]) => ["--env", `${key}=${value}`]),
|
|
5553
|
+
input.image,
|
|
5554
|
+
"--registry-mirror",
|
|
5555
|
+
input.mirror,
|
|
5556
|
+
"--tls=false"
|
|
5557
|
+
];
|
|
5558
|
+
var checkRegistryMirrorArgs = (input) => [
|
|
5559
|
+
"run",
|
|
5560
|
+
"--detach",
|
|
5561
|
+
"--rm",
|
|
5562
|
+
"--name",
|
|
5563
|
+
input.name,
|
|
5564
|
+
...input.labels.flatMap(([key, value]) => ["--label", `${key}=${value}`]),
|
|
5565
|
+
"--network",
|
|
5566
|
+
input.network,
|
|
5567
|
+
"--volume",
|
|
5568
|
+
`${input.volume}:${registryDataRoot}`,
|
|
5569
|
+
"--env",
|
|
5570
|
+
`REGISTRY_PROXY_REMOTEURL=${DockerHubRegistry}`,
|
|
5571
|
+
"--env",
|
|
5572
|
+
"REGISTRY_PROXY_TTL=0",
|
|
5573
|
+
input.image
|
|
5574
|
+
];
|
|
5575
|
+
var checkDockerClientConfig = (proxy) => proxy === undefined ? {} : { proxies: { default: { httpProxy: proxy, httpsProxy: proxy, noProxy: "localhost,127.0.0.1" } } };
|
|
5576
|
+
var orphanedCheckDocker = (listing, live) => listing.split(`
|
|
5577
|
+
`).map((line) => line.trim().split(/\s+/)).flatMap(([id, replica]) => id === undefined || id === "" || live.has(replica ?? "") ? [] : [id]);
|
|
5578
|
+
var removeCheckDocker = (runnerId, liveReplicas) => gen(function* () {
|
|
5579
|
+
const filter = ["--filter", `label=${CheckDockerLabel}=${runnerId}`];
|
|
5580
|
+
const format = `{{.ID}} {{.Label "${CheckDockerReplicaLabel}"}}`;
|
|
5581
|
+
const containers = orphanedCheckDocker(yield* runCommand2("docker", ["ps", "--all", ...filter, "--format", format], { timeout: "10 seconds" }), liveReplicas);
|
|
5582
|
+
if (containers.length > 0)
|
|
5583
|
+
yield* runCommand2("docker", ["rm", "--force", "--volumes", ...containers], { timeout: "30 seconds" });
|
|
5584
|
+
const networks = orphanedCheckDocker(yield* runCommand2("docker", ["network", "ls", ...filter, "--format", format], { timeout: "10 seconds" }), liveReplicas);
|
|
5585
|
+
if (networks.length > 0)
|
|
5586
|
+
yield* runCommand2("docker", ["network", "rm", ...networks], { timeout: "30 seconds" });
|
|
5587
|
+
}).pipe(ignore);
|
|
5588
|
+
var daemonLogs = (container) => gen(function* () {
|
|
5589
|
+
const state = yield* runCommand2("docker", [
|
|
5590
|
+
"inspect",
|
|
5591
|
+
"--format",
|
|
5592
|
+
"{{.State.Status}} (exit code {{.State.ExitCode}})",
|
|
5593
|
+
container
|
|
5594
|
+
]);
|
|
5595
|
+
const logs = yield* runCommand2("sh", ["-c", 'docker logs --tail 40 "$0" 2>&1', container]);
|
|
5596
|
+
return `${state.trim()}
|
|
5597
|
+
${logs.trim().slice(-3000)}`;
|
|
5598
|
+
}).pipe(orElseSucceed(() => "nothing, since docker could not show its state or logs"));
|
|
5599
|
+
var randomHex2 = () => Array.from(crypto.getRandomValues(new Uint8Array(4)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
5600
|
+
var dockerCheckDaemon = (input) => ({ id, network: allowed }) => gen(function* () {
|
|
5601
|
+
const run = `${dockerName2(id)}-${randomHex2()}`;
|
|
5602
|
+
const daemon = `kitman-check-docker-${run}`;
|
|
5603
|
+
const network = `kitman-check-docker-net-${run}`;
|
|
5604
|
+
const outside = `kitman-check-docker-out-${run}`;
|
|
5605
|
+
const mirror = `kitman-check-docker-mirror-${run}`;
|
|
5606
|
+
const proxyContainer = `kitman-check-docker-egress-${run}`;
|
|
5607
|
+
const forwarder = `kitman-check-docker-api-${run}`;
|
|
5608
|
+
const runLabel = "kitman.check-docker-run";
|
|
5609
|
+
const labels = [
|
|
5610
|
+
[CheckDockerLabel, input.runnerId],
|
|
5611
|
+
[CheckDockerReplicaLabel, input.replicaId],
|
|
5612
|
+
[runLabel, run]
|
|
5613
|
+
];
|
|
5614
|
+
const labelArgs = labels.flatMap(([key, value]) => ["--label", `${key}=${value}`]);
|
|
5615
|
+
const docker = (args, timeout = "30 seconds") => runCommand2("docker", args, { timeout }).pipe(mapError2((error) => new CheckDockerUnavailable({ reason: error.message })));
|
|
5616
|
+
yield* acquireRelease(void_3, () => gen(function* () {
|
|
5617
|
+
const ids = (yield* docker(["ps", "--all", "--quiet", "--filter", `label=${runLabel}=${run}`])).split(`
|
|
5618
|
+
`).filter((line) => line.trim() !== "");
|
|
5619
|
+
if (ids.length > 0)
|
|
5620
|
+
yield* docker(["rm", "--force", "--volumes", ...ids], "2 minutes");
|
|
5621
|
+
yield* ignore(docker(["network", "rm", network]));
|
|
5622
|
+
yield* ignore(docker(["network", "rm", outside]));
|
|
5623
|
+
}).pipe(ignore));
|
|
5624
|
+
yield* docker(["network", "create", "--opt", "com.docker.network.bridge.enable_icc=false", ...labelArgs, outside]);
|
|
5625
|
+
yield* docker(["network", "create", ...allowed === "open" ? [] : ["--internal"], ...labelArgs, network]);
|
|
5626
|
+
const addressOn = (container) => gen(function* () {
|
|
5627
|
+
yield* docker(["network", "connect", network, container]);
|
|
5628
|
+
const address = (yield* docker([
|
|
5629
|
+
"inspect",
|
|
5630
|
+
"--format",
|
|
5631
|
+
`{{(index .NetworkSettings.Networks "${network}").IPAddress}}`,
|
|
5632
|
+
container
|
|
5633
|
+
])).trim();
|
|
5634
|
+
if (address === "")
|
|
5635
|
+
return yield* new CheckDockerUnavailable({ reason: `${container} has no address` });
|
|
5636
|
+
return address;
|
|
5637
|
+
});
|
|
5638
|
+
const helper = (name, args) => docker(["run", "--detach", "--rm", "--name", name, ...labelArgs, "--network", outside, ...args], "30 minutes");
|
|
5639
|
+
yield* docker(checkRegistryMirrorArgs({
|
|
5640
|
+
name: mirror,
|
|
5641
|
+
image: input.registryImage,
|
|
5642
|
+
labels,
|
|
5643
|
+
network: outside,
|
|
5644
|
+
volume: checkRegistryCacheVolume(input.runnerId)
|
|
5645
|
+
}), "30 minutes");
|
|
5646
|
+
const mirrorUrl = `http://${yield* addressOn(mirror)}:${registryMirrorPort}`;
|
|
5647
|
+
const proxy = allowed === "open" ? undefined : yield* gen(function* () {
|
|
5648
|
+
yield* helper(proxyContainer, [
|
|
5649
|
+
"--volume",
|
|
5650
|
+
`${yield* helperScriptPath("egress-proxy.ts")}:/kitman/egress-proxy.ts:ro`,
|
|
5651
|
+
input.proxyImage ?? EgressProxyImage,
|
|
5652
|
+
"bun",
|
|
5653
|
+
"/kitman/egress-proxy.ts",
|
|
5654
|
+
allowed.hosts.join(",")
|
|
5655
|
+
]);
|
|
5656
|
+
return `http://${yield* addressOn(proxyContainer)}:${egressProxyPort}`;
|
|
5657
|
+
});
|
|
5658
|
+
yield* docker(checkDockerDaemonArgs({
|
|
5659
|
+
name: daemon,
|
|
5660
|
+
image: input.image,
|
|
5661
|
+
labels,
|
|
5662
|
+
network,
|
|
5663
|
+
mirror: mirrorUrl,
|
|
5664
|
+
...proxy === undefined ? undefined : { proxy }
|
|
5665
|
+
}), "30 minutes");
|
|
5666
|
+
yield* helper(forwarder, [
|
|
5667
|
+
"--publish",
|
|
5668
|
+
`127.0.0.1::${checkDockerPort}`,
|
|
5669
|
+
"--volume",
|
|
5670
|
+
`${yield* helperScriptPath("tcp-forwarder.ts")}:/kitman/tcp-forwarder.ts:ro`,
|
|
5671
|
+
input.proxyImage ?? EgressProxyImage,
|
|
5672
|
+
"bun",
|
|
5673
|
+
"/kitman/tcp-forwarder.ts",
|
|
5674
|
+
String(checkDockerPort),
|
|
5675
|
+
checkDockerAlias,
|
|
5676
|
+
String(checkDockerPort)
|
|
5677
|
+
]);
|
|
5678
|
+
yield* docker(["network", "connect", network, forwarder]);
|
|
5679
|
+
const hostPort = publishedPort(yield* docker(["port", forwarder, `${checkDockerPort}/tcp`]));
|
|
5680
|
+
if (hostPort === undefined)
|
|
5681
|
+
return yield* new CheckDockerUnavailable({ reason: "docker published no port" });
|
|
5682
|
+
yield* docker(["--host", `tcp://127.0.0.1:${hostPort}`, "version", "--format", "{{.Server.Version}}"], "10 seconds").pipe(retry({ schedule: spaced("500 millis"), times: 240 }), catch_((error) => gen(function* () {
|
|
5683
|
+
const logs = yield* daemonLogs(daemon);
|
|
5684
|
+
return yield* new CheckDockerUnavailable({ reason: `${error.reason}; the daemon logged: ${logs}` });
|
|
5685
|
+
})));
|
|
5686
|
+
return { container: daemon, hostPort, ...proxy === undefined ? undefined : { proxy } };
|
|
5468
5687
|
});
|
|
5469
5688
|
// packages/agent-runtime/src/codex-hook-trust.ts
|
|
5470
5689
|
class CodexAppServerFailed extends TaggedError("CodexAppServerFailed") {
|
|
@@ -5794,9 +6013,109 @@ var programProcessExecutor = (input) => (work) => gen(function* () {
|
|
|
5794
6013
|
status: "deferred",
|
|
5795
6014
|
crashed: `it did not start: ${error.message}`.slice(0, 500)
|
|
5796
6015
|
})));
|
|
6016
|
+
// packages/agent-runtime/src/half-close-relay.ts
|
|
6017
|
+
import { once } from "events";
|
|
6018
|
+
import { connect as connect2, createServer as createServer2 } from "net";
|
|
6019
|
+
var frameHeader = 4;
|
|
6020
|
+
var endOfInput = Buffer.alloc(frameHeader);
|
|
6021
|
+
var maxFrame = 1024 * 1024;
|
|
6022
|
+
var keepUp = (from, to, accepted) => {
|
|
6023
|
+
if (accepted)
|
|
6024
|
+
return;
|
|
6025
|
+
from.pause();
|
|
6026
|
+
to.once("drain", () => from.resume());
|
|
6027
|
+
};
|
|
6028
|
+
var closeTogether = (...sockets) => sockets.forEach((socket) => {
|
|
6029
|
+
socket.on("error", () => sockets.forEach((other) => other.destroy()));
|
|
6030
|
+
socket.on("close", () => sockets.forEach((other) => other.end()));
|
|
6031
|
+
});
|
|
6032
|
+
var listening = (server, port) => once(server.listen(port, "127.0.0.1"), "listening").then(() => server);
|
|
6033
|
+
var startHalfCloseDecoder = (input) => listening(createServer2({ allowHalfOpen: true }, (client) => {
|
|
6034
|
+
const upstream = connect2({ port: input.targetPort, host: "127.0.0.1", allowHalfOpen: true });
|
|
6035
|
+
let pending = Buffer.alloc(0);
|
|
6036
|
+
client.on("data", (chunk) => {
|
|
6037
|
+
pending = Buffer.concat([pending, chunk]);
|
|
6038
|
+
if (pending.length >= frameHeader && pending.readUInt32BE(0) > maxFrame)
|
|
6039
|
+
return void client.destroy();
|
|
6040
|
+
while (pending.length >= frameHeader && pending.length >= frameHeader + pending.readUInt32BE(0)) {
|
|
6041
|
+
const length = pending.readUInt32BE(0);
|
|
6042
|
+
if (length === 0)
|
|
6043
|
+
upstream.end();
|
|
6044
|
+
else
|
|
6045
|
+
keepUp(client, upstream, upstream.write(pending.subarray(frameHeader, frameHeader + length)));
|
|
6046
|
+
pending = pending.subarray(frameHeader + length);
|
|
6047
|
+
}
|
|
6048
|
+
});
|
|
6049
|
+
client.on("end", () => upstream.end());
|
|
6050
|
+
upstream.pipe(client);
|
|
6051
|
+
closeTogether(client, upstream);
|
|
6052
|
+
}), input.port);
|
|
6053
|
+
if (false)
|
|
6054
|
+
;
|
|
6055
|
+
|
|
5797
6056
|
// packages/agent-runtime/src/verification-executor.ts
|
|
5798
6057
|
var checkTimeout = "30 minutes";
|
|
5799
6058
|
var checkFilesPerVerification = 50;
|
|
6059
|
+
var halfCloseListener = (encoder, listenPort, relayPort) => `BUN_BE_BUN=1 ${encoder.map(quoted).join(" ")} ${listenPort} "$HTTP_PROXY" ${relayPort}`;
|
|
6060
|
+
var srtDockerTunnel = (relayPort, encoder) => srtLoopbackTunnel({
|
|
6061
|
+
service: "Docker daemon",
|
|
6062
|
+
hostPort: relayPort,
|
|
6063
|
+
listenPort: checkDockerPort,
|
|
6064
|
+
listener: halfCloseListener(encoder, checkDockerPort, relayPort),
|
|
6065
|
+
probe: String.raw`printf 'GET /_ping HTTP/1.0\r\n\r\n'`,
|
|
6066
|
+
read: "tail -c 2",
|
|
6067
|
+
answers: "OK"
|
|
6068
|
+
});
|
|
6069
|
+
var pipelineEnvironment = (docker, dockerHost) => ({
|
|
6070
|
+
DOCKER_HOST: dockerHost,
|
|
6071
|
+
DOCKER_CONFIG: `${docker.clientDir}/docker`,
|
|
6072
|
+
GCL_HOME: `${docker.clientDir}/gitlab-ci-local-home`
|
|
6073
|
+
});
|
|
6074
|
+
var dockerRoute = (backend, docker) => {
|
|
6075
|
+
if (docker === undefined)
|
|
6076
|
+
return { env: {}, hosts: [], unixSockets: [], services: [], tunnel: undefined };
|
|
6077
|
+
if (backend === "docker")
|
|
6078
|
+
return {
|
|
6079
|
+
env: {
|
|
6080
|
+
...pipelineEnvironment(docker, `tcp://${checkDockerAlias}:${checkDockerPort}`),
|
|
6081
|
+
NO_PROXY: `localhost,127.0.0.1,${checkDockerAlias}`,
|
|
6082
|
+
no_proxy: `localhost,127.0.0.1,${checkDockerAlias}`
|
|
6083
|
+
},
|
|
6084
|
+
hosts: [],
|
|
6085
|
+
unixSockets: [],
|
|
6086
|
+
services: [{ container: docker.container, alias: checkDockerAlias }],
|
|
6087
|
+
tunnel: undefined
|
|
6088
|
+
};
|
|
6089
|
+
switch (docker.route.kind) {
|
|
6090
|
+
case "socket":
|
|
6091
|
+
return {
|
|
6092
|
+
env: pipelineEnvironment(docker, `unix://${docker.route.dir}/docker.sock`),
|
|
6093
|
+
hosts: [],
|
|
6094
|
+
unixSockets: [docker.route.dir],
|
|
6095
|
+
services: [],
|
|
6096
|
+
tunnel: undefined
|
|
6097
|
+
};
|
|
6098
|
+
case "relay":
|
|
6099
|
+
return {
|
|
6100
|
+
env: pipelineEnvironment(docker, `tcp://127.0.0.1:${checkDockerPort}`),
|
|
6101
|
+
hosts: [`127.0.0.1:${docker.route.port}`],
|
|
6102
|
+
unixSockets: [],
|
|
6103
|
+
services: [],
|
|
6104
|
+
tunnel: srtDockerTunnel(docker.route.port, docker.route.encoder)
|
|
6105
|
+
};
|
|
6106
|
+
case "direct":
|
|
6107
|
+
throw new Error("A pipeline check in srt reaches its daemon through a socket or the relay, never directly.");
|
|
6108
|
+
}
|
|
6109
|
+
};
|
|
6110
|
+
var hostCheckEnvironment = (docker) => {
|
|
6111
|
+
const { POSTGRES_URL: _runnerDatabase, ...runner } = withoutPreloads2();
|
|
6112
|
+
if (docker === undefined)
|
|
6113
|
+
return runner;
|
|
6114
|
+
return {
|
|
6115
|
+
...Object.fromEntries(Object.entries(runner).filter(([name]) => !name.startsWith("DOCKER_") && !name.startsWith("GCL_") && name !== "SSH_AUTH_SOCK")),
|
|
6116
|
+
...pipelineEnvironment(docker, `tcp://127.0.0.1:${docker.hostPort}`)
|
|
6117
|
+
};
|
|
6118
|
+
};
|
|
5800
6119
|
var postgresRoute = (backend, postgres) => {
|
|
5801
6120
|
if (postgres === undefined)
|
|
5802
6121
|
return { url: undefined, hosts: [], unixSockets: [], services: [], tunnel: undefined };
|
|
@@ -5824,12 +6143,14 @@ var postgresRoute = (backend, postgres) => {
|
|
|
5824
6143
|
tunnel: srtPostgresTunnel(postgres.hostPort)
|
|
5825
6144
|
};
|
|
5826
6145
|
};
|
|
5827
|
-
var checkSandboxPolicy = (work, sandbox, checkout, cache, filesDir, postgresHosts) => ({
|
|
6146
|
+
var checkSandboxPolicy = (work, sandbox, checkout, cache, filesDir, postgresHosts, docker) => ({
|
|
5828
6147
|
...runnerStateSandboxPolicy(sandbox.runner, [
|
|
5829
6148
|
repositoryClone(sandbox.runner.workRoot, work.repoBinding.id),
|
|
5830
|
-
checkout
|
|
6149
|
+
checkout,
|
|
6150
|
+
...docker === undefined ? [] : [docker.clientDir],
|
|
6151
|
+
...docker?.route.kind === "relay" ? docker.route.encoder : []
|
|
5831
6152
|
]),
|
|
5832
|
-
writablePaths: [checkout, cache, filesDir],
|
|
6153
|
+
writablePaths: [checkout, cache, filesDir, ...docker === undefined ? [] : [docker.clientDir]],
|
|
5833
6154
|
network: verificationNetworkAllowlist({
|
|
5834
6155
|
apiUrl: sandbox.apiUrl,
|
|
5835
6156
|
storageOrigin: work.storageOrigin,
|
|
@@ -5839,16 +6160,15 @@ var checkSandboxPolicy = (work, sandbox, checkout, cache, filesDir, postgresHost
|
|
|
5839
6160
|
environment: srtCacheEnvironment2(cache)
|
|
5840
6161
|
});
|
|
5841
6162
|
var checkGitEnvironment = { GIT_CONFIG_GLOBAL: "/dev/null", GIT_TERMINAL_PROMPT: "0" };
|
|
5842
|
-
var checkRunner = (work, sandbox, cache, inherited) => (checkout) => ({ command, cwd, filesDir, onOutput, postgres }) => {
|
|
6163
|
+
var checkRunner = (work, sandbox, cache, inherited) => (checkout) => ({ command, cwd, filesDir, onOutput, postgres, docker }) => {
|
|
5843
6164
|
const env = { ...checkGitEnvironment, KITMAN_RUN_FILES_DIR: filesDir };
|
|
5844
6165
|
const output = onOutput === undefined ? undefined : { onOutput };
|
|
5845
6166
|
if (sandbox === undefined || sandbox.backend === undefined) {
|
|
5846
|
-
const { POSTGRES_URL: _runnerDatabase, ...runner } = withoutPreloads2();
|
|
5847
6167
|
return runShell2(command, {
|
|
5848
6168
|
cwd,
|
|
5849
6169
|
extendEnv: false,
|
|
5850
6170
|
env: {
|
|
5851
|
-
...
|
|
6171
|
+
...hostCheckEnvironment(docker),
|
|
5852
6172
|
...env,
|
|
5853
6173
|
...postgres === undefined ? undefined : { POSTGRES_URL: checkPostgresUrl(postgres, "127.0.0.1", postgres.hostPort) }
|
|
5854
6174
|
},
|
|
@@ -5857,14 +6177,18 @@ var checkRunner = (work, sandbox, cache, inherited) => (checkout) => ({ command,
|
|
|
5857
6177
|
});
|
|
5858
6178
|
}
|
|
5859
6179
|
const route = postgresRoute(sandbox.backend, postgres);
|
|
5860
|
-
const
|
|
6180
|
+
const daemon = dockerRoute(sandbox.backend, docker);
|
|
6181
|
+
const policy = checkSandboxPolicy(work, sandbox, checkout, cache, filesDir, [...route.hosts, ...daemon.hosts], docker);
|
|
6182
|
+
const [tunnel, ...innerTunnels] = [route.tunnel, daemon.tunnel].filter((script) => script !== undefined);
|
|
6183
|
+
const tunnelled = innerTunnels.reduceRight((inner, script) => `sh -c ${quoted(script)} sh ${quoted(inner)}`, command);
|
|
5861
6184
|
const sandboxCommand = {
|
|
5862
|
-
argv:
|
|
6185
|
+
argv: tunnel === undefined ? ["sh", "-c", command] : ["sh", "-c", tunnel, "sh", tunnelled],
|
|
5863
6186
|
cwd,
|
|
5864
6187
|
env: {
|
|
5865
6188
|
...env,
|
|
5866
6189
|
KITMAN_CHECK_SANDBOX: sandbox.backend,
|
|
5867
|
-
...route.url === undefined ? undefined : { POSTGRES_URL: route.url }
|
|
6190
|
+
...route.url === undefined ? undefined : { POSTGRES_URL: route.url },
|
|
6191
|
+
...daemon.env
|
|
5868
6192
|
},
|
|
5869
6193
|
timeout: checkTimeout,
|
|
5870
6194
|
...output
|
|
@@ -5873,7 +6197,7 @@ var checkRunner = (work, sandbox, cache, inherited) => (checkout) => ({ command,
|
|
|
5873
6197
|
backend: "srt",
|
|
5874
6198
|
policy,
|
|
5875
6199
|
command: { ...sandboxCommand, env: { ...inherited, ...sandboxCommand.env }, extendEnv: false },
|
|
5876
|
-
unixSockets: route.unixSockets,
|
|
6200
|
+
unixSockets: [...route.unixSockets, ...daemon.unixSockets],
|
|
5877
6201
|
...sandbox.srtCommand === undefined ? undefined : { srtCommand: sandbox.srtCommand }
|
|
5878
6202
|
}) : runSandboxCommand({
|
|
5879
6203
|
backend: "docker",
|
|
@@ -5883,7 +6207,7 @@ var checkRunner = (work, sandbox, cache, inherited) => (checkout) => ({ command,
|
|
|
5883
6207
|
readOnlyPaths: [repositoryClone(sandbox.runner.workRoot, work.repoBinding.id)],
|
|
5884
6208
|
policy,
|
|
5885
6209
|
command: sandboxCommand,
|
|
5886
|
-
services: route.services
|
|
6210
|
+
services: [...route.services, ...daemon.services]
|
|
5887
6211
|
});
|
|
5888
6212
|
};
|
|
5889
6213
|
var regularFiles = (dir) => gen(function* () {
|
|
@@ -5937,6 +6261,39 @@ var checkoutPostgres = (worktree, services) => gen(function* () {
|
|
|
5937
6261
|
});
|
|
5938
6262
|
return yield* services.postgres(services.id).pipe(mapError2((error) => new ServicesUnavailable({ reason: error.message })));
|
|
5939
6263
|
});
|
|
6264
|
+
var decodeListeningPort = decodeUnknownEffect2(Struct({ port: Finite }));
|
|
6265
|
+
var pipelineDaemon = (services, check) => gen(function* () {
|
|
6266
|
+
if (services.docker === undefined)
|
|
6267
|
+
return yield* new ServicesUnavailable({
|
|
6268
|
+
reason: `The pipeline check ${check} runs with a Docker daemon of its own, and this Runner cannot start one: set KITMAN_RUNNER_CHECK_DOCKER_IMAGE to a docker:*-dind-rootless image and KITMAN_RUNNER_CHECK_REGISTRY_IMAGE to a registry:3 image, each pinned by digest.`
|
|
6269
|
+
});
|
|
6270
|
+
const fs = yield* FileSystem;
|
|
6271
|
+
const started = yield* services.docker({ id: services.id, network: services.network }).pipe(mapError2((error) => new ServicesUnavailable({ reason: error.message })));
|
|
6272
|
+
const clientDir = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-check-docker-" });
|
|
6273
|
+
yield* fs.makeDirectory(`${clientDir}/docker`);
|
|
6274
|
+
yield* fs.makeDirectory(`${clientDir}/gitlab-ci-local-home`);
|
|
6275
|
+
yield* fs.writeFileString(`${clientDir}/docker/config.json`, encodeUnknownJsonStringSync(checkDockerClientConfig(started.proxy)));
|
|
6276
|
+
if (services.backend !== "srt")
|
|
6277
|
+
return { ...started, clientDir, route: { kind: "direct" } };
|
|
6278
|
+
if (services.platform !== "darwin") {
|
|
6279
|
+
const relay = yield* acquireRelease(promise(() => startHalfCloseDecoder({ port: 0, targetPort: started.hostPort })), (server) => sync2(() => server.close()));
|
|
6280
|
+
const { port } = yield* decodeListeningPort(relay.address()).pipe(mapError2(() => new ServicesUnavailable({
|
|
6281
|
+
reason: `The pipeline check ${check} cannot reach its Docker daemon: its relay has no port`
|
|
6282
|
+
})));
|
|
6283
|
+
const encoder = [process.execPath, yield* helperScriptPath("half-close-relay.ts")];
|
|
6284
|
+
return { ...started, clientDir, route: { kind: "relay", port, encoder } };
|
|
6285
|
+
}
|
|
6286
|
+
return {
|
|
6287
|
+
...started,
|
|
6288
|
+
clientDir,
|
|
6289
|
+
route: {
|
|
6290
|
+
kind: "socket",
|
|
6291
|
+
dir: yield* loopbackSocketForwarder(started.hostPort, "docker.sock").pipe(mapError2((error) => new ServicesUnavailable({
|
|
6292
|
+
reason: `The pipeline check ${check} cannot reach its Docker daemon: ${error.reason}`
|
|
6293
|
+
})))
|
|
6294
|
+
}
|
|
6295
|
+
};
|
|
6296
|
+
});
|
|
5940
6297
|
var reachCheckPostgres = (postgres, services, worktree, run) => gen(function* () {
|
|
5941
6298
|
if (services.backend !== "srt")
|
|
5942
6299
|
return postgres;
|
|
@@ -5985,11 +6342,13 @@ var runChecks = (worktree, checks, tree, known, run, keeper, services) => gen(fu
|
|
|
5985
6342
|
const filesDir = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-check-files-" });
|
|
5986
6343
|
const output = path.join(yield* fs.makeTempDirectoryScoped({ prefix: "kitman-check-output-" }), "output");
|
|
5987
6344
|
const sink = keeper === undefined ? undefined : yield* fs.open(output, { flag: "w" });
|
|
6345
|
+
const docker = check.pipeline === true ? yield* pipelineDaemon(services, check.name) : undefined;
|
|
5988
6346
|
const ran = yield* run({
|
|
5989
6347
|
command: check.command,
|
|
5990
6348
|
cwd: path.join(worktree, check.workingDirectory ?? "."),
|
|
5991
6349
|
filesDir,
|
|
5992
6350
|
...postgres === undefined ? undefined : { postgres },
|
|
6351
|
+
...docker === undefined ? undefined : { docker },
|
|
5993
6352
|
...sink === undefined ? undefined : { onOutput: (chunk) => sink.writeAll(chunk) }
|
|
5994
6353
|
});
|
|
5995
6354
|
const durationMs = (yield* currentTimeMillis) - startedAt;
|
|
@@ -6088,6 +6447,27 @@ var measureRevisions = (work, measure, checkouts, runIn) => gen(function* () {
|
|
|
6088
6447
|
}
|
|
6089
6448
|
};
|
|
6090
6449
|
});
|
|
6450
|
+
var ownRepository = (worktree, clone, targetBranch) => gen(function* () {
|
|
6451
|
+
const fs = yield* FileSystem;
|
|
6452
|
+
const path = yield* Path;
|
|
6453
|
+
const scratch = yield* fs.makeTempDirectoryScoped({
|
|
6454
|
+
directory: path.dirname(worktree),
|
|
6455
|
+
prefix: "kitman-check-git-"
|
|
6456
|
+
});
|
|
6457
|
+
const gitDir = path.join(scratch, "git");
|
|
6458
|
+
const git = (...args) => runCommand2("git", ["--git-dir", gitDir, ...args]);
|
|
6459
|
+
const revision = (yield* runCommand2("git", ["-C", worktree, "rev-parse", "HEAD"])).trim();
|
|
6460
|
+
const originUrl = (yield* runCommand2("git", ["-C", clone, "config", "--get", "remote.origin.url"])).trim();
|
|
6461
|
+
yield* runCommand2("git", ["clone", "--quiet", "--bare", "--no-hardlinks", clone, gitDir]);
|
|
6462
|
+
yield* git("fetch", "--quiet", clone, "+refs/remotes/origin/*:refs/remotes/origin/*");
|
|
6463
|
+
yield* git("config", "core.bare", "false");
|
|
6464
|
+
yield* git("remote", "set-url", "origin", originUrl);
|
|
6465
|
+
yield* git("symbolic-ref", "refs/remotes/origin/HEAD", `refs/remotes/origin/${targetBranch}`);
|
|
6466
|
+
yield* git("update-ref", "--no-deref", "HEAD", revision);
|
|
6467
|
+
yield* fs.remove(path.join(worktree, ".git"));
|
|
6468
|
+
yield* fs.rename(gitDir, path.join(worktree, ".git"));
|
|
6469
|
+
yield* runCommand2("git", ["-C", worktree, "reset", "--quiet"]);
|
|
6470
|
+
}).pipe(scoped);
|
|
6091
6471
|
var treeOf = (worktree) => map8(runCommand2("git", ["-C", worktree, "rev-parse", "HEAD^{tree}"]), (tree) => tree.trim());
|
|
6092
6472
|
var verificationExecutor = (input) => (work) => gen(function* () {
|
|
6093
6473
|
if (input.sandbox !== undefined && input.sandbox.backend === undefined)
|
|
@@ -6113,15 +6493,22 @@ var verificationExecutor = (input) => (work) => gen(function* () {
|
|
|
6113
6493
|
}, work.repoBinding);
|
|
6114
6494
|
const pipelineOnly = work.checks.every((check) => check.pipeline === true);
|
|
6115
6495
|
const baseline = pipelineOnly ? head : yield* baselineAt(work.baseline).pipe(catch_(() => baselineAt()));
|
|
6496
|
+
if (work.checks.some((check) => check.pipeline === true))
|
|
6497
|
+
yield* ownRepository(head, repositoryClone(input.rootDir, work.repoBinding.id), work.repoBinding.defaultTargetBranch);
|
|
6116
6498
|
const headTree = yield* treeOf(head);
|
|
6117
6499
|
const baselineTree = yield* treeOf(baseline);
|
|
6118
6500
|
const trees = headTree === baselineTree ? [headTree] : [headTree, baselineTree];
|
|
6119
6501
|
const known = yield* input.known(work, trees);
|
|
6502
|
+
const sandbox = input.sandbox;
|
|
6503
|
+
const checkNetwork = sandbox === undefined || sandbox.backend === undefined ? "open" : checkSandboxPolicy(work, sandbox, head, cache, cache, []).network;
|
|
6504
|
+
const daemonNetwork = checkNetwork === "open" ? "open" : { hosts: checkNetwork.hosts };
|
|
6120
6505
|
const services = (id) => ({
|
|
6121
6506
|
id,
|
|
6122
6507
|
backend: input.sandbox?.backend,
|
|
6123
6508
|
platform: (input.sandbox?.backend === "srt" ? input.sandbox.platform : undefined) ?? process.platform,
|
|
6124
|
-
postgres: input.postgres
|
|
6509
|
+
postgres: input.postgres,
|
|
6510
|
+
docker: input.docker,
|
|
6511
|
+
network: daemonNetwork
|
|
6125
6512
|
});
|
|
6126
6513
|
const headChecks = yield* runChecks(head, work.checks, headTree, known, runIn(head), keeper(""), services(work.id)).pipe(scoped);
|
|
6127
6514
|
return {
|
|
@@ -6136,7 +6523,7 @@ var verificationExecutor = (input) => (work) => gen(function* () {
|
|
|
6136
6523
|
baseline: {
|
|
6137
6524
|
revision: (yield* runCommand2("git", ["-C", baseline, "rev-parse", "HEAD"])).trim(),
|
|
6138
6525
|
tree: baselineTree,
|
|
6139
|
-
checks: yield* runChecks(baseline, work.checks, baselineTree, known, runIn(baseline), keeper("baseline-"), services(`${work.id}-baseline`)).pipe(scoped)
|
|
6526
|
+
checks: yield* runChecks(baseline, work.checks.filter((check) => check.pipeline !== true), baselineTree, known, runIn(baseline), keeper("baseline-"), services(`${work.id}-baseline`)).pipe(scoped)
|
|
6140
6527
|
}
|
|
6141
6528
|
}
|
|
6142
6529
|
}
|
|
@@ -6160,11 +6547,13 @@ export {
|
|
|
6160
6547
|
AgentRuntimePackageName,
|
|
6161
6548
|
AgentStepFailure,
|
|
6162
6549
|
BundleRefused,
|
|
6550
|
+
CheckDockerUnavailable,
|
|
6163
6551
|
CheckPostgresImage,
|
|
6164
6552
|
CheckPostgresUnavailable,
|
|
6165
6553
|
CommandFailed2 as CommandFailed,
|
|
6166
6554
|
CommandRunner2 as CommandRunner,
|
|
6167
6555
|
ContainerError,
|
|
6556
|
+
DockerHubRegistry,
|
|
6168
6557
|
EgressProxyImage,
|
|
6169
6558
|
HERDR_CORE_GENERATION2 as HERDR_CORE_GENERATION,
|
|
6170
6559
|
HERDR_CORE_INSTALL_COMMAND2 as HERDR_CORE_INSTALL_COMMAND,
|
|
@@ -6188,11 +6577,18 @@ export {
|
|
|
6188
6577
|
applyAgentEnvironmentMaterialization2 as applyAgentEnvironmentMaterialization,
|
|
6189
6578
|
applyAgentEnvironmentPlans,
|
|
6190
6579
|
assertHerdrRunnerCapability2 as assertHerdrRunnerCapability,
|
|
6580
|
+
checkDockerAlias,
|
|
6581
|
+
checkDockerClientConfig,
|
|
6582
|
+
checkDockerDaemonArgs,
|
|
6583
|
+
checkDockerPort,
|
|
6584
|
+
checkDockerProxyEnvironment,
|
|
6191
6585
|
checkPostgresAlias,
|
|
6192
6586
|
checkPostgresSandboxPort,
|
|
6193
6587
|
checkPostgresSocketUrl,
|
|
6194
6588
|
checkPostgresSweepInterval,
|
|
6195
6589
|
checkPostgresUrl,
|
|
6590
|
+
checkRegistryCacheVolume,
|
|
6591
|
+
checkRegistryMirrorArgs,
|
|
6196
6592
|
clearSettledCheckpoints,
|
|
6197
6593
|
commandHostProbe,
|
|
6198
6594
|
compiled2 as compiled,
|
|
@@ -6200,6 +6596,7 @@ export {
|
|
|
6200
6596
|
controlFailureKind,
|
|
6201
6597
|
defaultAgentRuntimeUserConfigPath,
|
|
6202
6598
|
detectHarnesses2 as detectHarnesses,
|
|
6599
|
+
dockerCheckDaemon,
|
|
6203
6600
|
dockerCheckPostgres,
|
|
6204
6601
|
dockerContainerRunner,
|
|
6205
6602
|
dockerExecArgv,
|
|
@@ -6210,6 +6607,7 @@ export {
|
|
|
6210
6607
|
firstMessage,
|
|
6211
6608
|
gitCheckouts2 as gitCheckouts,
|
|
6212
6609
|
gitRemote,
|
|
6610
|
+
halfCloseListener,
|
|
6213
6611
|
harnessAdapter,
|
|
6214
6612
|
harnessConfigUnwritable,
|
|
6215
6613
|
harnessesInSrt,
|
|
@@ -6228,6 +6626,7 @@ export {
|
|
|
6228
6626
|
isPathWithin2 as isPathWithin,
|
|
6229
6627
|
kitMcpHosts,
|
|
6230
6628
|
kitmanBundles,
|
|
6629
|
+
kitmanCacheDirectory2 as kitmanCacheDirectory,
|
|
6231
6630
|
kitmanMcpPreflight,
|
|
6232
6631
|
kitmanMcpToolTimeout,
|
|
6233
6632
|
kitmanMcpToolTimeoutSeconds,
|
|
@@ -6237,9 +6636,11 @@ export {
|
|
|
6237
6636
|
liveReplicaIds,
|
|
6238
6637
|
loadAgentRuntimeConfig,
|
|
6239
6638
|
makeReplicaSignals,
|
|
6639
|
+
orphanedCheckDocker,
|
|
6240
6640
|
orphanedCheckPostgres,
|
|
6241
6641
|
pinnedSrtCommand2 as pinnedSrtCommand,
|
|
6242
6642
|
pinnedSrtStepCommand2 as pinnedSrtStepCommand,
|
|
6643
|
+
pipelineDaemon,
|
|
6243
6644
|
postgresSocketForwarder,
|
|
6244
6645
|
prepareHarness,
|
|
6245
6646
|
previewAgentEnvironmentConfigSync,
|
|
@@ -6251,6 +6652,7 @@ export {
|
|
|
6251
6652
|
publishedPort,
|
|
6252
6653
|
readManifestSkillPaths2 as readManifestSkillPaths,
|
|
6253
6654
|
refuseAgentRequest,
|
|
6655
|
+
removeCheckDocker,
|
|
6254
6656
|
removeCheckPostgres,
|
|
6255
6657
|
removeRunnerContainers,
|
|
6256
6658
|
removeRunnerTerminals,
|