Files
proxdeploy/src/worker/ablaeufe/ausrollen.ts
T
florian.wildeandClaude Opus 5.5 d25ec54ef9 feat(lxc): LXC-Container ausrollen, mit oder ohne Node-SSH
Container aus dem Proxmox-Template (neueste passende Version aus
aplinfo), unprivilegiert, nesting automatisch für docker. Weil Proxmox
keine Exec-API für Container hat, läuft die Provisionierung per SSH:
bevorzugt pct exec über den Node, sonst direkt in den Container mit
einem Bereitstellungsschlüssel, der am Ende wieder entfernt wird.

Auf pve-demo beide Wege geprüft: Debian 13 mit docker per pct exec
(hello-world läuft mit nesting allein) und Ubuntu 24.04 per SSH in den
Container. Dabei gefunden: chrony scheitert ohne CAP_SYS_TIME (jetzt
if: vm), sshd -t auf Ubuntu 24.04 ohne /run/sshd.

Closes #009

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:19:13 +02:00

80 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { phasenAusfuehren } from "@/engine/ablauf/ablauf";
import { sshBefehl } from "@/engine/ablaeufe/vm-ausrollen";
import { ProxmoxClient } from "@/engine/proxmox/client";
import { prisma } from "@/lib/db";
import { melden } from "@/server/ereignisse/senke";
import {
ausrollenVorbereiten,
ausrollSchritte,
kopfzeile,
type AusrollStand,
} from "@/server/services/ausrollen";
import { verbindungAus } from "@/server/services/server";
import { vmidReservieren } from "@/server/services/vmid";
import { ablaufRegistrieren } from "../ausfuehren";
import { aufrufLogger } from "../aufruf-log";
ablaufRegistrieren("AUSROLLEN", async ({ auftrag, senke, abbruchGewuenscht, angelegt }) => {
// Dieselbe Vorbereitung wie beim Anlegen – der Katalog könnte sich seitdem geändert haben.
const v = await ausrollenVorbereiten(auftrag.anfrage);
const stand: AusrollStand = {};
const kopfSetzen = async () => {
await prisma.auftrag.update({
where: { id: auftrag.id },
data: { kopf: kopfzeile(v, stand), knoten: stand.knoten ?? null },
});
await melden(auftrag.id);
};
await kopfSetzen();
const client = new ProxmoxClient(verbindungAus(v.server), { beobachter: aufrufLogger(senke) });
try {
const ergebnis = await phasenAusfuehren(
ausrollSchritte(
v,
{
client,
vmidReservieren: async (belegt, wunsch) => {
const vmid = await vmidReservieren({
serverId: v.server.id,
auftragId: auftrag.id,
belegt,
von: v.server.gastVmidVon,
wunsch,
});
await prisma.auftrag.update({ where: { id: auftrag.id }, data: { vmid } });
await kopfSetzen();
return vmid;
},
templateVmidReservieren: (belegt) =>
vmidReservieren({
serverId: v.server.id,
auftragId: auftrag.id,
belegt,
von: v.server.templateVmidVon,
bis: v.server.templateVmidBis,
}),
angelegt,
auftragKurzId: auftrag.kurzId,
},
stand,
),
senke,
{ abbruchGewuenscht },
);
await kopfSetzen();
if (!ergebnis.ok) return ergebnis;
return {
ok: true,
ergebnis: {
vmid: stand.vmid,
knoten: stand.knoten,
ip: stand.ip,
ssh: sshBefehl(v.anfrage.zugang.benutzer, stand.ip),
},
};
} finally {
await client.schliessen();
}
});