feat(engine): Adapter debian und Profil-Engine
Profile sind deklarative Schritte je Distributionsfamilie; der Adapter übersetzt sie in ein idempotentes Shell-Skript. Ein neuer Adapter (rhel, alpine) ist eine Datei und ein Eintrag in der Registry. Variablen werden typisiert geprüft, in run-Schritten jeder Wert für die Shell gequotet. SSH-Härtung läuft zuletzt, damit sich eine Provisionierung per SSH nicht selbst aussperrt. Geprüft mit shellcheck und echt in Containern (Debian 12/13, Ubuntu 22.04/24.04/26.04) inklusive zweitem Lauf. Dabei aufgefallen: frische Images haben keine Paketlisten – der Vorspann macht jetzt apt-get update. Closes #005 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
# 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 (`<hash> <datei>`
|
||||
oder `<hash> *<datei>`) oder im BSD-Format (`SHA256 (<datei>) = <hash>`) 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/<familie>.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: |
|
||||
<h1>{{ var.titel }}</h1>
|
||||
<p>{{ guest.name }} · {{ os.id }} {{ os.version_id }}</p>
|
||||
- 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: <url>` | 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: <befehl>` | freier Shell-Befehl – nicht portabel, nur wenn nichts anderes passt |
|
||||
|
||||
Jeder Schritt kann `if: <variable>` (oder `if: "!<variable>"`) tragen und läuft dann nur, wenn die
|
||||
Variable wahr bzw. falsch ist.
|
||||
|
||||
### Platzhalter
|
||||
|
||||
`{{ var.<name> }}` (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
|
||||
```
|
||||
Reference in New Issue
Block a user