fix: replace addressed registry lifecycle with capability owner

This commit is contained in:
2026-08-11 16:03:27 +02:00
parent ca37156a56
commit 56acb397be
7 changed files with 356 additions and 198 deletions
+39 -1
View File
@@ -70,7 +70,7 @@ export class GitWorkspaceRepository {
readonly locksPath: string;
private readonly hooksPath: string;
constructor(private readonly config: WorkspaceRegistryConfig) {
constructor(readonly config: WorkspaceRegistryConfig) {
if (!isAbsolute(config.root)) {
throw new WorkspaceRegistryError("git_unavailable", "Workspace registry root is unavailable");
}
@@ -129,6 +129,44 @@ export class GitWorkspaceRepository {
};
}
private validateRevision(revision: string): void {
if (!/^[0-9a-f]{40}$/.test(revision)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace revision is invalid");
}
async workspacePathsAt(revision: string): Promise<string[]> {
this.validateRevision(revision);
const output = await this.git(["ls-tree", "-r", "--name-only", revision, "--", "workspaces"]);
const paths = output.trim() === "" ? [] : output.trim().split("\n");
for (const path of paths) if (!/^workspaces\/[a-z][a-z0-9-]{2,62}\.yaml$/.test(path)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace repository contains an invalid path");
return paths;
}
async readWorkspaceAt(revision: string, path: string): Promise<string> {
this.validateRevision(revision);
if (!/^workspaces\/[a-z][a-z0-9-]{2,62}\.yaml$/.test(path)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace repository path is invalid");
return this.git(["show", `${revision}:${path}`]);
}
async blobAt(revision: string, path: string): Promise<string> {
this.validateRevision(revision);
if (!/^workspaces\/[a-z][a-z0-9-]{2,62}\.yaml$/.test(path)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace repository path is invalid");
return (await this.git(["rev-parse", `${revision}:${path}`])).trim();
}
async fetchExact(revision: string): Promise<void> {
this.validateRevision(revision);
if (!this.config.remoteUrl) throw new WorkspaceRegistryError("git_unavailable", "Workspace registry remote is unavailable");
await this.git(["fetch", "--no-tags", "origin", revision]);
}
async ensureRunRef(runId: string, revision: string): Promise<void> {
this.validateRevision(revision);
if (!/^[0-9a-f]{32}$/.test(runId)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace publication run is invalid");
const ref = `refs/thoth/addressed-runs/${runId}/target`;
const current = await this.gitOptional(["rev-parse", "--verify", ref]);
if (current !== undefined && current.trim() !== revision) throw new WorkspaceRegistryError("workspace_conflict", "Workspace publication target conflicts");
if (current === undefined) await this.git(["update-ref", ref, revision]);
}
async runRef(runId: string): Promise<string | undefined> {
if (!/^[0-9a-f]{32}$/.test(runId)) throw new WorkspaceRegistryError("workspace_invalid", "Workspace publication run is invalid");
return (await this.gitOptional(["rev-parse", "--verify", `refs/thoth/addressed-runs/${runId}/target`]))?.trim();
}
async workspacePaths(): Promise<string[]> {
const output = await this.git(["ls-tree", "-r", "--name-only", "HEAD", "--", "workspaces"]);
const paths = output.trim() === "" ? [] : output.trim().split("\n");