Files
klaster/utils/update-garm-image-pin.mjs
2026-03-14 02:38:18 +01:00

92 lines
2.6 KiB
JavaScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execFileSync } from "node:child_process";
const pinFile = "apps/garm/image-source.env";
const deploymentFile = "apps/garm/deployment.yaml";
function fail(message) {
console.error(message);
process.exit(1);
}
function parseEnvFile(content) {
const vars = {};
for (const line of content.split(/\r?\n/)) {
if (!line || line.startsWith("#")) {
continue;
}
const idx = line.indexOf("=");
if (idx === -1) {
continue;
}
const key = line.slice(0, idx).trim();
const value = line.slice(idx + 1).trim();
vars[key] = value;
}
return vars;
}
function updateOrAdd(content, key, value) {
const pattern = new RegExp(`^${key}=.*$`, "m");
if (pattern.test(content)) {
return content.replace(pattern, `${key}=${value}`);
}
return `${content.trimEnd()}\n${key}=${value}\n`;
}
function gitOut(args, options = {}) {
return execFileSync("git", args, {
encoding: "utf8",
...options,
}).trim();
}
function gitRun(args, options = {}) {
execFileSync("git", args, options);
}
const pinContent = fs.readFileSync(pinFile, "utf8");
const vars = parseEnvFile(pinContent);
const commit = vars.GARM_COMMIT;
const imageRepo = vars.GARM_IMAGE_REPO || "gitea.lumpiasty.xyz/lumpiasty/garm-k8s";
if (!commit || !/^[0-9a-f]{40}$/.test(commit)) {
fail(`Invalid or missing GARM_COMMIT in ${pinFile}`);
}
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "garm-main-"));
let commitNumber;
try {
gitRun(["clone", "--filter=blob:none", "https://github.com/cloudbase/garm.git", tmpDir], {
stdio: "ignore",
});
commitNumber = gitOut(["-C", tmpDir, "rev-list", "--count", commit]);
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
if (!/^\d+$/.test(commitNumber)) {
fail(`Unable to resolve commit number for ${commit}`);
}
const image = `${imageRepo}:r${commitNumber}`;
let nextPin = pinContent;
nextPin = updateOrAdd(nextPin, "GARM_COMMIT_NUMBER", commitNumber);
nextPin = updateOrAdd(nextPin, "GARM_IMAGE_REPO", imageRepo);
nextPin = updateOrAdd(nextPin, "GARM_IMAGE", image);
fs.writeFileSync(pinFile, nextPin, "utf8");
const deployment = fs.readFileSync(deploymentFile, "utf8");
const imagePattern = /image:\s*(?:ghcr\.io\/cloudbase\/garm:[^\s]+|gitea\.lumpiasty\.xyz\/(?:Lumpiasty|lumpiasty)\/garm(?:-k8s)?:[^\s]+)/;
if (!imagePattern.test(deployment)) {
fail(`Unable to update garm image in ${deploymentFile}`);
}
const updatedDeployment = deployment.replace(imagePattern, `image: ${image}`);
fs.writeFileSync(deploymentFile, updatedDeployment, "utf8");
console.log(`Pinned garm image to ${image}`);