Keep checked browser runtime versions independent of authority upgrades

This commit is contained in:
Timothy J. Aveni
2026-10-07 17:03:01 -07:00
parent 391f02f78a
commit 61534d3fb5
3 changed files with 24 additions and 7 deletions
+18 -4
View File
@@ -10,10 +10,16 @@ import {
type CandidateMetadataScope,
} from "./metadata.js";
const rootPattern = /^\/nix\/store\/[a-z0-9]{32}-[^/\s]+$/;
async function readJson(root: string, file: string, scope: CandidateMetadataScope): Promise<any> {
async function readJson(root: string, file: string, scope: CandidateMetadataScope) {
const input = await readCandidateMetadata(join(root, file), scope, 32 * 1024 * 1024);
try {
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.bytes));
return {
value: JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.bytes)),
releaseTree: input.releaseTree,
};
} catch (error) {
input.releaseTree();
throw error;
} finally {
input.releaseInput();
}
@@ -30,6 +36,7 @@ export async function loadCheckedInstallationCandidate(
if (!rootPattern.test(root) || !(await lstat(root)).isDirectory())
throw Error("Candidate must be an immutable Nix output directory");
const scope = (resources.budget ?? candidateMetadataBudget).acquire(resources.owner ?? root);
let releaseValidation = () => {};
try {
// Sequential reads avoid partially rejected Promise.all() work allocating
// after the failed candidate's reservation has been released.
@@ -43,8 +50,13 @@ export async function loadCheckedInstallationCandidate(
"kernel.json",
"queries.json",
"graph-execution.json",
])
values.push(await readJson(root, file, scope));
]) {
const parsed = await readJson(root, file, scope);
values.push(parsed.value);
// candidate.json duplicates the checked plan for validation. Nothing in
// the installed candidate retains this input tree after validation.
if (file === "candidate.json") releaseValidation = parsed.releaseTree;
}
const [candidate, plan, artifacts, source, entryRequest, kernel, queries, graph] = values;
const { executionContracts: _legacyContracts, ...workspace } = candidate;
if (
@@ -149,6 +161,8 @@ export async function loadCheckedInstallationCandidate(
} catch (error) {
scope.release();
throw error;
} finally {
releaseValidation();
}
}