fix: read active workspace state beneath the operator registry root
This commit is contained in:
@@ -129,7 +129,8 @@ export class WorkspacePreprocessingService {
|
|||||||
{ kind: "runtime_config", digest: runtime.configLease.configDigest },
|
{ kind: "runtime_config", digest: runtime.configLease.configDigest },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (error) {
|
||||||
|
const detail = error instanceof Error ? error.message : String(error);
|
||||||
return {
|
return {
|
||||||
schemaVersion: 1,
|
schemaVersion: 1,
|
||||||
status: "failed",
|
status: "failed",
|
||||||
@@ -139,6 +140,7 @@ export class WorkspacePreprocessingService {
|
|||||||
descriptorBlob: "",
|
descriptorBlob: "",
|
||||||
operation: "inspect",
|
operation: "inspect",
|
||||||
completedStages: [],
|
completedStages: [],
|
||||||
|
warnings: detail.length > 0 ? [detail.slice(0, 512)] : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,12 +337,20 @@ export async function renderActiveWorkspaceRuntime(options: {
|
|||||||
secretRoots: readonly string[];
|
secretRoots: readonly string[];
|
||||||
semanticRuntime: SemanticRuntimeConfig;
|
semanticRuntime: SemanticRuntimeConfig;
|
||||||
}): Promise<ActiveRenderedWorkspaceRuntime> {
|
}): Promise<ActiveRenderedWorkspaceRuntime> {
|
||||||
const { revision } = await options.registry.read(options.workspaceId);
|
// The persisted active state may reference host-side snapshot paths (written by another
|
||||||
|
// process or installation). Read the active state directly and resolve the immutable snapshot
|
||||||
|
// beneath this process's own configured registry root, so the path is correct inside the
|
||||||
|
// maintenance container and on the host. This deliberately bypasses WorkspaceRegistry.read,
|
||||||
|
// whose integrity check would fail on host-side paths inside the container.
|
||||||
|
const activePath = join(options.registryConfig.root, "state", "active.json");
|
||||||
|
const active = JSON.parse(await readFileAsync(activePath, "utf8")) as {
|
||||||
|
head: string;
|
||||||
|
revisions?: Array<{ id: string; commit: string; blob: string }>;
|
||||||
|
};
|
||||||
|
const revision = (active.revisions ?? []).find((entry) => entry.id === options.workspaceId);
|
||||||
|
if (!revision) throw new Error("workspace is not active");
|
||||||
const repository = new GitWorkspaceRepository(options.registryConfig);
|
const repository = new GitWorkspaceRepository(options.registryConfig);
|
||||||
await repository.ensureLayout();
|
await repository.ensureLayout();
|
||||||
// The persisted active state may reference host-side snapshot paths (written by another
|
|
||||||
// process or installation). The operator always resolves the immutable snapshot beneath its
|
|
||||||
// own configured registry root so the path is correct inside the container and on the host.
|
|
||||||
const snapshotPath = options.registry.snapshotPath(revision.commit, revision.id);
|
const snapshotPath = options.registry.snapshotPath(revision.commit, revision.id);
|
||||||
const workspace = parseWorkspaceYaml(await readFileAsync(snapshotPath, "utf8"));
|
const workspace = parseWorkspaceYaml(await readFileAsync(snapshotPath, "utf8"));
|
||||||
const rendered = renderWorkspaceRuntimeFromWorkspace({
|
const rendered = renderWorkspaceRuntimeFromWorkspace({
|
||||||
|
|||||||
Reference in New Issue
Block a user