Merge pull request #2186 from pikasTech/fix/2183-hwpod-spec-configmap-symlink
fix: 支持 ConfigMap symlink HWPOD spec 发现
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
import { mkdir, mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
|
||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { test } from "bun:test";
|
import { test } from "bun:test";
|
||||||
@@ -109,6 +109,39 @@ test("cloud-api discovers preinstalled workspace hwpod-specs without hardcoded d
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("cloud-api discovers configmap-mounted registry hwpod-spec symlinks", async () => {
|
||||||
|
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-spec-registry-"));
|
||||||
|
const registryDir = path.join(root, "registry");
|
||||||
|
const dataDir = path.join(root, "data");
|
||||||
|
await mkdir(registryDir, { recursive: true });
|
||||||
|
await mkdir(dataDir, { recursive: true });
|
||||||
|
const targetPath = path.join(dataDir, "constart-71freq-c.yaml");
|
||||||
|
await writeFile(targetPath, sampleConstartSpecYaml(), "utf8");
|
||||||
|
await symlink(targetPath, path.join(registryDir, "constart-71freq-c.yaml"));
|
||||||
|
const server = createCloudApiServer({
|
||||||
|
env: {
|
||||||
|
PATH: process.env.PATH,
|
||||||
|
HWLAB_CODE_AGENT_WORKSPACE: root,
|
||||||
|
HWLAB_HWPOD_SPEC_REGISTRY_DIRS: registryDir
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await listen(server);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${serverUrl(server)}/v1/hwpod/specs`);
|
||||||
|
const payload = await response.json();
|
||||||
|
assert.equal(response.status, 200);
|
||||||
|
assert.equal(payload.contractVersion, "hwpod-spec-discovery-v1");
|
||||||
|
const spec = payload.specs.find((item: any) => item.name === "constart-71freq-c");
|
||||||
|
assert.ok(spec);
|
||||||
|
assert.equal(spec.uid, "CONSTART-71FREQ-C");
|
||||||
|
assert.equal(spec.nodeId, "node-d601-f103-v2");
|
||||||
|
assert.equal(spec.workspacePath, "F:\\Work\\ConStart");
|
||||||
|
} finally {
|
||||||
|
await close(server);
|
||||||
|
await rm(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("cloud-api probes discovered hwpod-spec availability through node-ops", async () => {
|
test("cloud-api probes discovered hwpod-spec availability through node-ops", async () => {
|
||||||
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-spec-probe-"));
|
const root = await mkdtemp(path.join(os.tmpdir(), "hwlab-hwpod-spec-probe-"));
|
||||||
const specDir = path.join(root, ".hwlab");
|
const specDir = path.join(root, ".hwlab");
|
||||||
@@ -379,6 +412,32 @@ spec:
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sampleConstartSpecYaml() {
|
||||||
|
return `apiVersion: hwlab.dev/v0alpha1
|
||||||
|
kind: Hwpod
|
||||||
|
metadata:
|
||||||
|
uid: CONSTART-71FREQ-C
|
||||||
|
name: constart-71freq-c
|
||||||
|
spec:
|
||||||
|
targetDevice:
|
||||||
|
board: ConStart 71-FREQ Controller
|
||||||
|
mcu: STM32F103
|
||||||
|
workspace:
|
||||||
|
path: 'F:\\Work\\ConStart'
|
||||||
|
toolchain: keil-mdk
|
||||||
|
debugProbe:
|
||||||
|
type: daplink
|
||||||
|
serialNumber: 3FD750C63E342E24
|
||||||
|
ioProbe:
|
||||||
|
uart:
|
||||||
|
port: COM4
|
||||||
|
baudRate: 921600
|
||||||
|
nodeBinding:
|
||||||
|
nodeId: node-d601-f103-v2
|
||||||
|
nodeType: pc-host
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
async function listen(server: any) {
|
async function listen(server: any) {
|
||||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ async function candidateRegistrySpecPaths(dirs: string[]) {
|
|||||||
try {
|
try {
|
||||||
const entries = await readdir(dir, { withFileTypes: true });
|
const entries = await readdir(dir, { withFileTypes: true });
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (!entry.isFile()) continue;
|
if (!entry.isFile() && !entry.isSymbolicLink()) continue;
|
||||||
if (!/\.ya?ml$/iu.test(entry.name)) continue;
|
if (!/\.ya?ml$/iu.test(entry.name)) continue;
|
||||||
paths.push(path.join(dir, entry.name));
|
paths.push(path.join(dir, entry.name));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user