@calltelemetry/ct-lab-mcp 0.8.105 → 0.8.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/assets/stig/SHA256SUMS +15 -1
  2. package/assets/stig/guest/collect-fips-state.sh +6 -0
  3. package/assets/stig/guest/collect-hardware.sh +3 -0
  4. package/assets/stig/guest/collect-host-checks.sh +3 -0
  5. package/assets/stig/guest/collect-network-services.sh +15 -0
  6. package/assets/stig/guest/collect-repolist.sh +3 -0
  7. package/assets/stig/guest/collect-rpm-inventory.sh +3 -0
  8. package/assets/stig/guest/collect-rpm-nevra.sh +3 -0
  9. package/assets/stig/guest/collect-rpmlist.sh +3 -0
  10. package/assets/stig/guest/collect-updateinfo-all.sh +3 -0
  11. package/assets/stig/guest/collect-updateinfo-security.sh +3 -0
  12. package/assets/stig/guest/collect-updateinfo-summary.sh +3 -0
  13. package/assets/stig/guest/oval-eval.sh +11 -0
  14. package/assets/stig/guest/oval-prep.sh +4 -0
  15. package/assets/stig/guest/verify-root.sh +13 -0
  16. package/assets/stig/image/verify-image.sh +28 -0
  17. package/dist/src/generated-version.d.ts +1 -1
  18. package/dist/src/generated-version.js +1 -1
  19. package/dist/src/stig/dist.d.ts +121 -0
  20. package/dist/src/stig/dist.d.ts.map +1 -0
  21. package/dist/src/stig/dist.js +234 -0
  22. package/dist/src/stig/dist.js.map +1 -0
  23. package/dist/src/stig/distribution.d.ts +95 -0
  24. package/dist/src/stig/distribution.d.ts.map +1 -0
  25. package/dist/src/stig/distribution.js +398 -0
  26. package/dist/src/stig/distribution.js.map +1 -0
  27. package/dist/src/stig/evidence.d.ts +135 -0
  28. package/dist/src/stig/evidence.d.ts.map +1 -0
  29. package/dist/src/stig/evidence.js +637 -0
  30. package/dist/src/stig/evidence.js.map +1 -0
  31. package/dist/src/stig/live.d.ts +67 -4
  32. package/dist/src/stig/live.d.ts.map +1 -1
  33. package/dist/src/stig/live.js +226 -5
  34. package/dist/src/stig/live.js.map +1 -1
  35. package/dist/src/stig/markers.d.ts +6 -0
  36. package/dist/src/stig/markers.d.ts.map +1 -0
  37. package/dist/src/stig/markers.js +23 -0
  38. package/dist/src/stig/markers.js.map +1 -0
  39. package/dist/src/stig/model.d.ts +2 -1
  40. package/dist/src/stig/model.d.ts.map +1 -1
  41. package/dist/src/stig/model.js +7 -2
  42. package/dist/src/stig/model.js.map +1 -1
  43. package/dist/src/stig/nodes.d.ts +52 -12
  44. package/dist/src/stig/nodes.d.ts.map +1 -1
  45. package/dist/src/stig/nodes.js +90 -11
  46. package/dist/src/stig/nodes.js.map +1 -1
  47. package/dist/src/stig/ports.d.ts +81 -2
  48. package/dist/src/stig/ports.d.ts.map +1 -1
  49. package/dist/src/stig/pve.d.ts +22 -0
  50. package/dist/src/stig/pve.d.ts.map +1 -0
  51. package/dist/src/stig/pve.js +26 -0
  52. package/dist/src/stig/pve.js.map +1 -0
  53. package/dist/src/stig/runner.d.ts +36 -9
  54. package/dist/src/stig/runner.d.ts.map +1 -1
  55. package/dist/src/stig/runner.js +129 -96
  56. package/dist/src/stig/runner.js.map +1 -1
  57. package/dist/src/tools/quick-provision.d.ts +2 -2
  58. package/dist/src/tools/slot-tools.d.ts +4 -4
  59. package/dist/src/tools/stig-tools.d.ts +52 -8
  60. package/dist/src/tools/stig-tools.d.ts.map +1 -1
  61. package/dist/src/tools/stig-tools.js +105 -21
  62. package/dist/src/tools/stig-tools.js.map +1 -1
  63. package/package.json +1 -1
