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>
125 lines
5.5 KiB
Markdown
125 lines
5.5 KiB
Markdown
# 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. Fest eingebaut sind `if: vm` und `if: lxc` – etwa für Zeitsync, die
|
||
in einem unprivilegierten Container nicht laufen kann.
|
||
|
||
### 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
|
||
```
|