# Katalog: Distributionen und Profile Distributionen und Profile sind Daten, kein Code. Jede liegt als YAML-Datei unter `catalog/` und wird beim Start von ProxDeploy in die Datenbank abgeglichen. Die Datei ist maßgeblich für den Inhalt; in der Oberfläche (*Katalog*) lassen sich Einträge nur aktivieren und deaktivieren. Eine fehlerhafte Datei wird mit Dateiname und Fehlerstelle im Log gemeldet und übersprungen. Regeln für beide Arten: - Dateiname = `id` + `.yaml` (`catalog/distros/debian-13.yaml` → `id: debian-13`) - unbekannte Schlüssel sind ein Fehler – ein Tippfehler fällt so sofort auf - nur HTTPS-Quellen ## Neue Distribution hinzufügen Beispiel Debian 13: ```yaml id: debian-13 name: Debian 13 „Trixie“ family: debian # wählt den Provisionierungs-Adapter os: id: debian # für Platzhalter in Profilen: {{ os.id }} version_id: "13" # {{ os.version_id }} – in Anführungszeichen, sonst wird 22.04 zur Zahl codename: trixie # {{ os.codename }} arch: amd64 vm: image_url: https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2 checksum_url: https://cloud.debian.org/images/cloud/trixie/latest/SHA512SUMS checksum_type: sha512 # sha256 | sha512 format: qcow2 # qcow2 | raw | vmdk default_user: debian guest_agent_preinstalled: false # sonst baut ProxDeploy ihn beim Template-Bau ein bios: ovmf # ovmf (UEFI, Standard) | seabios min_disk_gb: 4 lxc: template_pattern: "debian-13-standard_*_amd64.tar.zst" # wie in `pveam available` ostype: debian ``` `vm` oder `lxc` darf fehlen, wenn die Distribution nur eins davon kann. Bei mehreren passenden LXC-Templates gewinnt die höchste Version. Die Prüfsummen-Datei darf im GNU-Format (` ` oder ` *`) oder im BSD-Format (`SHA256 () = `) vorliegen. Gehört die Distribution zu einer Familie, für die es noch keinen Adapter gibt (etwa `rhel` für Rocky oder Alma, `alpine`), braucht es zusätzlich einen Adapter: 1. `src/engine/adapter/.ts` anlegen, das Interface `FamilienAdapter` aus `src/engine/adapter/schnittstelle.ts` umsetzen (Pakete, Dienste, Paketquellen, Zeitzone, Locale, Tastatur, Benutzer, SSH-Härtung, Guest-Agent, automatische Updates) 2. in `src/engine/adapter/index.ts` eintragen 3. Tests nach dem Muster von `tests/engine/profile.test.ts`, dazu ein Image in `tests/container/profile-pruefen.sh` 4. in den Profilen unter `families:` eine Umsetzung für die neue Familie ergänzen – Profile ohne Umsetzung erscheinen im Assistenten ausgegraut ## Eigenes Profil anlegen Ein Profil ist eine Liste von Schritten je Distributionsfamilie. Der Adapter übersetzt sie in ein Shell-Skript, das bei VMs über den Guest-Agent und bei Containern per SSH läuft. ```yaml id: nginx name: nginx description: Webserver mit Startseite requires: [base] # wird automatisch davor ausgeführt variables: - { name: titel, label: Seitentitel, default: Willkommen } - { name: tls, label: Zertifikat per certbot, type: boolean, default: false } lxc: features: { nesting: false } # Container-Features, die das Profil braucht families: debian: - packages: [nginx] - file: path: /var/www/html/index.html content: |

{{ var.titel }}

{{ guest.name }} · {{ os.id }} {{ os.version_id }}

- service: { name: nginx, enable: true, start: true } - packages: [certbot, python3-certbot-nginx] if: tls ``` ### Schritte | Schritt | Wirkung | |---|---| | `update: true` | Paketlisten aktualisieren und alle Pakete aktualisieren | | `packages: [a, b]` | Pakete installieren | | `service: { name, enable, start, restart }` | Dienst aktivieren, starten oder neu starten | | `repo: { name, key_url, uris, suites, components }` | Paketquelle mit Schlüssel einrichten (deb822) | | `repo_package: ` | ein Paket installieren, das selbst eine Quelle einrichtet (z. B. zabbix-release) | | `file: { path, content, mode }` | Datei schreiben (Inhalt wird unverändert übertragen) | | `timezone`, `locale`, `keyboard` | Zeitzone, Sprache, Tastaturbelegung | | `ssh_harden: { password_auth, root_login }` | SSH absichern – läuft immer ganz am Ende | | `guest_agent: true` | QEMU-Guest-Agent (in Containern übersprungen) | | `unattended_upgrades: true` | automatische Sicherheitsupdates | | `run: ` | freier Shell-Befehl – nicht portabel, nur wenn nichts anderes passt | Jeder Schritt kann `if: ` (oder `if: "!"`) tragen und läuft dann nur, wenn die Variable wahr bzw. falsch ist. Fest eingebaut sind `if: vm` und `if: lxc` – etwa für Zeitsync, die in einem unprivilegierten Container nicht laufen kann. ### Platzhalter `{{ var. }}` (Profil-Variable), `{{ os.id }}`, `{{ os.version_id }}`, `{{ os.codename }}`, `{{ guest.name }}`, `{{ guest.user }}`. `{{ var.a ?? var.b }}` nimmt `b`, wenn `a` leer ist. Ein unbekannter Platzhalter ist ein Fehler, kein leerer Text. In `run`-Schritten wird jeder eingesetzte Wert für die Shell gequotet – eine Eingabe im Formular kann so nie zu Code werden. Variablen dürfen keine Zeilenumbrüche enthalten. ### Variablentypen `string` (Standard), `number`, `boolean`, `select` (mit `options: [...]`). `required: true` macht das Feld im Assistenten zur Pflicht; `default` füllt es vor; `help` erscheint darunter. ### Prüfen ```bash pnpm exec tsx scripts/profil-rendern.ts debian-13 nginx titel=Hallo # Skript ansehen pnpm test:container debian-13 # wirklich ausführen ```