@artenx/dshb 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cordis.patch.yml +9 -9
- package/lib/auth/credentials.d.ts +30 -0
- package/lib/auth/credentials.js +121 -0
- package/lib/auth/credentials.js.map +1 -0
- package/lib/auth/decorate-webserver.d.ts +7 -0
- package/lib/auth/decorate-webserver.js +75 -0
- package/lib/auth/decorate-webserver.js.map +1 -0
- package/lib/auth/gate.d.ts +14 -0
- package/lib/auth/gate.js +45 -0
- package/lib/auth/gate.js.map +1 -0
- package/lib/auth/index.d.ts +8 -0
- package/lib/auth/index.js +51 -0
- package/lib/auth/index.js.map +1 -0
- package/lib/auth/login-page.d.ts +5 -0
- package/lib/auth/login-page.js +87 -0
- package/lib/auth/login-page.js.map +1 -0
- package/lib/auth/loopback-compat.d.ts +6 -0
- package/lib/auth/loopback-compat.js +94 -0
- package/lib/auth/loopback-compat.js.map +1 -0
- package/lib/auth/loopback.d.ts +7 -0
- package/lib/auth/loopback.js +24 -0
- package/lib/auth/loopback.js.map +1 -0
- package/lib/auth/ratelimit.d.ts +11 -0
- package/lib/auth/ratelimit.js +37 -0
- package/lib/auth/ratelimit.js.map +1 -0
- package/lib/auth/routes.d.ts +8 -0
- package/lib/auth/routes.js +224 -0
- package/lib/auth/routes.js.map +1 -0
- package/lib/auth/session.d.ts +11 -0
- package/lib/auth/session.js +52 -0
- package/lib/auth/session.js.map +1 -0
- package/lib/auth/startup.d.ts +15 -0
- package/lib/auth/startup.js +68 -0
- package/lib/auth/startup.js.map +1 -0
- package/lib/auth/webserver.d.ts +18 -0
- package/lib/auth/webserver.js +60 -0
- package/lib/auth/webserver.js.map +1 -0
- package/lib/client.js +2770 -0
- package/lib/client.js.map +1 -0
- package/lib/connection-sIX25pkS.d.ts +46 -0
- package/lib/core/audit.d.ts +16 -0
- package/lib/core/audit.js +38 -0
- package/lib/core/audit.js.map +1 -0
- package/lib/core/index.d.ts +8 -0
- package/lib/core/index.js +77 -0
- package/lib/core/index.js.map +1 -0
- package/lib/core/known-hosts.d.ts +23 -0
- package/lib/core/known-hosts.js +76 -0
- package/lib/core/known-hosts.js.map +1 -0
- package/lib/core/node-registry.d.ts +108 -0
- package/lib/core/node-registry.js +191 -0
- package/lib/core/node-registry.js.map +1 -0
- package/lib/core/routes.d.ts +9 -0
- package/lib/core/routes.js +404 -0
- package/lib/core/routes.js.map +1 -0
- package/lib/core/ssh-config.d.ts +23 -0
- package/lib/core/ssh-config.js +70 -0
- package/lib/core/ssh-config.js.map +1 -0
- package/lib/core/test.d.ts +43 -0
- package/lib/core/test.js +116 -0
- package/lib/core/test.js.map +1 -0
- package/lib/core/workspace-bindings.d.ts +28 -0
- package/lib/core/workspace-bindings.js +86 -0
- package/lib/core/workspace-bindings.js.map +1 -0
- package/lib/core/workspaces.d.ts +9 -0
- package/lib/core/workspaces.js +283 -0
- package/lib/core/workspaces.js.map +1 -0
- package/lib/exec-docker/daemon-runner.d.ts +21 -0
- package/lib/exec-docker/daemon-runner.js +326 -0
- package/lib/exec-docker/daemon-runner.js.map +1 -0
- package/lib/exec-docker/docker-backend.d.ts +48 -0
- package/lib/exec-docker/docker-backend.js +1 -0
- package/lib/exec-docker/docker-client.d.ts +46 -0
- package/lib/exec-docker/docker-client.js +302 -0
- package/lib/exec-docker/docker-client.js.map +1 -0
- package/lib/exec-docker/docker-routes.d.ts +6 -0
- package/lib/exec-docker/docker-routes.js +215 -0
- package/lib/exec-docker/docker-routes.js.map +1 -0
- package/lib/exec-docker/fs-provider.d.ts +50 -0
- package/lib/exec-docker/fs-provider.js +92 -0
- package/lib/exec-docker/fs-provider.js.map +1 -0
- package/lib/exec-docker/host-runner.d.ts +29 -0
- package/lib/exec-docker/host-runner.js +17 -0
- package/lib/exec-docker/host-runner.js.map +1 -0
- package/lib/exec-docker/index.d.ts +21 -0
- package/lib/exec-docker/index.js +137 -0
- package/lib/exec-docker/index.js.map +1 -0
- package/lib/exec-docker/process-provider.d.ts +20 -0
- package/lib/exec-docker/process-provider.js +75 -0
- package/lib/exec-docker/process-provider.js.map +1 -0
- package/lib/exec-docker/provision.d.ts +24 -0
- package/lib/exec-docker/provision.js +103 -0
- package/lib/exec-docker/provision.js.map +1 -0
- package/lib/exec-docker/remote-docker-cli.d.ts +52 -0
- package/lib/exec-docker/remote-docker-cli.js +155 -0
- package/lib/exec-docker/remote-docker-cli.js.map +1 -0
- package/lib/exec-docker/world.d.ts +37 -0
- package/lib/exec-docker/world.js +62 -0
- package/lib/exec-docker/world.js.map +1 -0
- package/lib/exec-ssh/connection-pool.d.ts +25 -0
- package/lib/exec-ssh/connection-pool.js +54 -0
- package/lib/exec-ssh/connection-pool.js.map +1 -0
- package/lib/exec-ssh/connection.d.ts +2 -0
- package/lib/exec-ssh/connection.js +125 -0
- package/lib/exec-ssh/connection.js.map +1 -0
- package/lib/exec-ssh/env-scrub.d.ts +7 -0
- package/lib/exec-ssh/env-scrub.js +40 -0
- package/lib/exec-ssh/env-scrub.js.map +1 -0
- package/lib/exec-ssh/executor.d.ts +46 -0
- package/lib/exec-ssh/executor.js +212 -0
- package/lib/exec-ssh/executor.js.map +1 -0
- package/lib/exec-ssh/fs-provider.d.ts +50 -0
- package/lib/exec-ssh/fs-provider.js +92 -0
- package/lib/exec-ssh/fs-provider.js.map +1 -0
- package/lib/exec-ssh/index.d.ts +16 -0
- package/lib/exec-ssh/index.js +30 -0
- package/lib/exec-ssh/index.js.map +1 -0
- package/lib/exec-ssh/process-provider.d.ts +20 -0
- package/lib/exec-ssh/process-provider.js +75 -0
- package/lib/exec-ssh/process-provider.js.map +1 -0
- package/lib/exec-ssh/runner.d.ts +13 -0
- package/lib/exec-ssh/runner.js +62 -0
- package/lib/exec-ssh/runner.js.map +1 -0
- package/lib/exec-ssh/world.d.ts +79 -0
- package/lib/exec-ssh/world.js +95 -0
- package/lib/exec-ssh/world.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/router/decorate-fs.d.ts +6 -0
- package/lib/router/decorate-fs.js +78 -0
- package/lib/router/decorate-fs.js.map +1 -0
- package/lib/router/decorate-shell.d.ts +6 -0
- package/lib/router/decorate-shell.js +35 -0
- package/lib/router/decorate-shell.js.map +1 -0
- package/lib/router/decorate-subprocess.d.ts +6 -0
- package/lib/router/decorate-subprocess.js +35 -0
- package/lib/router/decorate-subprocess.js.map +1 -0
- package/lib/router/index.d.ts +10 -0
- package/lib/router/index.js +21 -0
- package/lib/router/index.js.map +1 -0
- package/lib/router/resolve.d.ts +22 -0
- package/lib/router/resolve.js +45 -0
- package/lib/router/resolve.js.map +1 -0
- package/lib/router/router-fs.d.ts +25 -0
- package/lib/router/router-fs.js +64 -0
- package/lib/router/router-fs.js.map +1 -0
- package/lib/router/router-shell.d.ts +14 -0
- package/lib/router/router-shell.js +36 -0
- package/lib/router/router-shell.js.map +1 -0
- package/lib/router/router-subprocess.d.ts +13 -0
- package/lib/router/router-subprocess.js +33 -0
- package/lib/router/router-subprocess.js.map +1 -0
- package/lib/router/types.d.ts +2 -0
- package/lib/router/types.js +1 -0
- package/lib/types-C0TtEO7z.d.ts +67 -0
- package/lib/ui/decorate-picker.d.ts +6 -0
- package/lib/ui/decorate-picker.js +58 -0
- package/lib/ui/decorate-picker.js.map +1 -0
- package/lib/ui/index.d.ts +8 -0
- package/lib/ui/index.js +11 -0
- package/lib/ui/index.js.map +1 -0
- package/lib/ui/picker.d.ts +10 -0
- package/lib/ui/picker.js +58 -0
- package/lib/ui/picker.js.map +1 -0
- package/package.json +150 -10
- package/LICENSE +0 -21
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
//#region src/exec-docker/fs-provider.ts
|
|
2
|
+
var DockerFileSystem = class {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
async resolve(path) {
|
|
8
|
+
return path;
|
|
9
|
+
}
|
|
10
|
+
processPath(target) {
|
|
11
|
+
return target;
|
|
12
|
+
}
|
|
13
|
+
fileUrl(target) {
|
|
14
|
+
return `file://${target}`;
|
|
15
|
+
}
|
|
16
|
+
contains(parent, child) {
|
|
17
|
+
return child === parent || child.startsWith(`${parent}/`);
|
|
18
|
+
}
|
|
19
|
+
async stat(target, _signal) {
|
|
20
|
+
return this.client.stat(target);
|
|
21
|
+
}
|
|
22
|
+
async lstat(path, _opts, _signal) {
|
|
23
|
+
return this.client.stat(path);
|
|
24
|
+
}
|
|
25
|
+
async readText(target, _signal) {
|
|
26
|
+
return (await this.client.readFile(target)).toString("utf8");
|
|
27
|
+
}
|
|
28
|
+
async streamText(target, _signal) {
|
|
29
|
+
const text = (await this.client.readFile(target)).toString("utf8");
|
|
30
|
+
return (async function* () {
|
|
31
|
+
yield text;
|
|
32
|
+
})();
|
|
33
|
+
}
|
|
34
|
+
async readBytes(target, _signal, maxBytes) {
|
|
35
|
+
const slice = (await this.client.readFile(target)).subarray(0, maxBytes);
|
|
36
|
+
return new Uint8Array(slice.buffer, slice.byteOffset, slice.byteLength);
|
|
37
|
+
}
|
|
38
|
+
async listDir(target, _signal) {
|
|
39
|
+
return (await this.client.listDir(target)).map((e) => ({
|
|
40
|
+
name: e.name,
|
|
41
|
+
path: `${target.replace(/\/+$/, "")}/${e.name}`,
|
|
42
|
+
isDirectory: e.isDir,
|
|
43
|
+
isFile: e.isFile,
|
|
44
|
+
isSymlink: e.isSymlink,
|
|
45
|
+
size: e.size,
|
|
46
|
+
mtime: e.mtime
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
async writeText(target, content, _expected, _signal, _policy) {
|
|
50
|
+
const normalizeLf = (s) => s.replace(/\r\n/g, "\n");
|
|
51
|
+
const beforeInfo = await this.client.stat(target);
|
|
52
|
+
let before = null;
|
|
53
|
+
if (beforeInfo?.isFile) try {
|
|
54
|
+
before = normalizeLf((await this.client.readFile(target)).toString("utf8"));
|
|
55
|
+
} catch {
|
|
56
|
+
before = null;
|
|
57
|
+
}
|
|
58
|
+
const after = normalizeLf(content);
|
|
59
|
+
await this.client.writeFile(target, content);
|
|
60
|
+
const afterInfo = await this.client.stat(target);
|
|
61
|
+
const version = `${afterInfo?.size ?? content.length}:${afterInfo?.mtime ?? Date.now()}`;
|
|
62
|
+
return {
|
|
63
|
+
operation: before === null ? "create" : "update",
|
|
64
|
+
version,
|
|
65
|
+
before,
|
|
66
|
+
after
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async editText(target, edit, _expected, _signal, _policy) {
|
|
70
|
+
const normalizeLf = (s) => s.replace(/\r\n/g, "\n");
|
|
71
|
+
const before = normalizeLf((await this.client.readFile(target)).toString("utf8"));
|
|
72
|
+
const req = edit;
|
|
73
|
+
const oldString = normalizeLf(String(req.oldString ?? ""));
|
|
74
|
+
if (oldString.length === 0) throw new Error("edit oldString must be non-empty");
|
|
75
|
+
const newString = normalizeLf(String(req.newString ?? ""));
|
|
76
|
+
const matches = before.split(oldString).length - 1;
|
|
77
|
+
if (matches === 0) throw new Error("edit oldString not found in file");
|
|
78
|
+
if (!req.replaceAll && matches !== 1) throw new Error(`edit oldString matched ${matches} times; expected exactly one`);
|
|
79
|
+
const after = req.replaceAll ? before.split(oldString).join(newString) : before.replace(oldString, newString);
|
|
80
|
+
await this.client.writeFile(target, after);
|
|
81
|
+
const afterInfo = await this.client.stat(target);
|
|
82
|
+
return {
|
|
83
|
+
version: `${afterInfo?.size ?? after.length}:${afterInfo?.mtime ?? Date.now()}`,
|
|
84
|
+
before,
|
|
85
|
+
after
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { DockerFileSystem };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=fs-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-provider.js","names":[],"sources":["../../src/exec-docker/fs-provider.ts"],"sourcesContent":["import type { DockerBackend } from './docker-backend.js'\n\nexport class DockerFileSystem {\n constructor(private readonly client: DockerBackend) {}\n\n async resolve(path: string): Promise<string> {\n return path\n }\n\n processPath(target: string): string {\n return target\n }\n\n fileUrl(target: string): string {\n return `file://${target}`\n }\n\n contains(parent: string, child: string): boolean {\n return child === parent || child.startsWith(`${parent}/`)\n }\n\n async stat(target: string, _signal?: AbortSignal): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean } | undefined> {\n return this.client.stat(target)\n }\n\n async lstat(path: string, _opts?: { cwd?: string }, _signal?: AbortSignal): Promise<{ size: number; mtime: number; isDirectory: boolean; isFile: boolean } | undefined> {\n return this.client.stat(path)\n }\n\n async readText(target: string, _signal?: AbortSignal): Promise<string> {\n const data = await this.client.readFile(target)\n return data.toString('utf8')\n }\n\n async streamText(target: string, _signal?: AbortSignal): Promise<AsyncIterable<string>> {\n const data = await this.client.readFile(target)\n const text = data.toString('utf8')\n return (async function* () {\n yield text\n })()\n }\n\n async readBytes(target: string, _signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array> {\n const data = await this.client.readFile(target)\n const slice = data.subarray(0, maxBytes)\n return new Uint8Array(slice.buffer, slice.byteOffset, slice.byteLength)\n }\n\n async listDir(target: string, _signal?: AbortSignal): Promise<Array<{ name: string; path: string; isDirectory: boolean; isFile: boolean; isSymlink: boolean; size: number; mtime: number }>> {\n const entries = await this.client.listDir(target)\n return entries.map((e) => ({\n name: e.name,\n path: `${target.replace(/\\/+$/, '')}/${e.name}`,\n isDirectory: e.isDir,\n isFile: e.isFile,\n isSymlink: e.isSymlink,\n size: e.size,\n mtime: e.mtime,\n }))\n }\n\n async writeText(target: string, content: string, _expected?: unknown, _signal?: AbortSignal, _policy?: unknown): Promise<{ operation: 'create' | 'update'; version: string; before: string | null; after: string }> {\n const normalizeLf = (s: string) => s.replace(/\\r\\n/g, '\\n')\n const beforeInfo = await this.client.stat(target)\n let before: string | null = null\n if (beforeInfo?.isFile) {\n try {\n before = normalizeLf((await this.client.readFile(target)).toString('utf8'))\n } catch {\n before = null\n }\n }\n const after = normalizeLf(content)\n await this.client.writeFile(target, content)\n const afterInfo = await this.client.stat(target)\n const version = `${afterInfo?.size ?? content.length}:${afterInfo?.mtime ?? Date.now()}`\n return { operation: before === null ? 'create' : 'update', version, before, after }\n }\n\n async editText(target: string, edit: unknown, _expected?: unknown, _signal?: AbortSignal, _policy?: unknown): Promise<{ version: string; before: string; after: string }> {\n const normalizeLf = (s: string) => s.replace(/\\r\\n/g, '\\n')\n const before = normalizeLf((await this.client.readFile(target)).toString('utf8'))\n const req = edit as { oldString: string; newString: string; replaceAll: boolean }\n const oldString = normalizeLf(String(req.oldString ?? ''))\n if (oldString.length === 0) throw new Error('edit oldString must be non-empty')\n const newString = normalizeLf(String(req.newString ?? ''))\n const matches = before.split(oldString).length - 1\n if (matches === 0) throw new Error('edit oldString not found in file')\n if (!req.replaceAll && matches !== 1) throw new Error(`edit oldString matched ${matches} times; expected exactly one`)\n const after = req.replaceAll ? before.split(oldString).join(newString) : before.replace(oldString, newString)\n await this.client.writeFile(target, after)\n const afterInfo = await this.client.stat(target)\n const version = `${afterInfo?.size ?? after.length}:${afterInfo?.mtime ?? Date.now()}`\n return { version, before, after }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HostCommandRunner } from "./docker-backend.js";
|
|
2
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
//#region src/exec-docker/host-runner.d.ts
|
|
4
|
+
interface SshExecutorLike {
|
|
5
|
+
exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{
|
|
6
|
+
code: number;
|
|
7
|
+
stdout: string;
|
|
8
|
+
stderr: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
declare function sshRunner(executor: SshExecutorLike): HostCommandRunner;
|
|
12
|
+
interface DockerNodeLike {
|
|
13
|
+
id: string;
|
|
14
|
+
type: string;
|
|
15
|
+
ssh?: unknown;
|
|
16
|
+
docker?: {
|
|
17
|
+
containerId?: string;
|
|
18
|
+
image?: string;
|
|
19
|
+
mode?: string;
|
|
20
|
+
resources?: {
|
|
21
|
+
cpus?: number;
|
|
22
|
+
memoryMB?: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
declare function resolveHostRunner(ctx: Context, node: DockerNodeLike): Promise<HostCommandRunner | undefined>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { DockerNodeLike, resolveHostRunner, sshRunner };
|
|
29
|
+
//# sourceMappingURL=host-runner.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dockerDaemonRunner } from "./daemon-runner.js";
|
|
2
|
+
//#region src/exec-docker/host-runner.ts
|
|
3
|
+
function sshRunner(executor) {
|
|
4
|
+
return { run: async (argv, cwd) => executor.exec(argv, cwd ?? "/") };
|
|
5
|
+
}
|
|
6
|
+
async function resolveHostRunner(ctx, node) {
|
|
7
|
+
if (node.type === "remote-docker") {
|
|
8
|
+
const sshWorld = await ctx.get("dshbSshWorlds")?.ensure(node.id);
|
|
9
|
+
if (!sshWorld) return void 0;
|
|
10
|
+
return sshRunner(sshWorld.executor);
|
|
11
|
+
}
|
|
12
|
+
return dockerDaemonRunner();
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { resolveHostRunner, sshRunner };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=host-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-runner.js","names":[],"sources":["../../src/exec-docker/host-runner.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport type { HostCommandRunner } from './docker-backend.js'\nimport { dockerDaemonRunner } from './daemon-runner.js'\n\ninterface SshExecutorLike {\n exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport function sshRunner(executor: SshExecutorLike): HostCommandRunner {\n return {\n run: async (argv, cwd) => executor.exec(argv, cwd ?? '/'),\n }\n}\n\nexport interface DockerNodeLike {\n id: string\n type: string\n ssh?: unknown\n docker?: { containerId?: string; image?: string; mode?: string; resources?: { cpus?: number; memoryMB?: number } }\n}\n\nexport async function resolveHostRunner(ctx: Context, node: DockerNodeLike): Promise<HostCommandRunner | undefined> {\n if (node.type === 'remote-docker') {\n const sshWorlds = ctx.get('dshbSshWorlds') as { ensure(nodeId: string): Promise<{ executor: SshExecutorLike } | undefined> } | undefined\n const sshWorld = await sshWorlds?.ensure(node.id)\n if (!sshWorld) return undefined\n return sshRunner(sshWorld.executor)\n }\n return dockerDaemonRunner()\n}\n"],"mappings":";;AAQA,SAAgB,UAAU,UAA8C;CACtE,OAAO,EACL,KAAK,OAAO,MAAM,QAAQ,SAAS,KAAK,MAAM,OAAO,GAAG,EAC1D;AACF;AASA,eAAsB,kBAAkB,KAAc,MAA8D;CAClH,IAAI,KAAK,SAAS,iBAAiB;EAEjC,MAAM,WAAW,MADC,IAAI,IAAI,eACK,CAAC,EAAE,OAAO,KAAK,EAAE;EAChD,IAAI,CAAC,UAAU,OAAO,KAAA;EACtB,OAAO,UAAU,SAAS,QAAQ;CACpC;CACA,OAAO,mBAAmB;AAC5B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DockerBackend, HostCommandRunner } from "./docker-backend.js";
|
|
2
|
+
import { DockerClient } from "./docker-client.js";
|
|
3
|
+
import { DockerFileSystem } from "./fs-provider.js";
|
|
4
|
+
import { RemoteDockerCli } from "./remote-docker-cli.js";
|
|
5
|
+
import { DockerShellExecutor, DockerSubprocessRuntime } from "./process-provider.js";
|
|
6
|
+
import { DockerExecutionWorld, DockerWorldRegistry } from "./world.js";
|
|
7
|
+
import { ProvisionConfig, ProvisionResult, ProvisionStage, listContainers, provisionContainer, removeContainer } from "./provision.js";
|
|
8
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
9
|
+
//#region src/exec-docker/index.d.ts
|
|
10
|
+
declare const name = "dshb-exec-docker";
|
|
11
|
+
declare const inject: string[];
|
|
12
|
+
interface ProvisionStatus {
|
|
13
|
+
state: 'provisioning' | 'ready' | 'failed';
|
|
14
|
+
error?: string;
|
|
15
|
+
containerId?: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
declare function apply(ctx: Context): void;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { type DockerBackend, DockerClient, DockerExecutionWorld, DockerFileSystem, DockerShellExecutor, DockerSubprocessRuntime, DockerWorldRegistry, type HostCommandRunner, type ProvisionConfig, type ProvisionResult, type ProvisionStage, ProvisionStatus, RemoteDockerCli, apply, inject, listContainers, name, provisionContainer, removeContainer };
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { sharedWorldResolver } from "../router/resolve.js";
|
|
2
|
+
import { DockerClient } from "./docker-client.js";
|
|
3
|
+
import { RemoteDockerCli } from "./remote-docker-cli.js";
|
|
4
|
+
import { DockerFileSystem } from "./fs-provider.js";
|
|
5
|
+
import { DockerShellExecutor, DockerSubprocessRuntime } from "./process-provider.js";
|
|
6
|
+
import { DockerExecutionWorld, DockerWorldRegistry } from "./world.js";
|
|
7
|
+
import { listContainers, provisionContainer, removeContainer } from "./provision.js";
|
|
8
|
+
import { resolveHostRunner } from "./host-runner.js";
|
|
9
|
+
import { registerDockerRoutes } from "./docker-routes.js";
|
|
10
|
+
//#region src/exec-docker/index.ts
|
|
11
|
+
const name = "dshb-exec-docker";
|
|
12
|
+
const inject = ["nodeRegistry", "webServer"];
|
|
13
|
+
function apply(ctx) {
|
|
14
|
+
const worlds = new DockerWorldRegistry();
|
|
15
|
+
const provisionStatuses = /* @__PURE__ */ new Map();
|
|
16
|
+
ctx.provide("dshbDockerWorlds", worlds);
|
|
17
|
+
sharedWorldResolver().setRegistry({ get: (nodeId) => worlds.get(nodeId) });
|
|
18
|
+
ctx.provide("dshbDockerWorldsGeneric", { ensure: async (nodeId) => {
|
|
19
|
+
const node = ctx.get("nodeRegistry")?.get(nodeId);
|
|
20
|
+
if (!node) return void 0;
|
|
21
|
+
if (node.type === "local-docker" && node.docker?.containerId) return worlds.ensure(nodeId, new DockerClient(node.docker.containerId));
|
|
22
|
+
if (node.type === "remote-docker" && node.docker?.containerId && node.ssh) {
|
|
23
|
+
if (!ctx.get("dshbSshPool")) return void 0;
|
|
24
|
+
const sshWorlds = ctx.get("dshbSshWorlds");
|
|
25
|
+
if (!sshWorlds) return void 0;
|
|
26
|
+
const sshWorld = await sshWorlds.ensure(nodeId);
|
|
27
|
+
if (!sshWorld) return void 0;
|
|
28
|
+
return worlds.ensure(nodeId, new RemoteDockerCli(sshWorld.executor, node.docker.containerId));
|
|
29
|
+
}
|
|
30
|
+
} });
|
|
31
|
+
ctx.provide("dshbDockerProvisioner", {
|
|
32
|
+
provision: async (nodeId) => {
|
|
33
|
+
const node = ctx.get("nodeRegistry")?.get(nodeId);
|
|
34
|
+
if (!node) throw new Error(`node ${nodeId} not found`);
|
|
35
|
+
if (node.type !== "local-docker" && node.type !== "remote-docker") throw new Error("节点不是 Docker 类型");
|
|
36
|
+
const image = node.docker?.image;
|
|
37
|
+
if (!image) throw new Error("节点未配置镜像");
|
|
38
|
+
const runner = await resolveHostRunner(ctx, node);
|
|
39
|
+
if (!runner) throw new Error("节点执行通道未就绪");
|
|
40
|
+
const name = `dshb-${nodeId}`;
|
|
41
|
+
provisionStatuses.set(nodeId, {
|
|
42
|
+
state: "provisioning",
|
|
43
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
const result = await provisionContainer(runner, {
|
|
47
|
+
image,
|
|
48
|
+
cpus: node.docker?.resources?.cpus,
|
|
49
|
+
memoryMB: node.docker?.resources?.memoryMB,
|
|
50
|
+
name
|
|
51
|
+
});
|
|
52
|
+
await ctx.get("nodeRegistry")?.update(nodeId, { docker: {
|
|
53
|
+
...node.docker,
|
|
54
|
+
containerId: result.containerId,
|
|
55
|
+
mode: "managed"
|
|
56
|
+
} });
|
|
57
|
+
provisionStatuses.set(nodeId, {
|
|
58
|
+
state: "ready",
|
|
59
|
+
containerId: result.containerId,
|
|
60
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
61
|
+
});
|
|
62
|
+
return result;
|
|
63
|
+
} catch (err) {
|
|
64
|
+
provisionStatuses.set(nodeId, {
|
|
65
|
+
state: "failed",
|
|
66
|
+
error: err instanceof Error ? err.message : String(err),
|
|
67
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
68
|
+
});
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
status: (nodeId) => provisionStatuses.get(nodeId)
|
|
73
|
+
});
|
|
74
|
+
ctx.provide("dshbDockerTester", { test: async (node) => {
|
|
75
|
+
try {
|
|
76
|
+
const runner = await resolveHostRunner(ctx, node);
|
|
77
|
+
if (!runner) return {
|
|
78
|
+
ok: false,
|
|
79
|
+
reachable: false,
|
|
80
|
+
error: "执行通道未就绪",
|
|
81
|
+
category: "network"
|
|
82
|
+
};
|
|
83
|
+
const info = await runner.run([
|
|
84
|
+
"docker",
|
|
85
|
+
"info",
|
|
86
|
+
"--format",
|
|
87
|
+
"{{.ServerVersion}}"
|
|
88
|
+
]);
|
|
89
|
+
if (info.code !== 0) return {
|
|
90
|
+
ok: false,
|
|
91
|
+
reachable: false,
|
|
92
|
+
error: `Docker 守护进程不可用: ${(info.stderr || info.stdout).trim()}`,
|
|
93
|
+
category: "unknown"
|
|
94
|
+
};
|
|
95
|
+
const containerId = node.docker?.containerId;
|
|
96
|
+
if (!containerId) return {
|
|
97
|
+
ok: false,
|
|
98
|
+
reachable: false,
|
|
99
|
+
error: "未关联容器,请先创建并启动容器",
|
|
100
|
+
category: "unknown"
|
|
101
|
+
};
|
|
102
|
+
const inspect = await runner.run([
|
|
103
|
+
"docker",
|
|
104
|
+
"inspect",
|
|
105
|
+
"--format",
|
|
106
|
+
"{{.State.Running}}",
|
|
107
|
+
containerId
|
|
108
|
+
]);
|
|
109
|
+
if (inspect.code !== 0) return {
|
|
110
|
+
ok: false,
|
|
111
|
+
reachable: false,
|
|
112
|
+
error: "容器不存在或已删除"
|
|
113
|
+
};
|
|
114
|
+
if (inspect.stdout.trim() !== "true") return {
|
|
115
|
+
ok: false,
|
|
116
|
+
reachable: false,
|
|
117
|
+
error: "容器已停止"
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
ok: true,
|
|
121
|
+
reachable: true
|
|
122
|
+
};
|
|
123
|
+
} catch (err) {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
reachable: false,
|
|
127
|
+
error: err instanceof Error ? err.message : String(err),
|
|
128
|
+
category: "unknown"
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
} });
|
|
132
|
+
registerDockerRoutes(ctx);
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { DockerClient, DockerExecutionWorld, DockerFileSystem, DockerShellExecutor, DockerSubprocessRuntime, DockerWorldRegistry, RemoteDockerCli, apply, inject, listContainers, name, provisionContainer, removeContainer };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/exec-docker/index.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type { DockerBackend } from './docker-backend.js'\nimport { DockerWorldRegistry } from './world.js'\nimport { RemoteDockerCli } from './remote-docker-cli.js'\nimport { DockerClient } from './docker-client.js'\nimport { registerDockerRoutes } from './docker-routes.js'\nimport { listContainers, provisionContainer } from './provision.js'\nimport { resolveHostRunner, type DockerNodeLike } from './host-runner.js'\nimport { sharedWorldResolver } from '../router/resolve.js'\n\ninterface NodeRegistryLike {\n get(id: string): { id: string; type: string; ssh?: { host: string; port: number; username: string }; docker?: { containerId?: string; image?: string; mode?: 'existing' | 'managed'; resources?: { cpus?: number; memoryMB?: number } } } | undefined\n}\n\ninterface SshExecutorLike {\n exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport const name = 'dshb-exec-docker'\n\nexport const inject = ['nodeRegistry', 'webServer']\n\nexport interface ProvisionStatus {\n state: 'provisioning' | 'ready' | 'failed'\n error?: string\n containerId?: string\n updatedAt: string\n}\n\nexport function apply(ctx: Context): void {\n const worlds = new DockerWorldRegistry()\n const provisionStatuses = new Map<string, ProvisionStatus>()\n ctx.provide('dshbDockerWorlds', worlds)\n sharedWorldResolver().setRegistry({\n get: (nodeId: string) => worlds.get(nodeId),\n })\n ctx.provide('dshbDockerWorldsGeneric', {\n ensure: async (nodeId: string) => {\n const nodeRegistry = ctx.get('nodeRegistry') as NodeRegistryLike | undefined\n const node = nodeRegistry?.get(nodeId)\n if (!node) return undefined\n if (node.type === 'local-docker' && node.docker?.containerId) {\n return worlds.ensure(nodeId, new DockerClient(node.docker.containerId))\n }\n if (node.type === 'remote-docker' && node.docker?.containerId && node.ssh) {\n const sshPool = ctx.get('dshbSshPool') as { acquire(target: unknown, secrets: unknown): { getClient(): Promise<unknown> } } | undefined\n if (!sshPool) return undefined\n const sshWorlds = ctx.get('dshbSshWorlds') as { ensure(nodeId: string): Promise<{ executor: SshExecutorLike } | undefined> } | undefined\n if (!sshWorlds) return undefined\n const sshWorld = await sshWorlds.ensure(nodeId)\n if (!sshWorld) return undefined\n return worlds.ensure(nodeId, new RemoteDockerCli(sshWorld.executor, node.docker.containerId))\n }\n return undefined\n },\n })\n ctx.provide('dshbDockerProvisioner', {\n provision: async (nodeId: string) => {\n const nodeRegistry = ctx.get('nodeRegistry') as NodeRegistryLike | undefined\n const node = nodeRegistry?.get(nodeId)\n if (!node) throw new Error(`node ${nodeId} not found`)\n if (node.type !== 'local-docker' && node.type !== 'remote-docker') throw new Error('节点不是 Docker 类型')\n const image = node.docker?.image\n if (!image) throw new Error('节点未配置镜像')\n const runner = await resolveHostRunner(ctx, node)\n if (!runner) throw new Error('节点执行通道未就绪')\n const name = `dshb-${nodeId}`\n provisionStatuses.set(nodeId, { state: 'provisioning', updatedAt: new Date().toISOString() })\n try {\n const result = await provisionContainer(runner, {\n image,\n cpus: node.docker?.resources?.cpus,\n memoryMB: node.docker?.resources?.memoryMB,\n name,\n })\n const registry = ctx.get('nodeRegistry') as { update(id: string, input: { docker: Record<string, unknown> }): Promise<unknown> } | undefined\n await registry?.update(nodeId, { docker: { ...node.docker, containerId: result.containerId, mode: 'managed' } })\n provisionStatuses.set(nodeId, { state: 'ready', containerId: result.containerId, updatedAt: new Date().toISOString() })\n return result\n } catch (err) {\n provisionStatuses.set(nodeId, { state: 'failed', error: err instanceof Error ? err.message : String(err), updatedAt: new Date().toISOString() })\n throw err\n }\n },\n status: (nodeId: string) => provisionStatuses.get(nodeId),\n })\n ctx.provide('dshbDockerTester', {\n test: async (node: DockerNodeLike) => {\n try {\n const runner = await resolveHostRunner(ctx, node)\n if (!runner) return { ok: false, reachable: false, error: '执行通道未就绪', category: 'network' }\n const info = await runner.run(['docker', 'info', '--format', '{{.ServerVersion}}'])\n if (info.code !== 0) return { ok: false, reachable: false, error: `Docker 守护进程不可用: ${(info.stderr || info.stdout).trim()}`, category: 'unknown' }\n const containerId = node.docker?.containerId\n if (!containerId) return { ok: false, reachable: false, error: '未关联容器,请先创建并启动容器', category: 'unknown' }\n const inspect = await runner.run(['docker', 'inspect', '--format', '{{.State.Running}}', containerId])\n if (inspect.code !== 0) return { ok: false, reachable: false, error: '容器不存在或已删除' }\n if (inspect.stdout.trim() !== 'true') return { ok: false, reachable: false, error: '容器已停止' }\n return { ok: true, reachable: true }\n } catch (err) {\n return { ok: false, reachable: false, error: err instanceof Error ? err.message : String(err), category: 'unknown' }\n }\n },\n })\n registerDockerRoutes(ctx)\n}\n\nexport { DockerClient } from './docker-client.js'\nexport { RemoteDockerCli } from './remote-docker-cli.js'\nexport { DockerExecutionWorld, DockerWorldRegistry } from './world.js'\nexport { DockerFileSystem } from './fs-provider.js'\nexport { DockerShellExecutor, DockerSubprocessRuntime } from './process-provider.js'\nexport { provisionContainer, listContainers, removeContainer } from './provision.js'\nexport type { ProvisionConfig, ProvisionResult, ProvisionStage } from './provision.js'\nexport type { DockerBackend, HostCommandRunner } from './docker-backend.js'\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DockerBackend } from "./docker-backend.js";
|
|
2
|
+
import { SubprocessHandle, SubprocessSpawnSpec, SubprocessTerminalHandle, SubprocessTerminalSpawnSpec } from "@deepseek-ai/dsh-subprocess";
|
|
3
|
+
import { ShellExecRequest, ShellExecSpec, ShellProcess, ShellRunResult } from "@deepseek-ai/dsh-shell";
|
|
4
|
+
//#region src/exec-docker/process-provider.d.ts
|
|
5
|
+
declare class DockerShellExecutor {
|
|
6
|
+
private readonly client;
|
|
7
|
+
constructor(client: DockerBackend);
|
|
8
|
+
resolve(request: ShellExecRequest): ShellExecSpec;
|
|
9
|
+
run(spec: ShellExecSpec): Promise<ShellRunResult>;
|
|
10
|
+
start(spec: ShellExecSpec): ShellProcess;
|
|
11
|
+
}
|
|
12
|
+
declare class DockerSubprocessRuntime {
|
|
13
|
+
private readonly client;
|
|
14
|
+
constructor(client: DockerBackend);
|
|
15
|
+
spawn(spec: SubprocessSpawnSpec): SubprocessHandle;
|
|
16
|
+
spawnTerminal(spec: SubprocessTerminalSpawnSpec): Promise<SubprocessTerminalHandle>;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DockerShellExecutor, DockerSubprocessRuntime };
|
|
20
|
+
//# sourceMappingURL=process-provider.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//#region src/exec-docker/process-provider.ts
|
|
2
|
+
var DockerShellExecutor = class {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
resolve(request) {
|
|
8
|
+
return {
|
|
9
|
+
command: request.command,
|
|
10
|
+
workdir: request.workdir ?? "/",
|
|
11
|
+
timeoutMs: request.timeoutMs ?? 6e4,
|
|
12
|
+
stdoutMaxBytes: request.stdoutMaxBytes ?? 1048576,
|
|
13
|
+
signal: request.signal,
|
|
14
|
+
stdin: request.stdin,
|
|
15
|
+
env: request.env,
|
|
16
|
+
sandboxPolicy: request.sandboxPolicy
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async run(spec) {
|
|
20
|
+
const result = await this.client.exec([
|
|
21
|
+
"bash",
|
|
22
|
+
"-c",
|
|
23
|
+
spec.command
|
|
24
|
+
], spec.workdir, spec.env ?? {}, spec.stdin !== void 0 ? Buffer.from(spec.stdin) : void 0);
|
|
25
|
+
const collect = (text) => ({
|
|
26
|
+
text,
|
|
27
|
+
truncated: false
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
exitCode: result.code,
|
|
31
|
+
signal: null,
|
|
32
|
+
timedOut: false,
|
|
33
|
+
aborted: false,
|
|
34
|
+
timeoutMs: spec.timeoutMs,
|
|
35
|
+
stdout: collect(result.stdout),
|
|
36
|
+
stderr: collect(result.stderr)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
start(spec) {
|
|
40
|
+
return {
|
|
41
|
+
pid: -1,
|
|
42
|
+
done: this.run(spec),
|
|
43
|
+
kill: () => {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var DockerSubprocessRuntime = class {
|
|
48
|
+
client;
|
|
49
|
+
constructor(client) {
|
|
50
|
+
this.client = client;
|
|
51
|
+
}
|
|
52
|
+
spawn(spec) {
|
|
53
|
+
return {
|
|
54
|
+
pid: -1,
|
|
55
|
+
done: this.client.exec(spec.argv, spec.cwd, spec.env ?? {}).then((r) => ({
|
|
56
|
+
exitCode: r.code,
|
|
57
|
+
signal: null
|
|
58
|
+
})),
|
|
59
|
+
kill: () => {}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async spawnTerminal(spec) {
|
|
63
|
+
const pty = await this.client.pty(spec.argv, spec.cwd, spec.cols ?? 80, spec.rows ?? 24);
|
|
64
|
+
return {
|
|
65
|
+
write: (data) => pty.stream.write(data),
|
|
66
|
+
resize: (cols, rows) => pty.resize(cols, rows),
|
|
67
|
+
onData: (cb) => pty.stream.on("data", (chunk) => cb(chunk.toString("utf8"))),
|
|
68
|
+
kill: () => pty.kill()
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { DockerShellExecutor, DockerSubprocessRuntime };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=process-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-provider.js","names":[],"sources":["../../src/exec-docker/process-provider.ts"],"sourcesContent":["import type { DockerBackend } from './docker-backend.js'\nimport type { ShellExecRequest, ShellExecSpec, ShellProcess, ShellRunResult } from '@deepseek-ai/dsh-shell'\nimport type { CollectedOutput, SubprocessHandle, SubprocessSpawnSpec, SubprocessTerminalHandle, SubprocessTerminalSpawnSpec } from '@deepseek-ai/dsh-subprocess'\n\nexport class DockerShellExecutor {\n constructor(private readonly client: DockerBackend) {}\n\n resolve(request: ShellExecRequest): ShellExecSpec {\n return {\n command: request.command,\n workdir: request.workdir ?? '/',\n timeoutMs: request.timeoutMs ?? 60_000,\n stdoutMaxBytes: request.stdoutMaxBytes ?? 1024 * 1024,\n signal: request.signal,\n stdin: request.stdin,\n env: request.env,\n sandboxPolicy: request.sandboxPolicy,\n } as ShellExecSpec\n }\n\n async run(spec: ShellExecSpec): Promise<ShellRunResult> {\n const result = await this.client.exec(['bash', '-c', spec.command], spec.workdir, (spec.env ?? {}) as Record<string, string>, spec.stdin !== undefined ? Buffer.from(spec.stdin) : undefined)\n const collect = (text: string): CollectedOutput => ({ text, truncated: false })\n return {\n exitCode: result.code,\n signal: null,\n timedOut: false,\n aborted: false,\n timeoutMs: spec.timeoutMs,\n stdout: collect(result.stdout),\n stderr: collect(result.stderr),\n } as unknown as ShellRunResult\n }\n\n start(spec: ShellExecSpec): ShellProcess {\n const promise = this.run(spec)\n return {\n pid: -1,\n done: promise,\n kill: () => {\n void promise\n },\n } as unknown as ShellProcess\n }\n}\n\nexport class DockerSubprocessRuntime {\n constructor(private readonly client: DockerBackend) {}\n\n spawn(spec: SubprocessSpawnSpec): SubprocessHandle {\n const promise = this.client.exec(spec.argv as string[], spec.cwd, (spec.env ?? {}) as Record<string, string>)\n const handle: SubprocessHandle = {\n pid: -1,\n done: promise.then((r) => ({ exitCode: r.code, signal: null as NodeJS.Signals | null })),\n kill: () => {\n void promise\n },\n } as unknown as SubprocessHandle\n return handle\n }\n\n async spawnTerminal(spec: SubprocessTerminalSpawnSpec): Promise<SubprocessTerminalHandle> {\n const pty = await this.client.pty(spec.argv as string[], spec.cwd, (spec as { cols?: number }).cols ?? 80, (spec as { rows?: number }).rows ?? 24)\n const handle: SubprocessTerminalHandle = {\n write: (data: string) => pty.stream.write(data),\n resize: (cols: number, rows: number) => pty.resize(cols, rows),\n onData: (cb: (data: string) => void) => pty.stream.on('data', (chunk: Buffer) => cb(chunk.toString('utf8'))),\n kill: () => pty.kill(),\n } as unknown as SubprocessTerminalHandle\n return handle\n }\n}\n"],"mappings":";AAIA,IAAa,sBAAb,MAAiC;CACF;CAA7B,YAAY,QAAwC;EAAvB,KAAA,SAAA;CAAwB;CAErD,QAAQ,SAA0C;EAChD,OAAO;GACL,SAAS,QAAQ;GACjB,SAAS,QAAQ,WAAW;GAC5B,WAAW,QAAQ,aAAa;GAChC,gBAAgB,QAAQ,kBAAkB;GAC1C,QAAQ,QAAQ;GAChB,OAAO,QAAQ;GACf,KAAK,QAAQ;GACb,eAAe,QAAQ;EACzB;CACF;CAEA,MAAM,IAAI,MAA8C;EACtD,MAAM,SAAS,MAAM,KAAK,OAAO,KAAK;GAAC;GAAQ;GAAM,KAAK;EAAO,GAAG,KAAK,SAAU,KAAK,OAAO,CAAC,GAA8B,KAAK,UAAU,KAAA,IAAY,OAAO,KAAK,KAAK,KAAK,IAAI,KAAA,CAAS;EAC5L,MAAM,WAAW,UAAmC;GAAE;GAAM,WAAW;EAAM;EAC7E,OAAO;GACL,UAAU,OAAO;GACjB,QAAQ;GACR,UAAU;GACV,SAAS;GACT,WAAW,KAAK;GAChB,QAAQ,QAAQ,OAAO,MAAM;GAC7B,QAAQ,QAAQ,OAAO,MAAM;EAC/B;CACF;CAEA,MAAM,MAAmC;EAEvC,OAAO;GACL,KAAK;GACL,MAHc,KAAK,IAAI,IAGX;GACZ,YAAY,CAEZ;EACF;CACF;AACF;AAEA,IAAa,0BAAb,MAAqC;CACN;CAA7B,YAAY,QAAwC;EAAvB,KAAA,SAAA;CAAwB;CAErD,MAAM,MAA6C;EASjD,OAAO;GANL,KAAK;GACL,MAHc,KAAK,OAAO,KAAK,KAAK,MAAkB,KAAK,KAAM,KAAK,OAAO,CAAC,CAGlE,CAAC,CAAC,MAAM,OAAO;IAAE,UAAU,EAAE;IAAM,QAAQ;GAA8B,EAAE;GACvF,YAAY,CAEZ;EAEU;CACd;CAEA,MAAM,cAAc,MAAsE;EACxF,MAAM,MAAM,MAAM,KAAK,OAAO,IAAI,KAAK,MAAkB,KAAK,KAAM,KAA2B,QAAQ,IAAK,KAA2B,QAAQ,EAAE;EAOjJ,OAAO;GALL,QAAQ,SAAiB,IAAI,OAAO,MAAM,IAAI;GAC9C,SAAS,MAAc,SAAiB,IAAI,OAAO,MAAM,IAAI;GAC7D,SAAS,OAA+B,IAAI,OAAO,GAAG,SAAS,UAAkB,GAAG,MAAM,SAAS,MAAM,CAAC,CAAC;GAC3G,YAAY,IAAI,KAAK;EAEX;CACd;AACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HostCommandRunner } from "./docker-backend.js";
|
|
2
|
+
//#region src/exec-docker/provision.d.ts
|
|
3
|
+
interface ProvisionConfig {
|
|
4
|
+
image: string;
|
|
5
|
+
cpus?: number;
|
|
6
|
+
memoryMB?: number;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
interface ProvisionResult {
|
|
10
|
+
containerId: string;
|
|
11
|
+
name: string;
|
|
12
|
+
}
|
|
13
|
+
type ProvisionStage = 'pull' | 'create' | 'wait' | 'ready';
|
|
14
|
+
declare function provisionContainer(runner: HostCommandRunner, config: ProvisionConfig, onStage?: (stage: ProvisionStage, detail?: string) => void, timeoutMs?: number): Promise<ProvisionResult>;
|
|
15
|
+
declare function listContainers(runner: HostCommandRunner): Promise<Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
status: string;
|
|
19
|
+
image: string;
|
|
20
|
+
}>>;
|
|
21
|
+
declare function removeContainer(runner: HostCommandRunner, containerId: string): Promise<void>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { ProvisionConfig, ProvisionResult, ProvisionStage, listContainers, provisionContainer, removeContainer };
|
|
24
|
+
//# sourceMappingURL=provision.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//#region src/exec-docker/provision.ts
|
|
2
|
+
async function provisionContainer(runner, config, onStage, timeoutMs = 6e4) {
|
|
3
|
+
const name = config.name ?? `dshb-${Date.now()}`;
|
|
4
|
+
const inspectExisting = await runner.run([
|
|
5
|
+
"docker",
|
|
6
|
+
"inspect",
|
|
7
|
+
"--format",
|
|
8
|
+
"{{.Id}} {{.State.Running}}",
|
|
9
|
+
name
|
|
10
|
+
]);
|
|
11
|
+
if (inspectExisting.code === 0) {
|
|
12
|
+
const [containerId, running] = inspectExisting.stdout.trim().split(" ");
|
|
13
|
+
if (running === "true") {
|
|
14
|
+
onStage?.("ready", `容器 ${name} 已在运行`);
|
|
15
|
+
return {
|
|
16
|
+
containerId: containerId ?? name,
|
|
17
|
+
name
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if ((await runner.run([
|
|
21
|
+
"docker",
|
|
22
|
+
"start",
|
|
23
|
+
name
|
|
24
|
+
])).code === 0) {
|
|
25
|
+
onStage?.("ready", `容器 ${name} 已重新启动`);
|
|
26
|
+
return {
|
|
27
|
+
containerId: containerId ?? name,
|
|
28
|
+
name
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
onStage?.("pull", `拉取镜像 ${config.image}`);
|
|
33
|
+
const pull = await runner.run([
|
|
34
|
+
"docker",
|
|
35
|
+
"pull",
|
|
36
|
+
config.image
|
|
37
|
+
]);
|
|
38
|
+
if (pull.code !== 0) throw new Error(`镜像拉取失败: ${pull.stderr.trim() || pull.stdout.trim()}`);
|
|
39
|
+
onStage?.("create", `创建容器`);
|
|
40
|
+
const createArgs = [
|
|
41
|
+
"docker",
|
|
42
|
+
"run",
|
|
43
|
+
"-d",
|
|
44
|
+
"--name",
|
|
45
|
+
name
|
|
46
|
+
];
|
|
47
|
+
if (config.cpus) createArgs.push("--cpus", String(config.cpus));
|
|
48
|
+
if (config.memoryMB && config.memoryMB >= 6) createArgs.push("-m", `${config.memoryMB}m`);
|
|
49
|
+
createArgs.push(config.image, "sleep", "infinity");
|
|
50
|
+
const create = await runner.run(createArgs);
|
|
51
|
+
if (create.code !== 0) throw new Error(`容器创建失败: ${create.stderr.trim() || create.stdout.trim()}`);
|
|
52
|
+
const containerId = create.stdout.trim();
|
|
53
|
+
if (!containerId) throw new Error("容器创建失败:无容器 ID");
|
|
54
|
+
onStage?.("wait", `等待容器就绪`);
|
|
55
|
+
const deadline = Date.now() + timeoutMs;
|
|
56
|
+
while (Date.now() < deadline) {
|
|
57
|
+
if ((await runner.run([
|
|
58
|
+
"docker",
|
|
59
|
+
"inspect",
|
|
60
|
+
"--format",
|
|
61
|
+
"{{.State.Running}}",
|
|
62
|
+
containerId
|
|
63
|
+
])).stdout.trim() === "true") {
|
|
64
|
+
onStage?.("ready", `容器 ${name} 就绪`);
|
|
65
|
+
return {
|
|
66
|
+
containerId,
|
|
67
|
+
name
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`容器启动超时(${Math.round(timeoutMs / 1e3)} 秒)`);
|
|
73
|
+
}
|
|
74
|
+
async function listContainers(runner) {
|
|
75
|
+
const result = await runner.run([
|
|
76
|
+
"docker",
|
|
77
|
+
"ps",
|
|
78
|
+
"--format",
|
|
79
|
+
"{{.ID}} {{.Names}} {{.Status}} {{.Image}}"
|
|
80
|
+
]);
|
|
81
|
+
if (result.code !== 0) return [];
|
|
82
|
+
return result.stdout.split("\n").filter((line) => line.trim()).map((line) => {
|
|
83
|
+
const [id, name, status, image] = line.split(" ");
|
|
84
|
+
return {
|
|
85
|
+
id: id?.trim() ?? "",
|
|
86
|
+
name: name?.trim() ?? "",
|
|
87
|
+
status: status?.trim() ?? "",
|
|
88
|
+
image: image?.trim() ?? ""
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function removeContainer(runner, containerId) {
|
|
93
|
+
await runner.run([
|
|
94
|
+
"docker",
|
|
95
|
+
"rm",
|
|
96
|
+
"-f",
|
|
97
|
+
containerId
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { listContainers, provisionContainer, removeContainer };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provision.js","names":[],"sources":["../../src/exec-docker/provision.ts"],"sourcesContent":["import type { HostCommandRunner } from './docker-backend.js'\n\nexport interface ProvisionConfig {\n image: string\n cpus?: number\n memoryMB?: number\n name?: string\n}\n\nexport interface ProvisionResult {\n containerId: string\n name: string\n}\n\nexport type ProvisionStage = 'pull' | 'create' | 'wait' | 'ready'\n\nexport async function provisionContainer(\n runner: HostCommandRunner,\n config: ProvisionConfig,\n onStage?: (stage: ProvisionStage, detail?: string) => void,\n timeoutMs = 60_000,\n): Promise<ProvisionResult> {\n const name = config.name ?? `dshb-${Date.now()}`\n\n const inspectExisting = await runner.run(['docker', 'inspect', '--format', '{{.Id}}\\t{{.State.Running}}', name])\n if (inspectExisting.code === 0) {\n const [containerId, running] = inspectExisting.stdout.trim().split('\\t')\n if (running === 'true') {\n onStage?.('ready', `容器 ${name} 已在运行`)\n return { containerId: containerId ?? name, name }\n }\n const startResult = await runner.run(['docker', 'start', name])\n if (startResult.code === 0) {\n onStage?.('ready', `容器 ${name} 已重新启动`)\n return { containerId: containerId ?? name, name }\n }\n }\n\n onStage?.('pull', `拉取镜像 ${config.image}`)\n const pull = await runner.run(['docker', 'pull', config.image])\n if (pull.code !== 0) throw new Error(`镜像拉取失败: ${pull.stderr.trim() || pull.stdout.trim()}`)\n\n onStage?.('create', `创建容器`)\n const createArgs = ['docker', 'run', '-d', '--name', name]\n if (config.cpus) createArgs.push('--cpus', String(config.cpus))\n if (config.memoryMB && config.memoryMB >= 6) createArgs.push('-m', `${config.memoryMB}m`)\n createArgs.push(config.image, 'sleep', 'infinity')\n const create = await runner.run(createArgs)\n if (create.code !== 0) throw new Error(`容器创建失败: ${create.stderr.trim() || create.stdout.trim()}`)\n const containerId = create.stdout.trim()\n if (!containerId) throw new Error('容器创建失败:无容器 ID')\n\n onStage?.('wait', `等待容器就绪`)\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n const inspect = await runner.run(['docker', 'inspect', '--format', '{{.State.Running}}', containerId])\n if (inspect.stdout.trim() === 'true') {\n onStage?.('ready', `容器 ${name} 就绪`)\n return { containerId, name }\n }\n await new Promise((r) => setTimeout(r, 1000))\n }\n throw new Error(`容器启动超时(${Math.round(timeoutMs / 1000)} 秒)`)\n}\n\nexport async function listContainers(runner: HostCommandRunner): Promise<Array<{ id: string; name: string; status: string; image: string }>> {\n const result = await runner.run(['docker', 'ps', '--format', '{{.ID}}\\t{{.Names}}\\t{{.Status}}\\t{{.Image}}'])\n if (result.code !== 0) return []\n return result.stdout\n .split('\\n')\n .filter((line) => line.trim())\n .map((line) => {\n const [id, name, status, image] = line.split('\\t')\n return { id: id?.trim() ?? '', name: name?.trim() ?? '', status: status?.trim() ?? '', image: image?.trim() ?? '' }\n })\n}\n\nexport async function removeContainer(runner: HostCommandRunner, containerId: string): Promise<void> {\n await runner.run(['docker', 'rm', '-f', containerId])\n}\n"],"mappings":";AAgBA,eAAsB,mBACpB,QACA,QACA,SACA,YAAY,KACc;CAC1B,MAAM,OAAO,OAAO,QAAQ,QAAQ,KAAK,IAAI;CAE7C,MAAM,kBAAkB,MAAM,OAAO,IAAI;EAAC;EAAU;EAAW;EAAY;EAA+B;CAAI,CAAC;CAC/G,IAAI,gBAAgB,SAAS,GAAG;EAC9B,MAAM,CAAC,aAAa,WAAW,gBAAgB,OAAO,KAAK,CAAC,CAAC,MAAM,GAAI;EACvE,IAAI,YAAY,QAAQ;GACtB,UAAU,SAAS,MAAM,KAAK,MAAM;GACpC,OAAO;IAAE,aAAa,eAAe;IAAM;GAAK;EAClD;EAEA,KAAI,MADsB,OAAO,IAAI;GAAC;GAAU;GAAS;EAAI,CAAC,EAAA,CAC9C,SAAS,GAAG;GAC1B,UAAU,SAAS,MAAM,KAAK,OAAO;GACrC,OAAO;IAAE,aAAa,eAAe;IAAM;GAAK;EAClD;CACF;CAEA,UAAU,QAAQ,QAAQ,OAAO,OAAO;CACxC,MAAM,OAAO,MAAM,OAAO,IAAI;EAAC;EAAU;EAAQ,OAAO;CAAK,CAAC;CAC9D,IAAI,KAAK,SAAS,GAAG,MAAM,IAAI,MAAM,WAAW,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,GAAG;CAE1F,UAAU,UAAU,MAAM;CAC1B,MAAM,aAAa;EAAC;EAAU;EAAO;EAAM;EAAU;CAAI;CACzD,IAAI,OAAO,MAAM,WAAW,KAAK,UAAU,OAAO,OAAO,IAAI,CAAC;CAC9D,IAAI,OAAO,YAAY,OAAO,YAAY,GAAG,WAAW,KAAK,MAAM,GAAG,OAAO,SAAS,EAAE;CACxF,WAAW,KAAK,OAAO,OAAO,SAAS,UAAU;CACjD,MAAM,SAAS,MAAM,OAAO,IAAI,UAAU;CAC1C,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,WAAW,OAAO,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK,GAAG;CAChG,MAAM,cAAc,OAAO,OAAO,KAAK;CACvC,IAAI,CAAC,aAAa,MAAM,IAAI,MAAM,eAAe;CAEjD,UAAU,QAAQ,QAAQ;CAC1B,MAAM,WAAW,KAAK,IAAI,IAAI;CAC9B,OAAO,KAAK,IAAI,IAAI,UAAU;EAE5B,KAAI,MADkB,OAAO,IAAI;GAAC;GAAU;GAAW;GAAY;GAAsB;EAAW,CAAC,EAAA,CACzF,OAAO,KAAK,MAAM,QAAQ;GACpC,UAAU,SAAS,MAAM,KAAK,IAAI;GAClC,OAAO;IAAE;IAAa;GAAK;EAC7B;EACA,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,GAAI,CAAC;CAC9C;CACA,MAAM,IAAI,MAAM,UAAU,KAAK,MAAM,YAAY,GAAI,EAAE,IAAI;AAC7D;AAEA,eAAsB,eAAe,QAAwG;CAC3I,MAAM,SAAS,MAAM,OAAO,IAAI;EAAC;EAAU;EAAM;EAAY;CAA8C,CAAC;CAC5G,IAAI,OAAO,SAAS,GAAG,OAAO,CAAC;CAC/B,OAAO,OAAO,OACX,MAAM,IAAI,CAAC,CACX,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,CAC7B,KAAK,SAAS;EACb,MAAM,CAAC,IAAI,MAAM,QAAQ,SAAS,KAAK,MAAM,GAAI;EACjD,OAAO;GAAE,IAAI,IAAI,KAAK,KAAK;GAAI,MAAM,MAAM,KAAK,KAAK;GAAI,QAAQ,QAAQ,KAAK,KAAK;GAAI,OAAO,OAAO,KAAK,KAAK;EAAG;CACpH,CAAC;AACL;AAEA,eAAsB,gBAAgB,QAA2B,aAAoC;CACnG,MAAM,OAAO,IAAI;EAAC;EAAU;EAAM;EAAM;CAAW,CAAC;AACtD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { DockerBackend } from "./docker-backend.js";
|
|
2
|
+
//#region src/exec-docker/remote-docker-cli.d.ts
|
|
3
|
+
interface SshExecutorLike {
|
|
4
|
+
exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{
|
|
5
|
+
code: number;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
declare class RemoteDockerCli implements DockerBackend {
|
|
11
|
+
private readonly ssh;
|
|
12
|
+
private readonly containerId;
|
|
13
|
+
constructor(ssh: SshExecutorLike, containerId: string);
|
|
14
|
+
exec(argv: string[], cwd: string, env?: Record<string, string>, stdinData?: Buffer): Promise<{
|
|
15
|
+
code: number;
|
|
16
|
+
stdout: string;
|
|
17
|
+
stderr: string;
|
|
18
|
+
}>;
|
|
19
|
+
execShell(command: string, cwd: string): Promise<{
|
|
20
|
+
code: number;
|
|
21
|
+
stdout: string;
|
|
22
|
+
stderr: string;
|
|
23
|
+
}>;
|
|
24
|
+
readFile(path: string): Promise<Buffer>;
|
|
25
|
+
writeFile(path: string, content: Buffer | string): Promise<void>;
|
|
26
|
+
listDir(path: string): Promise<Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
isDir: boolean;
|
|
29
|
+
isFile: boolean;
|
|
30
|
+
isSymlink: boolean;
|
|
31
|
+
size: number;
|
|
32
|
+
mtime: number;
|
|
33
|
+
}>>;
|
|
34
|
+
stat(path: string): Promise<{
|
|
35
|
+
size: number;
|
|
36
|
+
mtime: number;
|
|
37
|
+
isDirectory: boolean;
|
|
38
|
+
isFile: boolean;
|
|
39
|
+
} | undefined>;
|
|
40
|
+
mkdir(path: string): Promise<void>;
|
|
41
|
+
remove(path: string): Promise<void>;
|
|
42
|
+
rename(src: string, dest: string): Promise<void>;
|
|
43
|
+
ensureRg(): Promise<void>;
|
|
44
|
+
pty(argv: string[], cwd: string, cols: number, rows: number): Promise<{
|
|
45
|
+
stream: NodeJS.ReadWriteStream;
|
|
46
|
+
resize: (c: number, r: number) => void;
|
|
47
|
+
kill: () => void;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { RemoteDockerCli };
|
|
52
|
+
//# sourceMappingURL=remote-docker-cli.d.ts.map
|