From 5713f91e23c4cdbaacfa67003375ed84cb584d84 Mon Sep 17 00:00:00 2001 From: pikastech Date: Tue, 21 Jul 2026 10:15:08 +0200 Subject: [PATCH] fix: deploy L1 HWPOD node from local artifact --- config/hwlab-hwpod-nodes.yaml | 2 ++ scripts/src/hwlab-hwpod-node.ts | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/hwlab-hwpod-nodes.yaml b/config/hwlab-hwpod-nodes.yaml index 6dbbbd31..85f7c4f5 100644 --- a/config/hwlab-hwpod-nodes.yaml +++ b/config/hwlab-hwpod-nodes.yaml @@ -47,6 +47,8 @@ targets: metadataUrl: https://lab-dev.hwpod.com/v1/hwlab-node/update channel: stable platform: windows + localPath: /root/hwlab-v03/tools/hwlab-node.py + localVersion: 0.1.3 workspace: allowedRoots: - "F:\\Work\\ConStart" diff --git a/scripts/src/hwlab-hwpod-node.ts b/scripts/src/hwlab-hwpod-node.ts index 2ea3695c..a5822349 100644 --- a/scripts/src/hwlab-hwpod-node.ts +++ b/scripts/src/hwlab-hwpod-node.ts @@ -64,7 +64,7 @@ interface HwpodNodeSpec { credentialPath: string; logPath: string; }; - artifact: { metadataUrl: string; channel: string; platform: string }; + artifact: { metadataUrl: string; channel: string; platform: string; localPath: string | null; localVersion: string | null }; workspace: { allowedRoots: string[]; defaultRoot: string }; desktopConfig: { serverUrl: string; @@ -247,6 +247,8 @@ function readSpec(node: string, lane: string): HwpodNodeSpec { metadataUrl: text(artifact.metadataUrl, `targets.${node}.artifact.metadataUrl`), channel: text(artifact.channel, `targets.${node}.artifact.channel`), platform: text(artifact.platform, `targets.${node}.artifact.platform`), + localPath: optionalText(artifact.localPath), + localVersion: optionalText(artifact.localVersion), }, workspace: { allowedRoots, defaultRoot: text(workspace.defaultRoot, `targets.${node}.workspace.defaultRoot`) }, desktopConfig: { @@ -362,6 +364,18 @@ function resultEnvelope( } async function readArtifact(spec: HwpodNodeSpec, includeContent: boolean): Promise { + if (spec.artifact.localPath) { + if (!spec.artifact.localVersion) throw new Error(`targets.${spec.node}.artifact.localVersion 是本地 artifact 必填项`); + if (!existsSync(spec.artifact.localPath)) throw new Error(`HWPOD 节点本地 artifact 不存在:${spec.artifact.localPath}`); + const content = readFileSync(spec.artifact.localPath); + const sha256 = createHash("sha256").update(content).digest("hex"); + return { + latestVersion: spec.artifact.localVersion, + downloadUrl: `local:${spec.artifact.localPath}`, + sha256, + content: includeContent ? content : Buffer.alloc(0), + }; + } const metadataUrl = new URL(spec.artifact.metadataUrl); metadataUrl.searchParams.set("platform", spec.artifact.platform); metadataUrl.searchParams.set("channel", spec.artifact.channel); @@ -702,6 +716,10 @@ function text(value: unknown, path: string): string { return value.trim(); } +function optionalText(value: unknown): string | null { + return typeof value === "string" && value.trim().length > 0 ? value.trim() : null; +} + function texts(value: unknown, path: string): string[] { if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.trim().length === 0)) throw new Error(`${path} 必须是非空字符串数组`); return value.map((item) => String(item));