Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3796,6 +3796,8 @@ bootstrap routes use this grant, not an Environment ID as authentication. Public
artifact routes contain no credentials. Native bundles must match the Core source
revision and Runtime wire version. Core release qualification consumes the same
three-platform native CI artifacts and includes them in its distribution.
`make check-distribution` exercises catalog assembly with manifests larger than
Node's default subprocess output buffer; catalog reads allow up to 64 MiB.
Bootstrap scripts own platform download/extraction only; installation, startup,
connection verification and Runtime execution remain common. Serialize background
PID inspection and publication so concurrent starts cannot create duplicate daemons.
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ check-microsandbox-provider:

.PHONY: check-distribution build-core-distribution
check-distribution:
node --test scripts/build-native-catalog.test.mjs
go test ./services/core-console -count=1
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/install -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 scripts/core-distribution-manifest.test.py
Expand Down
2 changes: 1 addition & 1 deletion scripts/build-native-catalog.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ await mkdir(output, { recursive: true });
const artifacts = {};
for (const [ci, platform] of Object.entries({ 'Linux-X64': 'linux-amd64', 'macOS-ARM64': 'darwin-arm64', 'Windows-X64': 'windows-amd64' })) {
const archive = resolve(input, `oac-native-installer-${ci}.tar.gz`);
const bundle = JSON.parse(execFileSync('tar', ['-xOzf', archive, './bundle.json'], { encoding: 'utf8' }));
const bundle = JSON.parse(execFileSync('tar', ['-xOzf', archive, './bundle.json'], { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }));
if (bundle.daemon_version !== version || `${bundle.os}-${bundle.arch}` !== platform) throw new Error(`Mismatched native artifact: ${platform}`);
const hash = createHash('sha256');
for await (const chunk of createReadStream(archive)) hash.update(chunk);
Expand Down
35 changes: 35 additions & 0 deletions scripts/build-native-catalog.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { createHash } from 'node:crypto';
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import test from 'node:test';

test('catalog accepts large native manifests and still rejects a foreign revision', async () => {
const directory = await mkdtemp(join(tmpdir(), 'oac-native-catalog-'));
try {
const input = join(directory, 'input');
const output = join(directory, 'output');
const bundle = join(directory, 'bundle');
await Promise.all([mkdir(input), mkdir(bundle)]);
const version = execFileSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).trim();
for (const [ci, os, arch] of [['Linux-X64', 'linux', 'amd64'], ['macOS-ARM64', 'darwin', 'arm64'], ['Windows-X64', 'windows', 'amd64']]) {
await writeFile(join(bundle, 'bundle.json'), JSON.stringify({ daemon_version: version, os, arch, files: { fixture: 'x'.repeat(2 * 1024 * 1024) } }));
execFileSync('tar', ['-czf', join(input, `oac-native-installer-${ci}.tar.gz`), '-C', bundle, './bundle.json']);
}
const script = resolve('scripts/build-native-catalog.mjs');
execFileSync(process.execPath, [script, input, output]);
const catalog = JSON.parse(await readFile(join(output, 'catalog.json'), 'utf8'));
assert.equal(catalog.version, version);
assert.equal(Object.keys(catalog.artifacts).length, 3);
const linux = await readFile(join(input, 'oac-native-installer-Linux-X64.tar.gz'));
assert.deepEqual(await readFile(join(output, 'linux-amd64.tar.gz')), linux);
assert.equal(catalog.artifacts['linux-amd64'].sha256, createHash('sha256').update(linux).digest('hex'));
await writeFile(join(bundle, 'bundle.json'), JSON.stringify({ daemon_version: 'foreign', os: 'linux', arch: 'amd64' }));
execFileSync('tar', ['-czf', join(input, 'oac-native-installer-Linux-X64.tar.gz'), '-C', bundle, './bundle.json']);
assert.throws(() => execFileSync(process.execPath, [script, input, output], { stdio: 'pipe' }), error => error.stderr.toString().includes('Mismatched native artifact'));
} finally {
await rm(directory, { recursive: true, force: true });
}
});