Files
orca/config/scripts/ssh-relay-runtime-toolchain.mjs
T
2026-07-14 17:36:56 -04:00

281 lines
9.8 KiB
JavaScript

import { execFile } from 'node:child_process'
import { createHash } from 'node:crypto'
import { createReadStream } from 'node:fs'
import { readdir, realpath, stat } from 'node:fs/promises'
import { createRequire } from 'node:module'
import { dirname, isAbsolute, join, relative } from 'node:path'
import { isDeepStrictEqual, promisify } from 'node:util'
const require = createRequire(import.meta.url)
const execFileAsync = promisify(execFile)
const MAX_TOOL_BYTES = 300 * 1024 * 1024
const TOOL_TIMEOUT_MS = 60_000
const TOOL_OUTPUT_BYTES = 1024 * 1024
const MAX_PACKAGE_FILES = 500
const MAX_PACKAGE_BYTES = 32 * 1024 * 1024
async function sha256File(path) {
const metadata = await stat(path)
if (!metadata.isFile() || metadata.size > MAX_TOOL_BYTES) {
throw new Error(`Runtime build tool is not a bounded regular file: ${path}`)
}
const hash = createHash('sha256')
for await (const chunk of createReadStream(path)) {
hash.update(chunk)
}
return `sha256:${hash.digest('hex')}`
}
async function capture(command, args, { env } = {}) {
try {
return await execFileAsync(command, args, {
encoding: 'utf8',
...(env ? { env: { ...process.env, ...env } } : {}),
maxBuffer: TOOL_OUTPUT_BYTES,
timeout: TOOL_TIMEOUT_MS,
windowsHide: true
})
} catch (error) {
if (typeof error?.stdout === 'string' || typeof error?.stderr === 'string') {
return { stdout: error.stdout ?? '', stderr: error.stderr ?? '' }
}
throw error
}
}
export function selectSshRelayRuntimeToolVersion({ stdout = '', stderr = '' }, pattern) {
const lines = `${stderr}\n${stdout}`
.split(/\r?\n/)
.map((line) => line.trim())
.filter(Boolean)
const version = pattern ? lines.find((line) => pattern.test(line)) : lines[0]
if (!version || Buffer.byteLength(version) > 512) {
const diagnostic = lines.slice(0, 3).join(' | ').slice(0, 512) || '<empty>'
throw new Error(`Runtime build tool did not report a bounded version line: ${diagnostic}`)
}
return version
}
async function locateExecutable(command, { xcrun = false } = {}) {
if (isAbsolute(command)) {
return realpath(command)
}
const locator = xcrun
? ['xcrun', ['--find', command]]
: process.platform === 'win32'
? ['where.exe', [command]]
: ['which', [command]]
const result = await capture(...locator)
const path = result.stdout
.split(/\r?\n/)
.map((line) => line.trim())
.find(Boolean)
if (!path || !isAbsolute(path)) {
throw new Error(`Runtime build tool executable could not be resolved: ${command}`)
}
return realpath(path)
}
async function executableRecord({
command,
args,
versionCommand,
versionArgs,
versionPattern,
windowsFileVersion = false,
xcrun = false
}) {
const path = await locateExecutable(command, { xcrun })
const invocation = windowsFileVersion
? sshRelayRuntimeWindowsFileVersionInvocation(path)
: { command: versionCommand ?? path, args: versionArgs ?? args }
const result = await capture(invocation.command, invocation.args, invocation.options)
return {
version: selectSshRelayRuntimeToolVersion(result, versionPattern),
sha256: await sha256File(path)
}
}
async function packageTreeRecord(name) {
const parsed = require(`${name}/package.json`)
const root = dirname(require.resolve(`${name}/package.json`))
const files = []
let totalBytes = 0
async function visit(directory) {
const entries = await readdir(directory, { withFileTypes: true })
entries.sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
for (const entry of entries) {
const path = join(directory, entry.name)
if (entry.isDirectory()) {
await visit(path)
} else if (entry.isFile()) {
files.push(path)
totalBytes += (await stat(path)).size
} else {
throw new Error(`Runtime build package contains a special entry: ${name}`)
}
if (files.length > MAX_PACKAGE_FILES) {
throw new Error(`Runtime build package exceeds the file-count bound: ${name}`)
}
if (totalBytes > MAX_PACKAGE_BYTES) {
throw new Error(`Runtime build package exceeds the byte bound: ${name}`)
}
}
}
await visit(root)
const hash = createHash('sha256')
for (const path of files) {
hash.update(relative(root, path).replaceAll('\\', '/'))
hash.update('\0')
hash.update(await sha256File(path))
hash.update('\n')
}
return { version: parsed.version, sha256: `sha256:${hash.digest('hex')}`, files: files.length }
}
export function sshRelayRuntimeBuilderIdentity({ gitCommit, env = process.env }) {
if (env.GITHUB_ACTIONS !== 'true') {
return `local://${process.platform}/${process.arch}`
}
if (
!/^[0-9a-f]{40}$/.test(gitCommit) ||
!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(env.GITHUB_REPOSITORY ?? '')
) {
throw new Error('GitHub runtime builder identity is incomplete')
}
const workflow = (env.GITHUB_WORKFLOW_REF ?? '').split('@')[0]
const prefix = `${env.GITHUB_REPOSITORY}/`
if (
!workflow.startsWith(prefix) ||
workflow.slice(prefix.length) !== '.github/workflows/ssh-relay-runtime-artifacts.yml'
) {
throw new Error('GitHub runtime builder workflow identity is malformed')
}
return `https://github.com/${env.GITHUB_REPOSITORY}/blob/${gitCommit}/${workflow.slice(prefix.length)}`
}
export function sshRelayRuntimeRunnerIdentity({ env = process.env } = {}) {
const github = env.GITHUB_ACTIONS === 'true'
const identity = {
os: env.RUNNER_OS ?? process.platform,
architecture: env.RUNNER_ARCH ?? process.arch,
environment: env.RUNNER_ENVIRONMENT ?? (github ? undefined : 'local'),
requestedLabel: env.ORCA_RUNTIME_REQUESTED_RUNNER ?? (github ? undefined : 'local'),
image: {
os: env.ImageOS ?? (github ? undefined : process.platform),
version: env.ImageVersion ?? (github ? undefined : 'local')
}
}
if (
!identity.os ||
!identity.architecture ||
!identity.environment ||
!identity.requestedLabel ||
!identity.image.os ||
!identity.image.version
) {
throw new Error('Runtime runner identity is incomplete')
}
return identity
}
export function sshRelayRuntimeStripVersionProbe(platform) {
// Why: GNU strip is silent/versionless without --version, while Apple strip delegates its
// version identity to the selected Xcode toolchain.
return platform === 'darwin'
? { versionCommand: 'xcodebuild', versionArgs: ['-version'] }
: { args: ['--version'] }
}
export function sshRelayRuntimeWindowsFileVersionInvocation(path) {
return {
command: 'pwsh.exe',
args: [
'-NoLogo',
'-NoProfile',
'-NonInteractive',
'-Command',
"[System.Diagnostics.FileVersionInfo]::GetVersionInfo([Environment]::GetEnvironmentVariable('ORCA_SSH_RELAY_TOOL_PATH')).FileVersion"
],
options: { env: { ORCA_SSH_RELAY_TOOL_PATH: path } }
}
}
export function assertSshRelayRuntimeToolchain(toolchain, tuple) {
const common = ['buildNode', 'bundledNode', 'compiler', 'buildSystem', 'python', 'archive']
const expected = tuple.startsWith('win32-')
? [...common, 'linker', 'nodeAddonApi', 'nodeGyp']
: [...common, 'nodeAddonApi', 'nodeGyp', 'strip']
if (!isDeepStrictEqual(Object.keys(toolchain).sort(), expected.sort())) {
throw new Error(`Runtime toolchain record is incomplete for ${tuple}`)
}
for (const [name, record] of Object.entries(toolchain)) {
const keys = Object.keys(record).sort()
const expectedKeys =
record.files === undefined ? ['sha256', 'version'] : ['files', 'sha256', 'version']
if (
!isDeepStrictEqual(keys, expectedKeys) ||
typeof record.version !== 'string' ||
record.version.length === 0 ||
Buffer.byteLength(record.version) > 512 ||
record.version.includes('\n') ||
!/^sha256:[0-9a-f]{64}$/.test(record.sha256) ||
(record.files !== undefined && (!Number.isSafeInteger(record.files) || record.files <= 0))
) {
throw new Error(`Runtime toolchain record is malformed: ${name}`)
}
}
}
export async function collectSshRelayRuntimeToolchain(nodePath) {
const common = {
bundledNode: await executableRecord({ command: nodePath, args: ['--version'] }),
buildNode: await executableRecord({ command: process.execPath, args: ['--version'] }),
nodeGyp: await packageTreeRecord('node-gyp'),
nodeAddonApi: await packageTreeRecord('node-addon-api')
}
if (process.platform === 'win32') {
const toolchain = {
...common,
compiler: await executableRecord({
command: 'cl.exe',
args: [],
versionPattern: /Compiler Version/i
}),
linker: await executableRecord({
command: 'link.exe',
args: [],
// Why: hosted link.exe is pipe-silent; authenticated PE metadata gives its real version.
windowsFileVersion: true,
versionPattern: /^\d+(?:\.\d+){2,3}(?:\s.*)?$/
}),
buildSystem: await executableRecord({
command: 'msbuild.exe',
args: ['-version', '-nologo']
}),
python: await executableRecord({ command: 'python.exe', args: ['--version'] }),
archive: await packageTreeRecord('yazl')
}
assertSshRelayRuntimeToolchain(toolchain, 'win32-x64')
return toolchain
}
const toolchain = {
...common,
compiler: await executableRecord({
command: process.platform === 'darwin' ? 'clang++' : 'c++',
args: ['--version'],
xcrun: process.platform === 'darwin'
}),
buildSystem: await executableRecord({ command: 'make', args: ['--version'] }),
python: await executableRecord({ command: 'python3', args: ['--version'] }),
archive: await executableRecord({ command: 'xz', args: ['--version'] }),
strip: await executableRecord({
command: 'strip',
...sshRelayRuntimeStripVersionProbe(process.platform),
xcrun: process.platform === 'darwin'
})
}
assertSshRelayRuntimeToolchain(toolchain, `${process.platform}-x64`)
return toolchain
}