feat: 配置 Webterm 默认恢复会话
This commit is contained in:
@@ -41,6 +41,7 @@ interface WebtermTarget {
|
||||
privileged: boolean;
|
||||
pid: "host" | "container";
|
||||
sourceMounts: Array<{ source: string; target: string; readOnly: boolean }>;
|
||||
autoStartSessions: Array<{ title: string; cwd: string; command: string; cols: number; rows: number }>;
|
||||
environment: Record<string, string>;
|
||||
};
|
||||
publicExposure: {
|
||||
@@ -252,6 +253,7 @@ function parseTarget(record: Record<string, unknown>, path: string): WebtermTarg
|
||||
const pk01 = recordField(exposure, "pk01", `${path}.publicExposure`);
|
||||
const environment = parseEnvironment(recordField(runtime, "environment", `${path}.runtime`), `${path}.runtime.environment`);
|
||||
const sourceMounts = parseSourceMounts(runtime.sourceMounts, `${path}.runtime.sourceMounts`);
|
||||
const autoStartSessions = parseAutoStartSessions(runtime.autoStartSessions, `${path}.runtime.autoStartSessions`);
|
||||
const target: WebtermTarget = {
|
||||
id: stringField(record, "id", path),
|
||||
enabled: booleanField(record, "enabled", path),
|
||||
@@ -269,6 +271,7 @@ function parseTarget(record: Record<string, unknown>, path: string): WebtermTarg
|
||||
privileged: booleanField(runtime, "privileged", `${path}.runtime`),
|
||||
pid: parsePid(stringField(runtime, "pid", `${path}.runtime`), `${path}.runtime.pid`),
|
||||
sourceMounts,
|
||||
autoStartSessions,
|
||||
environment,
|
||||
},
|
||||
publicExposure: {
|
||||
@@ -306,7 +309,11 @@ function resolveTarget(targetId: string | null): WebtermTarget {
|
||||
}
|
||||
|
||||
function renderCompose(target: WebtermTarget): string {
|
||||
const envLines = Object.entries(target.runtime.environment)
|
||||
const environment = {
|
||||
...target.runtime.environment,
|
||||
AUTO_START_SESSIONS_JSON: JSON.stringify(target.runtime.autoStartSessions),
|
||||
};
|
||||
const envLines = Object.entries(environment)
|
||||
.map(([key, value]) => ` ${key}: ${quoteYaml(value)}`)
|
||||
.join("\n");
|
||||
const volumeLines = target.runtime.sourceMounts
|
||||
@@ -378,6 +385,7 @@ function targetSummary(target: WebtermTarget): Record<string, unknown> {
|
||||
composeProject: target.runtime.composeProject,
|
||||
containerName: target.runtime.containerName,
|
||||
image: target.runtime.image,
|
||||
autoStartSessions: target.runtime.autoStartSessions.map((session) => session.title),
|
||||
sourceMounts: target.runtime.sourceMounts.map((mount) => `${mount.source}->${mount.target}${mount.readOnly ? ":ro" : ""}`),
|
||||
hostPort: target.runtime.hostPort,
|
||||
containerPort: target.runtime.containerPort,
|
||||
@@ -481,6 +489,21 @@ function parseSourceMounts(value: unknown, path: string): WebtermTarget["runtime
|
||||
});
|
||||
}
|
||||
|
||||
function parseAutoStartSessions(value: unknown, path: string): WebtermTarget["runtime"]["autoStartSessions"] {
|
||||
if (!Array.isArray(value)) throw new Error(`${path} must be an array`);
|
||||
return value.map((item, index) => {
|
||||
const itemPath = `${path}[${index}]`;
|
||||
const record = asRecord(item, itemPath);
|
||||
return {
|
||||
title: stringField(record, "title", itemPath),
|
||||
cwd: stringField(record, "cwd", itemPath),
|
||||
command: stringField(record, "command", itemPath),
|
||||
cols: integerField(record, "cols", itemPath),
|
||||
rows: integerField(record, "rows", itemPath),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function parseLiteral<T extends string>(value: string, expected: T, path: string): T {
|
||||
if (value !== expected) throw new Error(`${path} must be ${expected}`);
|
||||
return expected;
|
||||
|
||||
Reference in New Issue
Block a user