diff --git a/config/hwlab-node-control-plane.yaml b/config/hwlab-node-control-plane.yaml index 135a7f6d..601d51d0 100644 --- a/config/hwlab-node-control-plane.yaml +++ b/config/hwlab-node-control-plane.yaml @@ -152,6 +152,8 @@ targets: - COPY --from=python-runtime /usr/local /usr/local - COPY --from=docker-cli-runtime /usr/local/bin/docker /usr/local/bin/docker - RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx + - ENV HWLAB_CI_NODE_DEPS=/opt/hwlab-ci-node-deps/node_modules + - RUN set -eu; mkdir -p /opt/hwlab-ci-node-deps; cd /opt/hwlab-ci-node-deps; npm init -y >/dev/null; if [ -n "${HTTP_PROXY:-}" ]; then npm config set proxy "$HTTP_PROXY"; fi; if [ -n "${HTTPS_PROXY:-}" ]; then npm config set https-proxy "$HTTPS_PROXY"; fi; npm install --omit=dev --ignore-scripts --no-audit --no-fund yaml@2.8.3; node --input-type=module -e 'import("yaml").then(() => console.log("yaml-ok"))' - RUN node --version && npm --version && bun --version && git --version && python3 --version && docker --version && ssh -V buildArgs: NODE_IMAGE: docker.io/library/node:22-bookworm-slim diff --git a/scripts/src/hwlab-node-impl.ts b/scripts/src/hwlab-node-impl.ts index 34864e62..912e4d29 100644 --- a/scripts/src/hwlab-node-impl.ts +++ b/scripts/src/hwlab-node-impl.ts @@ -5051,11 +5051,16 @@ function nodeRuntimePipelinePostprocessScript(): string[] { "}", "function stepEnvBootstrapScript() {", " const entries = Object.entries(overlay.stepEnv || {}).filter(([, value]) => value !== undefined && value !== null && String(value).length > 0);", - " if (entries.length === 0) return '';", " const lines = ['# unidesk-step-env-bootstrap'];", " for (const [name, value] of entries) lines.push(`export ${name}=${shellSingle(value)}`);", " if (Object.prototype.hasOwnProperty.call(overlay.stepEnv || {}, 'HOME')) lines.push('mkdir -p \"$HOME\"');", " if (Object.prototype.hasOwnProperty.call(overlay.stepEnv || {}, 'XDG_CONFIG_HOME')) lines.push('mkdir -p \"$XDG_CONFIG_HOME\"');", + " lines.push('ci_node_deps=\"${HWLAB_CI_NODE_DEPS:-/opt/hwlab-ci-node-deps/node_modules}\"');", + " lines.push('if [ -d \"$ci_node_deps\" ]; then');", + " lines.push(' if [ -d /workspace/source/repo ]; then ci_node_deps_target=/workspace/source/repo/node_modules; else ci_node_deps_target=./node_modules; fi');", + " lines.push(' mkdir -p \"$ci_node_deps_target\"');", + " lines.push(' for ci_node_dep in yaml; do if [ -d \"$ci_node_deps/$ci_node_dep\" ] && [ ! -e \"$ci_node_deps_target/$ci_node_dep\" ]; then ln -s \"$ci_node_deps/$ci_node_dep\" \"$ci_node_deps_target/$ci_node_dep\"; fi; done');", + " lines.push('fi');", " return lines.join('\\n');", "}", "function runtimeGitopsPostprocessScript() {", @@ -5609,6 +5614,8 @@ function nodeRuntimePipelinePostprocessScript(): string[] { "}", "function patchScript(script) {", " let result = String(script || '');", + " const bootstrap = stepEnvBootstrapScript();", + " if (bootstrap && !result.includes('unidesk-step-env-bootstrap')) result = `${bootstrap}\\n${result}`;", " const inlineDeployServiceIdParser = `const deployText = fs.readFileSync(deployPath, 'utf8');\\nconst deploy = { services: [...deployText.matchAll(/(?:^|\\\\n)\\\\s*serviceId:\\\\s*[\\\"']?([^\\\"'\\\\n#]+)[\\\"']?/g)].map((match) => ({ serviceId: match[1].trim() })) };`;", " result = result.split('import { readStructuredFile } from \"./scripts/src/structured-config.mjs\";\\n').join('');", " result = result.split('const deploy = await readStructuredFile(process.cwd(), deployPath);').join(inlineDeployServiceIdParser);", @@ -5651,7 +5658,6 @@ function nodeRuntimePipelinePostprocessScript(): string[] { " result = result.replace('rm -rf \"$runtime_path\" \"$catalog_path\"; else rm -rf deploy/gitops/node \"$catalog_path\"; fi', 'rm -rf \"$runtime_path\" \"$catalog_path\" \"$unidesk_legacy_runtime_path\"; else rm -rf deploy/gitops/node \"$catalog_path\"; fi');", " result = result.replace('git add \"$catalog_path\" \"$runtime_path\"', 'git add \"$catalog_path\" \"$runtime_path\"\\n if [ -n \"${unidesk_legacy_runtime_path:-}\" ]; then git add -A \"$unidesk_legacy_runtime_path\" || true; fi');", " }", - " const bootstrap = stepEnvBootstrapScript();", " if (bootstrap && result.includes('git config --global') && !result.includes('unidesk-step-env-bootstrap')) {", " result = result.replace(/\\n([ \\t]*)git config --global/g, (match, indent) => `\\n${indent}${bootstrap.split('\\n').join(`\\n${indent}`)}\\n${indent}git config --global`);", " }",