"use client"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { EINGABE_KLASSE, Feld } from "@/components/formular"; import { Knopf } from "@/components/knopf"; import { Status } from "@/components/status"; import { apiAufruf, ApiFehler } from "@/lib/api-client"; type Knoten = { name: string; storages: string[]; bridges: string[] }; export function TemplateBauen({ server, distributionen, knoten, faehigkeit, profile, }: { server: string; distributionen: Array<{ id: string; name: string; familie: string }>; profile: Array<{ id: string; name: string; requires: string[]; familien: string[] }>; knoten: Knoten[]; faehigkeit: { weg: "api" | "ssh" | "nicht_moeglich"; grund: string }; }) { const router = useRouter(); const [werte, setWerte] = useState({ distribution: distributionen.find((d) => d.id === "debian-13")?.id ?? distributionen[0]?.id ?? "", knoten: knoten[0]?.name ?? "", storage: knoten[0]?.storages[0] ?? "", bridge: knoten[0]?.bridges.includes("vmbr0") ? "vmbr0" : (knoten[0]?.bridges[0] ?? ""), profile: [] as string[], }); const [fehler, setFehler] = useState<{ text: string; hinweis?: string } | null>(null); const [sendet, setSendet] = useState(false); const aktuell = knoten.find((k) => k.name === werte.knoten); async function bauen(ereignis: React.FormEvent) { ereignis.preventDefault(); setSendet(true); setFehler(null); try { const { kurzId } = await apiAufruf<{ kurzId: string }>( "POST", `/api/v1/server/${server}/templates`, werte, ); router.push(`/auftraege/${kurzId}`); } catch (ursache) { setFehler( ursache instanceof ApiFehler ? { text: ursache.message, hinweis: ursache.hinweis } : { text: "Unerwarteter Fehler." }, ); setSendet(false); } } return (
{faehigkeit.weg === "api" ? "Per API" : faehigkeit.weg === "ssh" ? "Per SSH" : "Nicht möglich"} –{" "} {faehigkeit.grund}
Profile einbacken (optional)

Was hier gewählt ist, ist in jedem Klon schon installiert – Deployments mit diesen Profilen sind schneller fertig. Profile mit Pflichtangaben (z. B. Zabbix-Server) laufen beim Ausrollen.

{profile .filter((p) => p.familien.includes(distributionen.find((d) => d.id === werte.distribution)?.familie ?? ""), ) .map((p) => { const benoetigt = profile.some( (x) => werte.profile.includes(x.id) && x.requires.includes(p.id), ); return ( ); })}

Der Vorbereitungsstart braucht DHCP und Internetzugang auf der Bridge, um qemu-guest-agent zu installieren.

{sendet ? "Startet …" : "Template bauen"}
{fehler ? (
{fehler.text} {fehler.hinweis ?

{fehler.hinweis}

: null}
) : null}
); }