@@ -0,0 +1,95 @@
1
+ import { type StigNodeName } from "./nodes.js";
2
+ import type { ClaimRecord, StigDeps } from "./ports.js";
3
+ export declare const SYNC_CLAIM_TTL_HOURS = 6;
4
+ /** The detached job outlived the poll budget; it keeps running and nothing is cleaned up. Re-apply to keep waiting. */
5
+ export declare class StillRunningError extends Error {
6
+ constructor(what: string);
7
+ }
8
+ export interface PublishPlan {
9
+ mode: "plan";
10
+ template: string;
11
+ vmid: number | null;
12
+ buildNode: StigNodeName;
13
+ host: string;
14
+ store: string;
15
+ keepVersions: number;
16
+ noop: boolean;
17
+ force: boolean;
18
+ published: boolean;
19
+ receiptFound: boolean;
20
+ steps: readonly string[];
21
+ planDigest: string;
22
+ }
23
+ export interface SyncPlan {
24
+ mode: "plan";
25
+ template: string;
26
+ node: StigNodeName;
27
+ host: string;
28
+ claim: string;
29
+ claimNode: string;
30
+ vmid: number | null;
31
+ thin: string;
32
+ bridge: string;
33
+ noop: boolean;
34
+ syncMode: "synced" | "origin" | "already-present" | "adopted" | "resume";
35
+ poolPercent: number | null;
36
+ poolMaxPercent: number;
37
+ blockedBy: string | null;
38
+ steps: readonly string[];
39
+ planDigest: string;
40
+ }
41
+ export declare const PUBLISH_STEPS: readonly ["verify-published", "export", "template-json", "sign", "index", "upload", "prune", "verify", "receipt"];
42
+ export declare const SYNC_STEPS: readonly ["claim", "verify", "qm-create", "template", "renew", "receipt"];
43
+ /**
44
+ * Golden-image guard: a publishable template is a sealed Proxmox template built by build_stig_template or build.sh (a claim with
45
+ * descriptor mode build-template on the same VMID). A clone, and anything a clone claim describes, is an experiment and can
46
+ * never become an image. `requireClaim` (publish) also refuses a template with no such claim; sync's adoption path only
47
+ * refuses the clone tag and a clone-mode claim.
48
+ */
49
+ export declare function assertGoldenCandidate(guest: {
50
+ name: string;
51
+ vmid?: number;
52
+ tags?: string;
53
+ } | undefined, claim: ClaimRecord | null, opts?: {
54
+ requireClaim?: boolean;
55
+ }): void;
56
+ /** A receipt file (receipts/<template>.json) for this template and VMID that shows fail=0 and error=0 on the template's SSG and DISA scans. */
57
+ export declare function receiptFilePasses(path: string, template: string, vmid?: number): boolean;
58
+ export declare class StigDistribution {
59
+ private readonly d;
60
+ constructor(d: StigDeps);
61
+ private log;
62
+ private sh;
63
+ private buildNode;
64
+ private distDir;
65
+ /** true when index.json lists the template and the node-side verification (fingerprint, signatures, sha256) passes. */
66
+ private verifiedOn;
67
+ planPublish(i: {
68
+ template: string;
69
+ force?: boolean;
70
+ }): Promise<PublishPlan>;
71
+ publish(i: {
72
+ template: string;
73
+ force?: boolean;
74
+ apply?: boolean;
75
+ planDigest?: string;
76
+ receiptPath?: string;
77
+ manifestPath?: string;
78
+ }): Promise<any>;
79
+ private exec;
80
+ /** An unreachable node counts as busy: pruning is the one irreversible step. */
81
+ private anyNodeImporting;
82
+ planSync(i: {
83
+ template: string;
84
+ node: string;
85
+ }): Promise<SyncPlan>;
86
+ sync(i: {
87
+ template: string;
88
+ node: string;
89
+ apply?: boolean;
90
+ planDigest?: string;
91
+ }): Promise<any>;
92
+ /** Destroys a half-created VM (only if it is the one this sync named) and releases the claim. Never called once the template is final. */
93
+ private cleanup;
94
+ }
95
+ //# sourceMappingURL=distribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution.d.ts","sourceRoot":"","sources":["../../../src/stig/distribution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,398 @@
1
+ /**
2
+ * STIG template distribution: publish a sealed template as a signed qcow2 on the shared image store (build node,
3
+ * read-write) and sync it onto a node as a claimed Proxmox template (read-only mount, verified on the node).
4
+ *
5
+ * Mirrors the ct-meta `rhel8-stig-template` scripts publish.sh and sync.sh, with every side effect behind a port
6
+ * (./ports.ts). Plans are pure reads; applies need the digest of the plan they were shown.
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ import { createReadStream, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, chmodSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { STIG_BUILD_NODE, STIG_EVIDENCE_FPR, STIG_IMAGE_KEEP_VERSIONS, STIG_NODE_NAMES, STIG_STORE, resolveStigNode, templateClaimName, } from "./nodes.js";
12
+ import { assertIndexNames, indexRank, EXPORT_DONE, SYNC_DONE, assertTemplateName, buildExportScript, buildIndex, buildPublishReceipt, buildQmCreateScript, buildSyncReceipt, buildTemplateJson, indexHas, parseIndex, pyJson, scanFromSummary, validateTemplateJson, } from "./dist.js";
13
+ import { STIG_POOL_LIMIT_PERCENT, STIG_RECEIPT_ANNOTATION, STIG_TTL_CAP_HOURS, redact, stigDescriptor, validateReceiptSummary } from "./model.js";
14
+ import { listGuests, lowestFreeVmid } from "./pve.js";
15
+ export const SYNC_CLAIM_TTL_HOURS = 6;
16
+ const STORE_DIR = `${STIG_STORE.mount}/rhel8-stig`;
17
+ const digest = (value) => createHash("sha256").update(JSON.stringify(value)).digest("hex");
18
+ /** The detached job outlived the poll budget; it keeps running and nothing is cleaned up. Re-apply to keep waiting. */
19
+ export class StillRunningError extends Error {
20
+ constructor(what) { super(`${what} is still running; re-apply with the same planDigest to keep waiting`); this.name = "StillRunningError"; }
21
+ }
22
+ async function sha256Stream(path) {
23
+ const h = createHash("sha256");
24
+ await new Promise((resolveP, reject) => { const s = createReadStream(path); s.on("data", (c) => h.update(c)); s.on("end", () => resolveP()); s.on("error", reject); });
25
+ return h.digest("hex");
26
+ }
27
+ const sha256Text = (text) => createHash("sha256").update(text).digest("hex");
28
+ export const PUBLISH_STEPS = ["verify-published", "export", "template-json", "sign", "index", "upload", "prune", "verify", "receipt"];
29
+ export const SYNC_STEPS = ["claim", "verify", "qm-create", "template", "renew", "receipt"];
30
+ /**
31
+ * Golden-image guard: a publishable template is a sealed Proxmox template built by build_stig_template or build.sh (a claim with
32
+ * descriptor mode build-template on the same VMID). A clone, and anything a clone claim describes, is an experiment and can
33
+ * never become an image. `requireClaim` (publish) also refuses a template with no such claim; sync's adoption path only
34
+ * refuses the clone tag and a clone-mode claim.
35
+ */
36
+ export function assertGoldenCandidate(guest, claim, opts = {}) {
37
+ if (guest && /(^|[;,\s])rhel8-stig-clone($|[;,\s])/.test(guest.tags ?? ""))
38
+ throw new Error(`refusing: ${guest.name} is tagged as a STIG clone; clones are experiments and are never published as golden templates`);
39
+ if (opts.requireClaim && !claim)
40
+ throw new Error(`refusing: ${guest?.name ?? "the template"} has no build-template claim; only a template built by build_stig_template is published`);
41
+ if (claim) {
42
+ let mode = null;
43
+ try {
44
+ mode = stigDescriptor(claim)?.mode;
45
+ }
46
+ catch {
47
+ mode = null;
48
+ }
49
+ if (opts.requireClaim ? mode !== "build-template" : (mode !== undefined && mode !== null && mode !== "build-template"))
50
+ throw new Error(`refusing: claim ${claim.metadata.name} is a '${String(mode)}' claim, not a build-template claim; only a built template is published`);
51
+ if (opts.requireClaim && guest?.vmid !== undefined && claim.spec?.vmid !== guest.vmid)
52
+ throw new Error(`refusing: claim ${claim.metadata.name} is VMID ${claim.spec?.vmid}, the template is VMID ${guest.vmid}`);
53
+ }
54
+ }
55
+ /** A receipt file (receipts/<template>.json) for this template and VMID that shows fail=0 and error=0 on the template's SSG and DISA scans. */
56
+ export function receiptFilePasses(path, template, vmid) {
57
+ try {
58
+ const rc = JSON.parse(readFileSync(path, "utf8"));
59
+ if (rc?.template?.name !== template)
60
+ return false;
61
+ if (vmid !== undefined && rc?.template?.vmid !== vmid)
62
+ return false;
63
+ return ["template_scan", "template_scan_disa"].every((k) => rc?.[k]?.result_fail === 0 && (rc?.[k]?.result_error ?? 0) === 0 && Number(rc?.[k]?.result_pass) > 0);
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ export class StigDistribution {
70
+ d;
71
+ constructor(d) {
72
+ this.d = d;
73
+ }
74
+ log(line) { this.d.log.info(redact(line)); }
75
+ sh(node) { return this.d.pveFor(node.host); }
76
+ buildNode() { return resolveStigNode(STIG_BUILD_NODE); }
77
+ distDir() { const p = join(this.d.baseDir, "dist"); mkdirSync(p, { recursive: true, mode: 0o700 }); chmodSync(p, 0o700); return p; }
78
+ /** true when index.json lists the template and the node-side verification (fingerprint, signatures, sha256) passes. */
79
+ async verifiedOn(node, template) {
80
+ try {
81
+ await this.d.store.verify(node.host, template, STIG_EVIDENCE_FPR);
82
+ return true;
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ /* ----------------------------------------------------------------- publish */
89
+ async planPublish(i) {
90
+ const template = assertTemplateName(i.template);
91
+ const build = this.buildNode();
92
+ const published = await this.verifiedOn(build, template);
93
+ const force = i.force === true;
94
+ const noop = published && !force;
95
+ const guest = (await listGuests(this.sh(build))).find((g) => g.name === template && g.template === 1);
96
+ if (!noop) {
97
+ const thin = await this.d.storage.status(build.host, build.thin);
98
+ if (thin.type !== "lvmthin")
99
+ throw new Error(`refusing: ${build.thin} on ${build.name} is '${thin.type}', thin storage required`);
100
+ if (!guest)
101
+ throw new Error(`no template named ${template} on ${build.name}`);
102
+ if (!(await this.d.store.isWritable(build.host)))
103
+ throw new Error(`${STIG_STORE.mount} is not mounted rw on ${build.name}`);
104
+ const old = parseIndex(await this.d.store.readText(build.host, `${STORE_DIR}/index.json`));
105
+ assertIndexNames(old);
106
+ if (indexRank(old, template) >= STIG_IMAGE_KEEP_VERSIONS)
107
+ throw new Error(`refusing: ${template} sorts outside the newest ${STIG_IMAGE_KEEP_VERSIONS} versions in index.json and would be pruned at once`);
108
+ }
109
+ const vmid = guest?.vmid ?? null;
110
+ const claim = await this.d.claims.get(templateClaimName(template, build.name));
111
+ if (!noop)
112
+ assertGoldenCandidate(guest, claim, { requireClaim: true });
113
+ const raw = claim?.metadata.annotations?.[STIG_RECEIPT_ANNOTATION];
114
+ const receiptFound = typeof raw === "string";
115
+ return {
116
+ mode: "plan", template, vmid, buildNode: build.name, host: build.host, store: STIG_STORE.name, keepVersions: STIG_IMAGE_KEEP_VERSIONS,
117
+ noop, force, published, receiptFound, steps: PUBLISH_STEPS,
118
+ planDigest: digest({ kind: "publish", template, vmid, node: build.name, host: build.host, keep: STIG_IMAGE_KEEP_VERSIONS, force, noop }),
119
+ };
120
+ }
121
+ async publish(i) {
122
+ const plan = await this.planPublish(i);
123
+ if (!i.apply)
124
+ return plan;
125
+ if (!i.planDigest || i.planDigest !== plan.planDigest)
126
+ throw new Error("plan digest missing or stale; re-run the plan and apply with its planDigest");
127
+ if (plan.noop)
128
+ return { ok: true, noop: true, template: plan.template, message: `no-op: ${plan.template} is already published and verifies` };
129
+ const { template } = plan;
130
+ const vmid = plan.vmid;
131
+ const build = this.buildNode();
132
+ // Golden gate before anything is exported: a passing dual-scan receipt (claim summary or receipt file) and a build-template claim.
133
+ {
134
+ const gateClaim = await this.d.claims.get(templateClaimName(template, build.name));
135
+ const gateGuest = (await listGuests(this.sh(build))).find((g) => g.name === template && g.template === 1);
136
+ assertGoldenCandidate(gateGuest, gateClaim, { requireClaim: true });
137
+ const gateRaw = gateClaim?.metadata.annotations?.[STIG_RECEIPT_ANNOTATION];
138
+ let gateSummary = null;
139
+ if (typeof gateRaw === "string") {
140
+ try {
141
+ gateSummary = validateReceiptSummary(JSON.parse(gateRaw));
142
+ }
143
+ catch {
144
+ gateSummary = null;
145
+ }
146
+ }
147
+ if (gateSummary && !gateSummary.gate.failZero)
148
+ throw new Error(`refusing: the receipt of ${template} does not show fail=0 on both scans`);
149
+ if (!gateSummary && !(i.receiptPath && receiptFilePasses(i.receiptPath, template, vmid)))
150
+ throw new Error(`refusing: ${template} has no passing dual-scan receipt (fail=0 on the SSG and DISA scans); only a gated template is published`);
151
+ }
152
+ const sh = this.sh(build);
153
+ const work = mkdtempSync(join(this.distDir(), `publish-${template}.`));
154
+ chmodSync(work, 0o700);
155
+ try {
156
+ const cfgRun = await sh.run(`qm config ${vmid}`);
157
+ if (cfgRun.code !== 0 || !/^template: 1$/m.test(cfgRun.stdout))
158
+ throw new Error(`VM ${vmid} is not a Proxmox template`);
159
+ this.log(`publish ${template} vmid ${vmid}`);
160
+ await this.exec(build, `install -d ${STIG_STORE.mount}/import ${STORE_DIR}/${template}`);
161
+ // 1. export from the read-only base LV (detached; resumable)
162
+ const job = await this.d.store.runDetached(build.host, { name: `ct-stig-publish-${template}`, script: buildExportScript({ template, vmid }), doneMarker: EXPORT_DONE, polls: 56, intervalMs: 10_000 });
163
+ if (job.state === "failed")
164
+ throw new Error(`export failed: ${redact(job.log).slice(-300)}`);
165
+ if (job.state === "running")
166
+ throw new StillRunningError("export");
167
+ this.log(job.log.trim().split("\n").filter((l) => l.startsWith("lv_attr")).join(" "));
168
+ const qSha = ((await this.d.store.readText(build.host, `${STORE_DIR}/${template}.qcow2.sha256`)) ?? "").trim();
169
+ if (!/^[a-f0-9]{64}$/.test(qSha))
170
+ throw new Error("export produced no readable qcow2 sha256");
171
+ const qBytes = await this.d.store.fileSize(build.host, `${STIG_STORE.mount}/import/${template}.qcow2`);
172
+ const info = JSON.parse((await this.d.store.readText(build.host, `${STORE_DIR}/${template}.qemu-img-info.json`)) ?? "{}");
173
+ const vsize = info["virtual-size"];
174
+ if (!Number.isInteger(vsize))
175
+ throw new Error("qemu-img info has no virtual-size");
176
+ await this.exec(build, `mv ${STORE_DIR}/${template}.qemu-img-info.json ${STORE_DIR}/${template}/qemu-img-info.json; rm -f ${STORE_DIR}/${template}.qcow2.sha256; rm -f /root/ct-stig-publish-${template}.sh`);
177
+ // 2. template.json: hardware from qm config, scan counts from the template claim's receipt, digests of receipt and manifest
178
+ const claim = await this.d.claims.get(templateClaimName(template, build.name));
179
+ const raw = claim?.metadata.annotations?.[STIG_RECEIPT_ANNOTATION];
180
+ let summary = null;
181
+ if (typeof raw === "string") {
182
+ try {
183
+ summary = validateReceiptSummary(JSON.parse(raw));
184
+ }
185
+ catch {
186
+ summary = null;
187
+ }
188
+ }
189
+ if (summary && !summary.gate.failZero)
190
+ throw new Error(`refusing: the receipt of ${template} does not show fail=0 on both scans`);
191
+ const receiptSha = i.receiptPath ? await sha256Stream(i.receiptPath) : typeof raw === "string" ? sha256Text(raw) : null;
192
+ const manifestSha = i.manifestPath ? await sha256Stream(i.manifestPath) : null;
193
+ const nowMs = this.d.clock.now();
194
+ const tpl = buildTemplateJson({ template, vmid, qcowSha256: qSha, qcowBytes: qBytes, virtualBytes: vsize, qmConfig: cfgRun.stdout, scan: scanFromSummary(summary), receiptSha256: receiptSha, manifestSha256: manifestSha, publishedMs: nowMs });
195
+ const tplPath = join(work, "template.json");
196
+ writeFileSync(tplPath, pyJson(tpl));
197
+ const tjSha = await sha256Stream(tplPath);
198
+ // 3. sign the qcow2 (staged locally for gpg) and template.json
199
+ const qPath = join(work, `${template}.qcow2`);
200
+ this.log("staging qcow2 locally for signing");
201
+ await this.d.store.fetchFile(build.host, `${STIG_STORE.mount}/import/${template}.qcow2`, qPath);
202
+ if ((await sha256Stream(qPath)) !== qSha)
203
+ throw new Error("qcow2 changed in transit");
204
+ const signed = await this.d.gpg.signDetached([qPath, tplPath], STIG_EVIDENCE_FPR);
205
+ const sums = `${qSha} ${template}.qcow2\n${tjSha} template.json\n`;
206
+ // 4. index.json (newest first, keep N) + signature
207
+ const old = parseIndex(await this.d.store.readText(build.host, `${STORE_DIR}/index.json`));
208
+ assertIndexNames(old);
209
+ const { index, dropped } = buildIndex({ old, template, vmid, qcowSha256: qSha, qcowBytes: qBytes, templateJsonSha256: tjSha, publishedMs: nowMs });
210
+ const idxPath = join(work, "index.json");
211
+ writeFileSync(idxPath, pyJson(index));
212
+ await this.d.gpg.signDetached([idxPath], STIG_EVIDENCE_FPR);
213
+ // 5. upload; index.json goes last and atomically
214
+ const read = async (p) => readFileSync(p, "utf8");
215
+ const dir = `${STORE_DIR}/${template}`;
216
+ await this.d.store.writeText(build.host, `${dir}/template.json`, await read(tplPath));
217
+ await this.d.store.writeText(build.host, `${dir}/template.json.asc`, await read(`${tplPath}.asc`));
218
+ await this.d.store.writeText(build.host, `${dir}/${template}.qcow2.asc`, await read(`${qPath}.asc`));
219
+ await this.d.store.writeText(build.host, `${dir}/SHA256SUMS`, sums);
220
+ await this.d.store.writeText(build.host, `${STORE_DIR}/stig-evidence-signing.pub.asc`, signed.publicKey);
221
+ await this.d.store.writeText(build.host, `${STORE_DIR}/index.json.new`, await read(idxPath));
222
+ await this.d.store.writeText(build.host, `${STORE_DIR}/index.json.asc.new`, await read(`${idxPath}.asc`));
223
+ await this.exec(build, `cd ${STORE_DIR} && mv index.json.new index.json && mv index.json.asc.new index.json.asc`);
224
+ // 6. prune dropped versions: never 'latest', never one a node is importing
225
+ const pruned = [];
226
+ const skipped = [];
227
+ for (const v of dropped) {
228
+ if (v === index.latest)
229
+ continue;
230
+ if (await this.anyNodeImporting(v)) {
231
+ skipped.push(v);
232
+ this.log(`skip prune of ${v}: in use`);
233
+ continue;
234
+ }
235
+ await this.exec(build, `rm -rf ${STIG_STORE.mount}/import/${v}.qcow2 ${STORE_DIR}/${v}`);
236
+ pruned.push(v);
237
+ }
238
+ // 7. verify from the build node (fingerprint, signatures, sha256), then the receipt
239
+ await this.d.store.verify(build.host, template, STIG_EVIDENCE_FPR);
240
+ const receipt = buildPublishReceipt({ template: tpl, index, buildNode: build.name, pruned });
241
+ const receiptPath = join(this.distDir(), `publish-${template}.json`);
242
+ writeFileSync(receiptPath, pyJson(receipt));
243
+ return { ok: true, noop: false, receipt, receiptPath, skippedPrune: skipped };
244
+ }
245
+ finally {
246
+ rmSync(work, { recursive: true, force: true });
247
+ }
248
+ }
249
+ async exec(node, script) {
250
+ const r = await this.d.store.exec(node.host, script);
251
+ if (r.code !== 0)
252
+ throw new Error(`store command failed on ${node.name} (exit ${r.code}): ${redact(r.stderr).slice(0, 200)}`);
253
+ }
254
+ /** An unreachable node counts as busy: pruning is the one irreversible step. */
255
+ async anyNodeImporting(version) {
256
+ for (const name of STIG_NODE_NAMES) {
257
+ try {
258
+ if (await this.d.store.importing(resolveStigNode(name).host, version))
259
+ return true;
260
+ }
261
+ catch {
262
+ return true;
263
+ }
264
+ }
265
+ return false;
266
+ }
267
+ /* -------------------------------------------------------------------- sync */
268
+ async planSync(i) {
269
+ const template = assertTemplateName(i.template);
270
+ const node = resolveStigNode(i.node);
271
+ const claimName = templateClaimName(template, node.name);
272
+ const guests = await listGuests(this.sh(node));
273
+ const existing = guests.find((g) => g.name === template && g.template === 1);
274
+ const claim = await this.d.claims.get(claimName);
275
+ const noop = Boolean(existing && claim);
276
+ if (existing && !claim)
277
+ assertGoldenCandidate(existing, null); // adopting a template claims it as golden: never a clone
278
+ let blockedBy = null;
279
+ let poolPercent = null;
280
+ const poolMaxPercent = STIG_POOL_LIMIT_PERCENT;
281
+ const adoptable = node.name === STIG_BUILD_NODE;
282
+ let syncMode = noop ? (node.name === STIG_BUILD_NODE ? "origin" : "already-present") : existing ? "adopted" : claim ? "resume" : "synced";
283
+ if (!noop && existing && !claim && !adoptable)
284
+ blockedBy = `a template named ${template} already exists on ${node.name} without its claim; refusing to adopt it off the build node (claim it by hand or retire it first)`;
285
+ if (!blockedBy && !noop && !existing) {
286
+ const st = await this.d.storage.status(node.host, node.thin);
287
+ poolPercent = st.percent;
288
+ if (st.type !== "lvmthin")
289
+ blockedBy = `${node.thin} on ${node.name} is '${st.type}', thin storage required`;
290
+ else if (!Number.isFinite(st.percent) || st.percent > poolMaxPercent)
291
+ blockedBy = `${node.thin} on ${node.name} at ${st.percent}% (max ${poolMaxPercent})`;
292
+ }
293
+ if (!blockedBy && !noop) {
294
+ const idx = parseIndex(await this.d.store.readText(node.host, `${STORE_DIR}/index.json`));
295
+ if (!indexHas(idx, template))
296
+ blockedBy = `${template} is not in the published index.json on ${node.name} (publish it, and check ${STIG_STORE.name} is mounted)`;
297
+ }
298
+ const vmid = existing ? existing.vmid : Number.isInteger(claim?.spec?.vmid) ? claim.spec.vmid : noop ? null : lowestFreeVmid(guests, (await this.d.claims.list()).filter((c) => (c.spec?.node ?? "minis") === node.claimNode));
299
+ return {
300
+ mode: "plan", template, node: node.name, host: node.host, claim: claimName, claimNode: node.claimNode, vmid, thin: node.thin, bridge: node.bridge,
301
+ noop, syncMode, poolPercent, poolMaxPercent, blockedBy, steps: SYNC_STEPS,
302
+ planDigest: digest({ kind: "sync", template, node: node.name, host: node.host, claim: claimName, vmid, thin: node.thin, bridge: node.bridge, noop, syncMode }),
303
+ };
304
+ }
305
+ async sync(i) {
306
+ const plan = await this.planSync(i);
307
+ if (!i.apply)
308
+ return plan;
309
+ if (!i.planDigest || i.planDigest !== plan.planDigest)
310
+ throw new Error("plan digest missing or stale; re-run the plan and apply with its planDigest");
311
+ if (plan.blockedBy)
312
+ throw new Error(`refusing: ${plan.blockedBy}`);
313
+ const node = resolveStigNode(plan.node);
314
+ const { template, claim: claimName } = plan;
315
+ const sh = this.sh(node);
316
+ let vmid = plan.vmid;
317
+ let mode = plan.syncMode === "resume" ? "synced" : plan.syncMode;
318
+ let state = plan.noop ? "final" : "start";
319
+ if (!plan.noop) {
320
+ // 1. claim first (a half-synced node is a claimed one the operator can reap)
321
+ let claim = await this.d.claims.get(claimName);
322
+ if (!claim) {
323
+ this.log(`claim ${claimName}: creating (vmid ${vmid}, ${SYNC_CLAIM_TTL_HOURS}h) on ${node.claimNode}`);
324
+ claim = await this.d.claims.create({ name: claimName, vmid, vmName: template, ttlHours: SYNC_CLAIM_TTL_HOURS, node: node.claimNode });
325
+ }
326
+ else
327
+ vmid = claim.spec.vmid;
328
+ state = "claimed";
329
+ try {
330
+ await this.d.claims.waitReady(claimName);
331
+ this.log(`claim=${claimName} node=${node.name} vmid=${vmid} Ready`);
332
+ // 2. verify on the node: pinned fingerprint, index, template.json and qcow2 sha256 + signatures
333
+ const verified = await this.d.store.verify(node.host, template, STIG_EVIDENCE_FPR);
334
+ const tplText = await this.d.store.readText(node.host, `${STORE_DIR}/${template}/template.json`);
335
+ if (!tplText)
336
+ throw new Error("template.json is missing on the store");
337
+ if (sha256Text(tplText) !== verified.templateJsonSha256)
338
+ throw new Error("template.json sha256 mismatch");
339
+ const tpl = validateTemplateJson(JSON.parse(tplText), template);
340
+ if (tpl.image.sha256 !== verified.qcow2Sha256)
341
+ throw new Error("template.json image sha256 does not match the verified qcow2");
342
+ this.log(`verified on ${node.name}: index.json, template.json and ${template}.qcow2 signatures + sha256`);
343
+ if (plan.syncMode === "adopted")
344
+ state = "final";
345
+ else {
346
+ // 3. qm create + import-from onto thin storage, efidisk, cloud-init, qm template (detached; the import takes minutes)
347
+ state = "created";
348
+ const job = await this.d.store.runDetached(node.host, { name: `ct-stig-sync-${template}`, script: buildQmCreateScript({ template: tpl, vmid, thin: node.thin, bridge: node.bridge }), doneMarker: SYNC_DONE, polls: 55, intervalMs: 10_000 });
349
+ if (job.state === "running")
350
+ throw new StillRunningError("import");
351
+ if (job.state === "failed")
352
+ throw new Error(`qm create/import failed: ${redact(job.log).slice(-300)}`);
353
+ await this.exec(node, `rm -f /root/ct-stig-sync-${template}.sh`);
354
+ const cfg = await sh.run(`qm config ${vmid}`);
355
+ if (cfg.code !== 0 || !/^template: 1$/m.test(cfg.stdout))
356
+ throw new Error(`VM ${vmid} is not a template after the import`);
357
+ state = "final"; // from here a receipt problem must never destroy the template
358
+ }
359
+ }
360
+ catch (e) {
361
+ if (!(e instanceof StillRunningError) && state !== "final")
362
+ await this.cleanup(node, claimName, template, vmid, state === "created");
363
+ throw e;
364
+ }
365
+ await this.d.claims.renew(claimName, STIG_TTL_CAP_HOURS - 1);
366
+ }
367
+ else {
368
+ await this.d.store.verify(node.host, template, STIG_EVIDENCE_FPR);
369
+ }
370
+ // 4. receipt: thin mapped bytes of the template disk
371
+ const mapped = await this.d.storage.mappedBytes(node.host, vmid);
372
+ const idx = parseIndex(await this.d.store.readText(node.host, `${STORE_DIR}/index.json`));
373
+ const entry = idx.versions.find((v) => v.name === template);
374
+ const receipt = buildSyncReceipt({ template, node: node.name, vmid, claim: claimName, mode, qcowSha256: entry.qcow2_sha256, thin: node.thin, lvSizeBytes: mapped.lvSizeBytes, mappedPercent: mapped.mappedPercent, syncedMs: this.d.clock.now() });
375
+ const receiptPath = join(this.distDir(), `sync-${template}-${node.name}.json`);
376
+ writeFileSync(receiptPath, pyJson(receipt));
377
+ return { ok: true, noop: plan.noop, receipt, receiptPath };
378
+ }
379
+ /** Destroys a half-created VM (only if it is the one this sync named) and releases the claim. Never called once the template is final. */
380
+ async cleanup(node, claimName, template, vmid, created) {
381
+ this.log(`sync failed; releasing claim ${claimName}`);
382
+ try {
383
+ if (created) {
384
+ const g = (await listGuests(this.sh(node))).find((x) => x.vmid === vmid);
385
+ if (g && g.name === template && g.template !== 1)
386
+ await this.sh(node).run(`qm destroy ${vmid} --purge`);
387
+ }
388
+ }
389
+ catch { /* best effort */ }
390
+ try {
391
+ const rec = await this.d.claims.get(claimName);
392
+ if (rec)
393
+ await this.d.claims.delete(claimName, rec.metadata.uid);
394
+ }
395
+ catch { /* best effort */ }
396
+ }
397
+ }
398
+ //# sourceMappingURL=distribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution.js","sourceRoot":"","sources":["../../../src/stig/distribution.ts"],"names":[],"mappings":"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"}