import fs from "node:fs"; import path from "node:path"; const { QUALITEER_EXECUTOR_URL, QUALITEER_EXECUTOR_USE_SCRIPT, QUALITEER_EXECUTOR_BIN, QUALITEER_EXECUTOR_BIN_URL, } = process.env; const executorUrl = QUALITEER_EXECUTOR_URL; const executorAsScript = QUALITEER_EXECUTOR_USE_SCRIPT === "true"; const executorBin = QUALITEER_EXECUTOR_BIN ?? `qltr-executor`; const executorBinFetchUrl = QUALITEER_EXECUTOR_BIN_URL; const jobsDir = "jobs/"; const jobsPath = path.resolve(jobsDir); const defaultsFile = path.resolve("./lib/jobs/k8s/k8s-job.json"); const defaults = JSON.parse(fs.readFileSync(defaultsFile)); function wrapCommand(jobId, command) { const bin = executorAsScript ? `node ${executorBin}` : `chmod +x ${executorBin} && ./${executorBin}`; const executorPayload = JSON.stringify({ jobId, command, url: executorUrl }); const payload = Buffer.from(executorPayload, "utf8").toString("base64"); const curlCmd = `if ! [ -f qltr-executor ]; then curl -o qltr-executor ${executorBinFetchUrl}; fi || true && ${bin} ${payload}`; return curlCmd; } export function jobBuilder(jobRequest) { const { resources, name, image, command, id: jobId } = jobRequest; // Safety Checks if (!jobId) throw Error("'jobId' required!"); if (!name) throw Error("'name' required!"); if (!command) throw Error("'command' required!"); if (!image) throw Error("'image' required!"); if (!Array.isArray(command)) throw Error("'command' must be an array!"); // Apply configuration const job = { ...defaults }; job.metadata.name = `qltr-${name}-${jobId}`; const container = job.spec.template.spec.containers[0]; container.name = job.metadata.name; container.command = wrapCommand(jobId, command); container.image = JSON.stringify(image); // Apply resources job.resources = { ...job.resources, ...resources }; return job; } export const createFile = (job) => { const { name } = job.metadata; if (!fs.existsSync(jobsPath)) fs.mkdirSync(jobsPath); const filePath = path.resolve(jobsDir, `${name}.json`); fs.writeFileSync(filePath, JSON.stringify(job)); return filePath; }; export const deleteFile = (filePath) => fs.unlinkSync(filePath);