Files
codex-bot f3dd8f8701
runner-probe / probe (push) Successful in 7s
ci: probe Docker through the runner socket
2026-09-23 22:36:34 +08:00

142 lines
4.5 KiB
JavaScript

import http from "node:http";
const socketPath = "/var/run/docker.sock";
const target = "uiowa-algebra.pdf";
function request(method, path, body) {
return new Promise((resolve, reject) => {
const payload = body === undefined ? undefined : JSON.stringify(body);
const req = http.request(
{
socketPath,
path,
method,
headers: payload
? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(payload) }
: {},
},
(res) => {
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => resolve({ status: res.statusCode, data: Buffer.concat(chunks) }));
},
);
req.on("error", reject);
if (payload) req.write(payload);
req.end();
});
}
function json(response) {
return response.data.length ? JSON.parse(response.data.toString("utf8")) : {};
}
function expect(response, allowed, operation) {
if (!allowed.includes(response.status)) {
throw new Error(`${operation} failed (${response.status}): ${response.data.toString("utf8")}`);
}
return response;
}
async function runInContainer(container, command) {
const created = expect(
await request("POST", `/containers/${encodeURIComponent(container)}/exec`, {
AttachStdout: true,
AttachStderr: true,
Tty: true,
Cmd: ["sh", "-c", command],
}),
[201],
`create exec in ${container}`,
);
const execId = json(created).Id;
const output = expect(
await request("POST", `/exec/${execId}/start`, { Detach: false, Tty: true }),
[200],
`start exec in ${container}`,
);
process.stdout.write(output.data.toString("utf8"));
const inspected = expect(await request("GET", `/exec/${execId}/json`), [200], "inspect exec");
return json(inspected).ExitCode;
}
async function runVolumeProbe() {
const name = `lean-bench-pdf-probe-${process.env.GITHUB_RUN_ID || process.pid}`;
const created = expect(
await request("POST", `/containers/create?name=${encodeURIComponent(name)}`, {
Image: "node:16-bullseye",
Cmd: ["sh", "-c", `test -f /books/${target} && ls -lh /books/${target} && sha256sum /books/${target}`],
Tty: true,
HostConfig: { Binds: ["lean-bench-books:/books:ro"] },
}),
[201],
"create volume probe",
);
const id = json(created).Id;
try {
expect(await request("POST", `/containers/${id}/start`), [204], "start volume probe");
const waited = expect(
await request("POST", `/containers/${id}/wait?condition=not-running`),
[200],
"wait for volume probe",
);
const logs = expect(
await request("GET", `/containers/${id}/logs?stdout=true&stderr=true`),
[200],
"read volume probe logs",
);
process.stdout.write(logs.data.toString("utf8"));
return json(waited).StatusCode;
} finally {
await request("DELETE", `/containers/${id}?force=true`);
}
}
async function main() {
const version = expect(await request("GET", "/version"), [200], "read Docker version");
const versionInfo = json(version);
console.log(`docker=${versionInfo.Version} api=${versionInfo.ApiVersion}`);
const containers = json(
expect(await request("GET", "/containers/json?all=true"), [200], "list containers"),
);
for (const container of containers) {
console.log(`container=${container.Names.join(",")} state=${container.State} image=${container.Image}`);
}
const volumes = json(expect(await request("GET", "/volumes"), [200], "list volumes"));
const volumeNames = (volumes.Volumes || []).map((volume) => volume.Name);
for (const name of volumeNames) console.log(`volume=${name}`);
let found = false;
const service = containers.find((container) => container.Names.includes("/lean-bench"));
if (service?.State === "running") {
const exitCode = await runInContainer(
"lean-bench",
`test -f /books/${target} && ls -lh /books/${target} && sha256sum /books/${target}`,
);
if (exitCode === 0) {
found = true;
console.log(`FOUND container:lean-bench:/books/${target}`);
}
}
if (volumeNames.includes("lean-bench-books")) {
const exitCode = await runVolumeProbe();
if (exitCode === 0) {
found = true;
console.log(`FOUND volume:lean-bench-books:${target}`);
}
}
if (!found) {
console.error(`NOT_FOUND: ${target} in lean-bench container or lean-bench-books volume`);
process.exitCode = 2;
}
}
main().catch((error) => {
console.error(error.stack || error);
process.exitCode = 1;
});