import { Paths } from '../../../utils/index.js'; import { type ServerSpec, type ServerSpecDocument } from '../../../domain/server-spec/ServerSpecDocument.js'; import type { DeleteServerSpecOptions, IServerSpecRepository, LoadedServerSpec, ServerSpecDeleteResult, WriteServerSpecOptions } from '../../../application/ports/outbound/IServerSpecRepository.js'; import { type ServerSpecRenderer } from './DockerComposeRenderer.js'; import type { IContainerRuntimePort } from '../../../application/ports/outbound/IContainerRuntimePort.js'; /** Points where tests step in to interleave another writer; no behaviour in production. */ export declare const serverSpecTestHooks: { /** After every check, right before the re-check that precedes the first write. */ beforeWrite: () => Promise; /** Inside the servers/compose.yml lock, after the fresh read, before the write. */ beforeIncludeWrite: () => Promise; /** How long to wait for another process holding servers/compose.yml. */ includeLockWaitMs: number; /** Before delete moves servers//data/ to worlds/ (#735). */ beforeWorldMove: (_world: string) => Promise; }; /** * IServerSpecRepository on the Docker file layout (#675, ADR-0003 §2-§3): * servers//server.yaml is the definition; config.env, the server * docker-compose.yml and its servers/compose.yml entry are rendered from it. * A server without server.yaml is imported in memory from those files. */ export declare class FileServerSpecRepository implements IServerSpecRepository { private readonly paths; private readonly renderer; private readonly runtime?; private readonly resolveIps; /** * @param runtime asked whether a server is stopped before its world changes; without it such writes are refused (R7). * @param hostIps the host addresses for nip.io router hosts (default: resolveHostIps). */ constructor(paths?: Paths, renderer?: ServerSpecRenderer, runtime?: IContainerRuntimePort | undefined, resolveIps?: () => string[]); list(): Promise; save(spec: ServerSpec): Promise; /** * Remove a server (#735, delete-server.sh steps 2-4): plan its worlds * (#652), drop its servers/compose.yml entry under the servers/compose.yml * lock, move the world inside the server to worlds/ unless deleteWorld * (a failed move puts the entry back), then remove servers/ (what rm * leaves is a warning). Every refusal comes before the first change. * A second delete of the server, from any process, is 'locked' meanwhile. */ delete(name: string, options?: DeleteServerSpecOptions): Promise; /** delete() once the server directory is known to exist. */ private deleteServer; /** * Put the server's servers/compose.yml entry back after a failed move: the * text delete replaced when nobody changed the file since, else the entry * added unless one names it; not when servers//docker-compose.yml is gone. * '' when done, else what happened or how to add it by hand. */ private restoreInclude; /** * servers/compose.yml text without the server's generated entry; 'conflict' * when it does not parse or has a hand-written entry for the server (#735). */ private includeWithout; /** Move servers//data/ to worlds/, adding each to `moved`; on failure report what already moved. */ private moveWorlds; /** * The spec with hand edits of the generated files absorbed (ADR-0003 §3), * or imported in memory when server.yaml is missing. Never writes. */ load(name: string): Promise; /** server.yaml as written, without absorbing edits of the generated files (`mcctl migrate spec --force`). */ loadFile(name: string): Promise; /** * Write server.yaml, then render the generated files (ADR-0003 §2-§3). * Every check runs before the first write. Unchanged files are not written. * All or nothing per file: when a write fails, the files this write already * changed get their earlier content back (or are removed when new), so a * caller undoing its own steps (migrate worlds) matches the files. */ write(doc: ServerSpecDocument, options?: WriteServerSpecOptions): Promise; /** * ADR-0003 R4: when the rendered config.env moves the server's world * (LEVEL or storage), apply ADR-0002 to the snapshot with that config.env: * R1 (no other holder), R7 (every server determined), server stopped. * Uses the snapshot reader directly, not IWorldAssignmentPort, because the * assignment adapter writes through this repository (ADR-0003 §2). * Rejects WorldAssignmentError. */ private checkWorldChange; private importServer; /** The spec before this write: server.yaml, else the import (a refused import blocks unless forced). */ private previous; /** * A new server (ADR-0003 §5): claim servers/ with mkdir, write * server.yaml and the generated files, create data/, logs/ and * servers/global.env, then add the include entry. All or nothing: on any * failure after the claim the entry it added and the directory are * removed, so the same create can be retried at once (#657). */ private create; /** * A new spec's env starts from the bundled template's config.env keys * (minus the managed ones and EXTRA_ARGS, which world.storage renders), in * template order; the document's own values win (create-server.sh copied * the template and changed lines). */ private withTemplateEnv; /** * Run `fn` on servers/compose.yml under servers/.compose.yml.lock. The file * is shared by every server and by CLI and API processes. */ private withIncludeLock; /** * Add the server's servers/compose.yml entry under the lock: read the file * fresh, merge, write, read back and check every entry it had plus ours * (one retry for a writer that ignores the lock). */ private writeInclude; /** Remove the server's generated servers/compose.yml entry under the lock. */ private removeInclude; private protectedWarnings; private renderContext; /** A context that does not read servers/compose.yml: for renders whose include entry is not used. */ private withoutInclude; private parse; /** server.yaml and .bak files hold config values (secrets included): they get the source file's mode. */ private fileMode; private hostIps; } //# sourceMappingURL=FileServerSpecRepository.d.ts.map