Files
orca/config/scripts/run-linux-lid-sleep-assertion-docker.mjs
OrcaWinandm4air ba742a86bb fix(linux): release orphaned processes when their owner exits (#22247)
* fix(linux): release orphaned processes when their owner exits

* fix(linux): handle inhibitor errors until streams close

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-09-22 05:10:03 -07:00

158 lines
4.5 KiB
JavaScript

import { execFileSync, spawnSync } from 'node:child_process'
import { copyFileSync, existsSync, mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { delimiter, dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { build } from 'esbuild'
const repo = resolve(fileURLToPath(new URL('../..', import.meta.url)))
const fixture = join(repo, 'config/docker/linux-lid-sleep-assertion')
const sourcePath = join(repo, 'src/main/linux-lid-sleep-assertion.ts')
const args = process.argv.slice(2)
const options = new Map()
for (let index = 0; index < args.length; index += 2) {
const key = args[index]
const value = args[index + 1]
if (
!['--baseline', '--container'].includes(key) ||
!value ||
value.startsWith('-') ||
options.has(key)
) {
throw new Error(
'Usage: run-linux-lid-sleep-assertion-docker.mjs [--baseline <git-ref>] [--container <name>]'
)
}
options.set(key, value)
}
const baseline = options.get('--baseline')
const suffix = `${process.pid}-${Date.now()}`
const container = options.get('--container') ?? `orca-inhibitor-oracle-${suffix}`
const image = `orca-inhibitor-oracle:${suffix}`
const docker =
process.env.ORCA_DOCKER ??
(existsSync('/Applications/Docker.app/Contents/Resources/bin/docker')
? '/Applications/Docker.app/Contents/Resources/bin/docker'
: 'docker')
const dockerDir = dirname(docker)
const env = {
...process.env,
ORCA_BACKGROUND_LAUNCH: '1',
PATH: `${dockerDir}${delimiter}${process.env.PATH ?? ''}`
}
const platform =
process.env.ORCA_DOCKER_PLATFORM ?? (process.arch === 'arm64' ? 'linux/arm64' : 'linux/amd64')
const temp = mkdtempSync(join(tmpdir(), 'orca-inhibitor-oracle-'))
const remote = `/tmp/orca-inhibitor-oracle-${suffix}`
function runDocker(command, allowFailure = false) {
const result = spawnSync(docker, command, {
cwd: repo,
env,
encoding: 'utf8',
maxBuffer: 16 * 1024 * 1024
})
if (result.error) {
throw result.error
}
if (result.status !== 0 && !allowFailure) {
throw new Error(`docker ${command[0]} failed: ${result.stdout}\n${result.stderr}`)
}
return result
}
async function bundle(mode, ref) {
const oldSource = ref
? execFileSync('git', ['show', `${ref}:src/main/linux-lid-sleep-assertion.ts`], {
cwd: repo,
encoding: 'utf8'
})
: null
await build({
entryPoints: [sourcePath],
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node18',
outfile: join(temp, `${mode}.cjs`),
logLevel: 'warning',
plugins:
oldSource === null
? []
: [
{
name: 'baseline-source',
setup(api) {
api.onLoad({ filter: /linux-lid-sleep-assertion\.ts$/ }, () => ({
contents: oldSource,
loader: 'ts',
resolveDir: dirname(sourcePath)
}))
}
}
]
})
}
try {
await bundle('candidate')
if (baseline) {
await bundle('baseline', baseline)
}
for (const file of ['owner.cjs', 'oracle.cjs']) {
copyFileSync(join(fixture, file), join(temp, file))
}
if (!options.has('--container')) {
runDocker(['build', '--platform', platform, '-t', image, fixture])
runDocker([
'run',
'-d',
'--name',
container,
'--platform',
platform,
'--privileged',
'--cgroupns=host',
'--tmpfs',
'/run',
'--tmpfs',
'/run/lock',
'-v',
'/sys/fs/cgroup:/sys/fs/cgroup:rw',
image
])
}
const deadline = Date.now() + 20000
while (
runDocker(['exec', container, 'systemctl', 'is-active', 'systemd-logind'], true).status !== 0
) {
if (Date.now() >= deadline) {
throw new Error('systemd-logind did not start')
}
await new Promise((resolve) => setTimeout(resolve, 100))
}
runDocker(['exec', container, 'mkdir', remote])
runDocker(['cp', `${temp}/.`, `${container}:${remote}`])
for (const mode of baseline ? ['baseline', 'candidate'] : ['candidate']) {
const result = runDocker([
'exec',
'-e',
'ORCA_BACKGROUND_LAUNCH=1',
container,
'node',
`${remote}/oracle.cjs`,
mode,
`${remote}/${mode}.cjs`
])
process.stdout.write(result.stdout)
process.stderr.write(result.stderr)
}
} finally {
runDocker(['exec', container, 'rm', '-rf', remote], true)
if (!options.has('--container')) {
runDocker(['rm', '-f', container], true)
runDocker(['image', 'rm', image], true)
}
rmSync(temp, { recursive: true, force: true })
}