import fs from "node:fs"; import { URL } from "node:url"; 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 k8sFolder = new URL(".", import.meta.url).pathname; const defaultsFilePath = path.resolve(k8sFolder, "k8s-job.json"); const defaults = JSON.parse(fs.readFileSync(defaultsFilePath)); function commandBuilder(jobId, jobRequest) { const executorPayload = JSON.stringify({ jobId, jobRequest, url: executorUrl, }); const payload = Buffer.from(executorPayload, "utf8").toString("base64"); return [`./${executorBin}`, payload]; } export function jobBuilder(jobRequest) { const { resources, name, image, id: jobId } = jobRequest; // Safety Checks if (!jobId) throw Error("'jobId' required!"); if (!image) throw Error("'image' required!"); // Apply configuration const job = { ...defaults }; job.metadata.name = `qltr-${jobId}`; const container = job.spec.template.spec.containers[0]; container.name = job.metadata.name; container.command = commandBuilder(jobId, jobRequest); 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);