feat: finish the docker plugin (B15)

This commit is contained in:
LukeGus committed 2026-09-24 11:58:20 -05:00
1 parent 0a3f05d99d
commit 993a91c899
167 files changed
+26299 -5136

No files matched your search

+22 -71
View File
@@ -1,82 +1,33 @@
import express, { type Router } from "express";
import type { Router } from "express";
import type { PluginContext } from "@termix/plugin-sdk/backend";
import { setPluginSsh } from "./ssh.js";
import { logger } from "../../../../src/backend/utils/logger.js";
import { AuthManager } from "../../../../src/backend/utils/auth-manager.js";
import { registerDockerContainerRoutes } from "./container-routes.js";
import {
sshSessions,
pendingTOTPSessions,
executeDockerCommand,
} from "./session-manager.js";
import {
DOCKER_TIMESTAMP_RE,
getRequestUserId,
registerDockerSshRoutes,
} from "./routes.js";
import {
closeConsoleServer,
handleConsoleUpgrade,
startConsoleServer,
} from "./console.js";
import { createLogger } from "./helpers.js";
import { createDockerSessions } from "./sessions.js";
import { registerRoutes } from "./routes.js";
import { registerConsole } from "./console.js";
import { registerServices } from "./services.js";
import { normalizeImportedHost } from "./host-settings.js";
let authManagerInstance: ReturnType<typeof AuthManager.getInstance> | null =
null;
export type {
DockerContainerAction,
DockerContainerSummary,
DockerEvent,
DockerEventsV1,
DockerServiceV1,
} from "./services.js";
export async function activate(ctx: PluginContext) {
setPluginSsh(ctx.ssh);
ctx.disposables.add(() => setPluginSsh(null));
// An express app rather than the router directly, so the existing
// register*Routes helpers keep the Application they expect. Core mounts it
// at /plugin-api/docker and runs compression, CORS, cookies, auth and body
// parsing in front of it.
const app = express();
app.use((_req, res, next) => {
res.setHeader("Cache-Control", "no-store");
next();
});
const log = createLogger(ctx.log);
const sessions = createDockerSessions(ctx.schedule, log);
ctx.disposables.add(() => sessions.closeAll());
registerDockerSshRoutes(app);
registerDockerContainerRoutes(app, {
sshSessions,
pendingTOTPSessions,
getRequestUserId,
executeDockerCommand,
dockerTimestampPattern: DOCKER_TIMESTAMP_RE,
});
ctx.http.router<Router>({ bodyLimit: "100mb" }).use(app);
authManagerInstance = AuthManager.getInstance();
try {
await authManagerInstance.initialize();
} catch (err) {
logger.error("Failed to initialize Docker backend", err, {
operation: "startup",
});
}
await startConsoleServer();
// Public because the console authenticates each session over the socket
// itself, where the container and host checks also live.
ctx.ws.upgrade(
"/console",
(request, socket, head) =>
handleConsoleUpgrade(
request as Parameters<typeof handleConsoleUpgrade>[0],
socket as Parameters<typeof handleConsoleUpgrade>[1],
head as Buffer,
),
{ public: true },
);
registerRoutes(ctx.http.router<Router>(), { ctx, sessions, log });
registerConsole(ctx, log);
registerServices(ctx, log);
ctx.registry.provide("docker.hostImportNormalizer", normalizeImportedHost);
ctx.log.info(
"Docker mounted at /plugin-api/docker and /plugin-ws/docker/console",
);
}
export async function deactivate() {
await closeConsoleServer();
authManagerInstance = null;
}
export async function deactivate() {}