feat: add v02 device-pod env reuse boot path
This commit is contained in:
@@ -141,6 +141,12 @@
|
||||
"artifactCatalog": "deploy/artifact-catalog.v02.json",
|
||||
"runtimePath": "deploy/gitops/g14/runtime-v02",
|
||||
"imageTagMode": "full",
|
||||
"envReuseServices": [
|
||||
"hwlab-device-pod"
|
||||
],
|
||||
"bootScripts": {
|
||||
"hwlab-device-pod": "deploy/runtime/boot/hwlab-device-pod.sh"
|
||||
},
|
||||
"services": [
|
||||
{
|
||||
"serviceId": "hwlab-cloud-api",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
export HWLAB_SERVICE_ID="hwlab-device-pod"
|
||||
export HWLAB_RUNTIME_MODE="${HWLAB_RUNTIME_MODE:-env-reuse-git-mirror-checkout}"
|
||||
export HWLAB_COMMIT_ID="${HWLAB_BOOT_COMMIT:?HWLAB_BOOT_COMMIT is required}"
|
||||
export HWLAB_REVISION="${HWLAB_BOOT_COMMIT}"
|
||||
export HWLAB_IMAGE="${HWLAB_ENVIRONMENT_IMAGE:-${HWLAB_IMAGE:-}}"
|
||||
export HWLAB_IMAGE_DIGEST="${HWLAB_ENVIRONMENT_DIGEST:-${HWLAB_IMAGE_DIGEST:-unknown}}"
|
||||
|
||||
exec bun cmd/hwlab-device-pod/main.ts
|
||||
@@ -0,0 +1,61 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync, mkdirSync, rmSync, symlinkSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const bootRepo = requiredEnv("HWLAB_BOOT_REPO");
|
||||
const bootCommit = requiredEnv("HWLAB_BOOT_COMMIT");
|
||||
const bootSh = requiredEnv("HWLAB_BOOT_SH");
|
||||
const checkoutDir = process.env.HWLAB_BOOT_CHECKOUT_DIR || "/workspace/hwlab-boot/repo";
|
||||
const runtimeNodeModules = process.env.HWLAB_RUNTIME_NODE_MODULES || "/opt/hwlab-env/node_modules";
|
||||
|
||||
if (!/^[a-f0-9]{40}$/u.test(bootCommit)) fail("HWLAB_BOOT_COMMIT must be a full 40-char SHA");
|
||||
if (path.isAbsolute(bootSh) || bootSh.split("/").includes("..")) fail("HWLAB_BOOT_SH must be repo-relative");
|
||||
|
||||
const readUrl = process.env.HWLAB_BOOT_READ_URL || mirrorReadUrl(bootRepo);
|
||||
mkdirSync(path.dirname(checkoutDir), { recursive: true });
|
||||
rmSync(checkoutDir, { recursive: true, force: true });
|
||||
run("git", ["clone", "--no-checkout", readUrl, checkoutDir], "/");
|
||||
run("git", ["fetch", "--depth", "1", "origin", bootCommit], checkoutDir);
|
||||
run("git", ["checkout", "--detach", bootCommit], checkoutDir);
|
||||
linkNodeModules();
|
||||
|
||||
const scriptPath = path.join(checkoutDir, bootSh);
|
||||
if (!existsSync(scriptPath)) fail(`boot script not found: ${bootSh}`);
|
||||
run("sh", [scriptPath], checkoutDir, { replace: true });
|
||||
|
||||
function requiredEnv(name: string): string {
|
||||
const value = process.env[name];
|
||||
if (!value) fail(`${name} is required`);
|
||||
return value;
|
||||
}
|
||||
|
||||
function mirrorReadUrl(repo: string): string {
|
||||
if (/github\.com[:/]pikasTech\/HWLAB(?:\.git)?$/u.test(repo)) {
|
||||
return "http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git";
|
||||
}
|
||||
fail("no mirror resolver for HWLAB_BOOT_REPO; refusing direct runtime GitHub fallback");
|
||||
}
|
||||
|
||||
function linkNodeModules(): void {
|
||||
const target = path.join(checkoutDir, "node_modules");
|
||||
if (existsSync(target) || !existsSync(runtimeNodeModules)) return;
|
||||
symlinkSync(runtimeNodeModules, target, "dir");
|
||||
}
|
||||
|
||||
function run(command: string, args: string[], cwd: string, options: { replace?: boolean } = {}): void {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd,
|
||||
env: process.env,
|
||||
stdio: "inherit"
|
||||
});
|
||||
if (result.error) fail(`${command} failed to start: ${result.error.message}`);
|
||||
if (result.signal) process.kill(process.pid, result.signal);
|
||||
const code = result.status ?? 0;
|
||||
if (options.replace) process.exit(code);
|
||||
if (code !== 0) process.exit(code);
|
||||
}
|
||||
|
||||
function fail(message: string): never {
|
||||
process.stderr.write(`${JSON.stringify({ status: "failed", error: "hwlab_env_reuse_launcher_failed", message })}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user