Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions scripts/runner.node.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
getBuildLabel,
getBuildMetadata,
getBuildUrl,
getCloudInstanceType,
getCommit,
getDistro,
getDistroVersion,
Expand Down Expand Up @@ -1131,7 +1132,7 @@ async function runTests() {
context: "flaky",
label: title,
style: "warning",
content: `<details><summary><a href="${getFileUrl(title)}"><code>${title}</code></a> - ${reason} <i>(in the parallel batch on ${getBuildLabel()}; passed alone)</i></summary>${detail}</details>`,
content: `<details><summary><a href="${getFileUrl(title)}"><code>${title}</code></a> - ${reason} <i>(in the parallel batch on ${getTestLabel()}; passed alone)</i></summary>${detail}</details>`,
});
}
}
Expand Down Expand Up @@ -2789,10 +2790,19 @@ function addPath(...paths) {
}

/**
* The lane a failure is reported against, plus the machine type the job
* actually ran on when that is known, e.g. ":debian: 13 x64-asan (r7i.2xlarge)".
* The type is what tells a timeout on fallback hardware apart from one on the
* hardware the lane asks for, so it goes in the annotation next to the lane.
* @returns {string | undefined}
*/
function getTestLabel() {
return getBuildLabel()?.replace(" - test-bun", "");
const label = getBuildLabel()?.replace(" - test-bun", "");
if (!label) {
return;
}
const instanceType = getCloudInstanceType();
return instanceType ? `${label} (${instanceType})` : label;
}

/**
Expand Down
81 changes: 80 additions & 1 deletion scripts/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ import {
writeFileSync,
} from "node:fs";
import { connect } from "node:net";
import { hostname, homedir as nodeHomedir, tmpdir as nodeTmpdir, release, userInfo } from "node:os";
import {
availableParallelism,
cpus,
hostname,
homedir as nodeHomedir,
tmpdir as nodeTmpdir,
release,
userInfo,
} from "node:os";
import { basename, dirname, join, relative, resolve } from "node:path";
import { normalize as normalizeWindows } from "node:path/win32";

Expand Down Expand Up @@ -1870,6 +1878,75 @@ export function getPublicIp() {
}
}

/**
* The CPU model and the number of CPUs this process may run on, e.g.
* "Intel(R) Xeon(R) Platinum 8488C x8" or "Apple M2 Ultra x24".
* @returns {string | undefined}
*/
export function getCpuDescription() {
const [cpu] = cpus();
const model = cpu?.model?.replace(/\s+/g, " ").trim();
if (!model) {
return;
}
return `${model} x${availableParallelism()}`;
}

/** @type {string | undefined} "" once looked up and not available */
let cloudInstanceType;

/**
* The instance type the cloud provider actually launched for this machine,
* e.g. "r7i.2xlarge" on EC2 or "Standard_D8s_v5" on Azure. CI asks for one
* type per lane (.buildkite/ci.mjs), but under capacity pressure the
* machine may be a different, slower type, and nothing else in a job log
* records which one it was. Looked up once per process.
* @returns {string | undefined}
*/
export function getCloudInstanceType() {
if (typeof cloudInstanceType !== "string") {
cloudInstanceType = fetchCloudInstanceType() || "";
}
return cloudInstanceType || undefined;
}

/**
* @returns {string | undefined}
*/
function fetchCloudInstanceType() {
// The `cloud` tag scripts/agent.mjs puts on the agents we launch ourselves.
// Anything without it (the darwin fleet, GitHub Actions) is not a machine
// whose type we chose, so there is nothing to compare against and no request.
const cloud = getEnv("BUILDKITE_AGENT_META_DATA_CLOUD", false);
let request;
if (cloud === "aws") {
request = ["http://169.254.169.254/latest/meta-data/instance-type"];
} else if (cloud === "azure") {
request = [
"-H",
"Metadata: true",
"http://169.254.169.254/metadata/instance/compute/vmSize?api-version=2021-02-01&format=text",
];
} else {
return;
}

const { error, stdout } = spawnSync([
"curl",
"-sf",
"--noproxy",
"*",
"--connect-timeout",
"1",
"--max-time",
"3",
...request,
]);
if (!error) {
return stdout.trim() || undefined;
}
}

/**
* @returns {string}
*/
Expand Down Expand Up @@ -3095,8 +3172,10 @@ export function printEnvironment() {
}
console.log("Distro:", getDistro());
console.log("Distro Version:", getDistroVersion());
console.log("CPU:", getCpuDescription());
console.log("Hostname:", getHostname());
if (isCI) {
console.log("Instance Type:", getCloudInstanceType());
console.log("Tailscale IP:", getTailscaleIp());
console.log("Public IP:", getPublicIp());
}
Expand Down