fix: harden provider gateway upgrades
This commit is contained in:
@@ -156,6 +156,8 @@ export function rebuildService(config: UniDeskConfig, service: RebuildableServic
|
||||
`label=com.docker.compose.project=${config.docker.projectName}`,
|
||||
"--filter",
|
||||
`label=com.docker.compose.service=${service}`,
|
||||
"--filter",
|
||||
"label=com.docker.compose.oneoff=False",
|
||||
];
|
||||
const upCommand = [...compose, "up", "-d", "--no-deps", service];
|
||||
const script = [
|
||||
@@ -209,6 +211,8 @@ export function dockerContainers(config: UniDeskConfig): ContainerStatus[] {
|
||||
"-a",
|
||||
"--filter",
|
||||
`label=com.docker.compose.project=${config.docker.projectName}`,
|
||||
"--filter",
|
||||
"label=com.docker.compose.oneoff=False",
|
||||
"--format",
|
||||
"{{json .}}",
|
||||
], repoRoot);
|
||||
|
||||
+14
-7
@@ -154,6 +154,8 @@ function dockerPortSummary(): unknown {
|
||||
"ps",
|
||||
"--filter",
|
||||
"label=com.docker.compose.project=unidesk",
|
||||
"--filter",
|
||||
"label=com.docker.compose.oneoff=False",
|
||||
"--format",
|
||||
"{{.Names}}\t{{.Ports}}",
|
||||
], repoRoot);
|
||||
@@ -346,8 +348,9 @@ async function serviceChecks(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
});
|
||||
const upgradeTaskId = (upgradeDispatch as { body?: { taskId?: string } }).body?.taskId ?? "";
|
||||
const upgradeTask = upgradeTaskId ? await waitForTaskStatus(upgradeTaskId, "succeeded") : { ok: false, error: "missing taskId", upgradeDispatch };
|
||||
const taskResult = (upgradeTask as { task?: { result?: { plan?: unknown; mode?: string } }; ok?: boolean }).task?.result;
|
||||
addCheck(checks, "provider:upgrade-plan", (upgradeDispatch as { ok?: boolean }).ok === true && (upgradeTask as { ok?: boolean }).ok === true && taskResult?.mode === "plan" && taskResult.plan !== undefined, { upgradeDispatch, upgradeTask });
|
||||
const taskResult = (upgradeTask as { task?: { result?: { plan?: { providerGatewayVersion?: string; targetProviderGatewayVersion?: string }; mode?: string } }; ok?: boolean }).task?.result;
|
||||
const upgradePlan = taskResult?.plan;
|
||||
addCheck(checks, "provider:upgrade-plan", (upgradeDispatch as { ok?: boolean }).ok === true && (upgradeTask as { ok?: boolean }).ok === true && taskResult?.mode === "plan" && upgradePlan !== undefined && upgradePlan.providerGatewayVersion === expectedGatewayVersion && upgradePlan.targetProviderGatewayVersion === expectedGatewayVersion, { expectedGatewayVersion, upgradeDispatch, upgradeTask });
|
||||
addCheck(checks, "provider-ingress:public-health", (providerIngress as { ok?: boolean; body?: { ok?: boolean } }).ok === true && (providerIngress as { body?: { ok?: boolean } }).body?.ok === true, providerIngress);
|
||||
}
|
||||
|
||||
@@ -589,8 +592,12 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
const lower = text.toLowerCase();
|
||||
return lower.includes("met nonlinear 训练编排")
|
||||
&& text.includes("D601")
|
||||
&& text.includes("任务队列")
|
||||
&& text.includes("GPU 与镜像")
|
||||
&& text.includes("Fork Project")
|
||||
&& text.includes("加入待启动队列")
|
||||
&& text.includes("启动队列")
|
||||
&& text.includes("当前队列")
|
||||
&& text.includes("GPU/镜像")
|
||||
&& !text.includes("创建10个10轮任务")
|
||||
&& text.includes("仅 UniDesk frontend 代理访问")
|
||||
&& /Health\s+OK/i.test(text);
|
||||
}, undefined, { timeout: 30000 });
|
||||
@@ -610,9 +617,9 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
addCheck(checks, "frontend:no-naked-json-before-click", rawBlocksBefore === 0 && !nakedJsonText, { rawBlocksBefore, nakedJsonText });
|
||||
addCheck(checks, "frontend:raw-json-explicit-button", rawText.includes('"providerId"') && rawText.includes(config.providerGateway.id), { rawTextPreview: rawText.slice(0, 400) });
|
||||
addCheck(checks, "frontend:system-monitor-visible", monitorText.includes("任务管理器视图") && monitorText.includes("CPU") && monitorText.includes("Memory") && monitorText.includes("Disk") && monitorText.includes("不含缓存"), { monitorTextPreview: monitorText.slice(0, 800) });
|
||||
addCheck(checks, "frontend:upgrade-plan-dispatch", upgradeControlText.includes("预检升级 已下发"), { providerId: config.providerGateway.id, upgradeControlPreview: upgradeControlText.slice(0, 500) });
|
||||
addCheck(checks, "frontend:upgrade-plan-dispatch", upgradeControlText.includes("预检升级 已下发") && upgradeControlText.includes("指定 Provider") && upgradeControlText.includes(`v${providerGatewayPackageVersion()}`), { providerId: config.providerGateway.id, upgradeControlPreview: upgradeControlText.slice(0, 500) });
|
||||
addCheck(checks, "frontend:docker-status-visible", dockerText.toLowerCase().includes("docker desktop 视图") && dockerText.toLowerCase().includes("containers") && dockerText.includes("unidesk_pgdata_10gb") && (dockerText.includes("unidesk-frontend") || dockerText.includes("unidesk-backend-core")), { dockerTextPreview: dockerText.slice(0, 800) });
|
||||
addCheck(checks, "frontend:gateway-version-records-visible", gatewayTextLower.includes("provider gateway 版本") && gatewayText.includes("自动更新记录") && gatewayText.includes(config.providerGateway.id) && gatewayText.includes(`v${providerGatewayPackageVersion()}`) && gatewayText.includes("provider.upgrade"), { gatewayTextPreview: gatewayText.slice(0, 900) });
|
||||
addCheck(checks, "frontend:gateway-version-records-visible", gatewayTextLower.includes("provider gateway 版本") && gatewayText.includes("自动更新记录") && gatewayText.includes("Gateway 版本") && gatewayText.includes(config.providerGateway.id) && gatewayText.includes(`v${providerGatewayPackageVersion()}`) && gatewayText.includes("provider.upgrade"), { gatewayTextPreview: gatewayText.slice(0, 900) });
|
||||
addCheck(checks, "frontend:provider-operation-availability-visible", sshAvailabilityTexts.length >= 1 && upgradeAvailabilityTexts.length >= 1 && sshAvailabilityTexts.every((text) => text.includes("SSH 透传")) && upgradeAvailabilityTexts.every((text) => text.includes("远程更新")) && upgradeAvailabilityTexts.some((text) => text.includes("always-enabled")), { sshAvailabilityTexts, upgradeAvailabilityTexts });
|
||||
addCheck(checks, "frontend:overview-pgdata-visible", bodyText.includes("PGDATA") && bodyText.includes(config.database.volume), { bodyPreview: bodyText.slice(0, 800) });
|
||||
addCheck(checks, "frontend:microservice-catalog-visible", microserviceCatalogTextLower.includes("findjob") && microserviceCatalogTextLower.includes("pipeline") && microserviceCatalogTextLower.includes("todo note") && microserviceCatalogTextLower.includes("met nonlinear") && microserviceCatalogText.includes("D601") && microserviceCatalogText.includes(config.providerGateway.id) && microserviceCatalogTextLower.includes("private") && microserviceCatalogText.includes("https://gitee.com/Lyon1998/findjob") && microserviceCatalogText.includes("https://github.com/pikasTech/pipeline") && microserviceCatalogText.includes("https://github.com/pikasTech/met_nonlinear") && microserviceCatalogText.includes("https://gitee.com/Lyon1998/todo_note"), { microserviceCatalogPreview: microserviceCatalogText.slice(0, 1600) });
|
||||
@@ -620,7 +627,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
|
||||
addCheck(checks, "frontend:findjob-integrated-visible", findjobTextLower.includes("findjob 工作台".toLowerCase()) && findjobText.includes("岗位总量") && findjobText.includes("D601") && findjobText.includes("近期岗位") && findjobText.includes("仅 UniDesk frontend 代理访问") && /岗位总量\s+\d+/.test(findjobText) && /health\s+ok/i.test(findjobText) && /[1-9]\d*\/[1-9]\d*\s+preview/i.test(findjobText), { findjobTextPreview: findjobText.slice(0, 1200) });
|
||||
addCheck(checks, "frontend:pipeline-integrated-visible", pipelineTextLower.includes("pipeline v2 工作台".toLowerCase()) && pipelineText.includes("D601") && pipelineText.includes("控制图") && pipelineText.includes("最近运行") && pipelineText.includes("仅 UniDesk frontend 代理访问") && /Health\s+OK/i.test(pipelineText) && /组件\s+\d+/.test(pipelineText) && /运行记录\s+[1-9]\d*/.test(pipelineText), { pipelineTextPreview: pipelineText.slice(0, 1200) });
|
||||
addCheck(checks, "frontend:pipeline-react-flow-visible", pipelineFlowNodeCount > 0 && pipelineFlowEdgeCount > 0, { pipelineFlowNodeCount, pipelineFlowEdgeCount });
|
||||
addCheck(checks, "frontend:met-nonlinear-integrated-visible", metNonlinearTextLower.includes("met nonlinear 训练编排") && metNonlinearText.includes("D601") && metNonlinearText.includes("任务队列") && metNonlinearText.includes("GPU 与镜像") && metNonlinearText.includes("创建10个10轮任务") && metNonlinearText.includes("仅 UniDesk frontend 代理访问") && /Health\s+OK/i.test(metNonlinearText), { metNonlinearTextPreview: metNonlinearText.slice(0, 1400) });
|
||||
addCheck(checks, "frontend:met-nonlinear-integrated-visible", metNonlinearTextLower.includes("met nonlinear 训练编排") && metNonlinearText.includes("D601") && metNonlinearText.includes("当前队列") && metNonlinearText.includes("GPU/镜像") && metNonlinearText.includes("Fork Project") && metNonlinearText.includes("加入待启动队列") && metNonlinearText.includes("启动队列") && !metNonlinearText.includes("创建10个10轮任务") && metNonlinearText.includes("仅 UniDesk frontend 代理访问") && /Health\s+OK/i.test(metNonlinearText), { metNonlinearTextPreview: metNonlinearText.slice(0, 1400) });
|
||||
addCheck(checks, "frontend:no-console-errors", consoleErrors.length === 0, { consoleErrors });
|
||||
return { screenshotPath, bodyText, consoleErrors };
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user