/** * DockerSupervisor — manages one Docker container per project * * Spawned from runInDocker() when multiple projects are configured. */ import type { ProjectRegistration } from '../types'; import type { DockerRunOptions } from './docker-runner'; export declare class DockerSupervisor { private handles; private updating; private opts; private version; private onAllStopped; private readonly defaultAgentId; /** Per-project agentId updated when the container registers with the API. */ private projectAgentIds; private sigintHandler; private sigtermHandler; constructor(version: string, opts: DockerRunOptions); private projectKey; private getProjectAgentId; private setProjectAgentId; /** * Read the `registered-agent-id` marker file (written by the container * after it registers with the server) and apply it to in-memory state if * it differs from what we already have. * * Single source of truth for the "read marker → compare → update" idiom * that used to be duplicated three times in this class — before a rebuild, * before spawning, and inside the runtime `fs.watch` callback — each with * its own copy of the readFileSync/trim/compare logic and its own risk of * drifting from the other two. * * Reads directly in a try/catch rather than gating on `fs.existsSync` * first: the watch-callback call site can race a rename event against the * container still writing the file, so a plain existsSync-then-read would * reintroduce that TOCTOU gap the original watch-callback's try/catch was * written to avoid. The other two previous call sites only guarded with * `existsSync` (a read failure after that check would have propagated * uncaught); swallowing ENOENT/any read failure here is a deliberate * unification onto the safer of the two prior behaviors, not a no-op * refactor of already-identical code. * * Returns the previous/new id pair when the marker caused an update, or * `null` when the marker is absent, unreadable, empty, or unchanged * (nothing to log). */ private applyRegisteredAgentId; private createProjectApiClient; start(projects: ProjectRegistration[], onStop?: () => void): void; private getImageTag; private rebuildAndRestart; private spawnProject; /** * Stop all running containers and resolve once every `docker stop` command * this issues has actually completed (the container exited, or `docker * stop`'s own `--time` grace period elapsed and it SIGKILLed the * container) — not merely once the commands have been *issued*. * * This is `await`ed by the host-side auto-updater's `stopAllAgents` * callback (`startHostAutoUpdater` in docker-runner.ts, via * `auto-updater.ts`'s `await stopAllAgents()`) before it proceeds to * restart/re-exec the host process. Previously this method spawned * `docker stop` and returned immediately without waiting for it to finish, * so the host's self-update logic would restart itself right after merely * *issuing* the stop command — without knowing whether the up to * `SHUTDOWN_GRACE_PERIOD_SECONDS` grace period it just requested had * actually elapsed or the container had actually exited. The `docker stop` * CLI command itself already blocks until the container exits (or it times * out and SIGKILLs it), so awaiting the spawned process's own exit is * sufficient — no separate polling is needed. */ stopAll(): Promise; } //# sourceMappingURL=docker-supervisor.d.ts.map