Encoding/CT-101: PVE-Host-NFS konvergiert, Berechtigungsmodell entschieden, Verifikation dokumentiert.

- pve_nfs_export: NFSv4-only via /etc/nfs.conf ([nfsd] vers2/vers3=n; Debian-13-Unit
  startet nfsd ohne EnvironmentFile, RPCNFSDARGS wirkungslos), Restart-Handler,
  selbstheilende nfsd-Versionspruefung; verify-production um Export-Root- und
  Versions-Assertions erweitert
- Autorisierte Konvergenz auf dem PVE-Host: Export-Root 100000:970 2775,
  /proc/fs/nfsd/versions -3 +4 +4.1 +4.2, verify ok=17 changed=0, Idempotenz changed=0
- Berechtigungsmodell (Betreiberentscheidung 30.10.2026): Mode 2777 auf input/- und
  output/-Baum der Pipeline (LXC-idmap-Diskrepanz guest-root vs. UID 982/983:970)
- GNENC-000/001/002, GNAI-017/018/019 auf NFS-auf-PVE-Host-Stand gebracht;
  CT-101-Verifikation ok=47 changed=0 dokumentiert; AGENTS.md-Seccomp-Hinweis korrigiert

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-10-30 19:54:42 +01:00
parent 6a1eff7392
commit 88b063a234
11 changed files with 259 additions and 72 deletions
@@ -1,8 +1,8 @@
# Video-Encoding – Dokumentationsindex und Projektstand
**Dokumenten-ID:** GNENC-000-DOC
**Stand:** 2026-10-19
**Status:** Planungsabschluss; Pipeline geplant, Implementierung noch nicht begonnen
**Stand:** 2026-10-30
**Status:** Planungsabschluss; externe Abhängigkeiten (CT-101, PVE-Host-NFS) umgesetzt; Implementierung auf ghostnet-ki noch nicht begonnen
## Dokumente
@@ -23,9 +23,16 @@ beschrieben.
(ProtonVPN), jDownloader2 (Download), Encoding-Worker (HandBrakeCLI +
ffmpeg); Handover ausschließlich über das Filesystem, In-Progress-Schutz
über Work-Ordner und atomares `mv`.
- Speicherort: CT-101 (Samba/NAS, 10.0.0.9) — NFS-Export
`/media/datenhdd3/Encoding`, gemountet auf `/var/lib/ghostnet-encoding`
(ghostnet-ki hat nur eine 2-TB-NVMe; die Medienbibliothek liegt auf CT-101).
- Speicherort: PVE-Host-Medienverbund `/media/datenhdd3` (per LXC-Mount auch
in CT-101 sichtbar) — NFS-Export `10.0.0.2:/media/datenhdd3/Encoding`,
gemountet auf `/var/lib/ghostnet-encoding` (ghostnet-ki hat nur eine
2-TB-NVMe; die Medienbibliothek liegt auf dem PVE-Host/CT-101).
- CT-101 per Ansible adoptiert und PVE-Host-NFS umgesetzt (GNAI-019);
Verifikation 30.10.2026: CT-101 `verify-production` `ok=47 changed=0`;
PVE-Host nach autorisierter Konvergenz: Export-Root `100000:970 2775`,
NFSv4-only wirksam (`-3`), `verify-production` `ok=17 changed=0`,
Idempotenz `changed=0`. Berechtigungsmodell entschieden: Mode 2777 auf den
SMB-berührten Verzeichnissen (GNENC-002 Abschnitt 4).
- Verzeichnislayout: `input/<Profil>/*.dlc`, `jd/`, `queue/<Profil>/<Release>/`,
`work/`, `output/<Profil>/<Release>/` + `output/_failed/`, `state/jobs/` +
`state/system.json`.
@@ -64,10 +71,12 @@ beschrieben.
## Noch offen
1. Feinjustierung der Ressourcenlimits nach einem repräsentativen Encoding-Test
1. NFSv4.2-Mount-Abnahme von `ghostnet-ki` gegen `10.0.0.2` (inkl.
Schreib-/Lesetest als UID 982/983 und mv-Simulation als `ghost` über SMB)
— mit der Encoding-Implementierung.
2. Feinjustierung der Ressourcenlimits nach einem repräsentativen Encoding-Test
unter gleichzeitiger Inferenzlast.
2. Rootless-TUN-Verifizierung für den VPN-Sidecar auf dem Host.
3. Implementierung: CT-101 (NFS-Export, Shares `[Encode]`/`[Encode-In]`,
Gruppe `gn-media`/GID-Abgleich — GNAI-017), Konten `gn-download`/
`gn-dashboard`, NFS-Mount, Image-Bauten, Quadlet-Units (inkl. VPN-Sidecar),
Skripte, Monitoring-Bereich (Collector, Dashboard).
3. Rootless-TUN-Verifizierung für den VPN-Sidecar auf dem Host.
4. Implementierung auf ghostnet-ki: Konten `gn-download`/`gn-dashboard`,
NFS-Mount, Image-Bauten, Quadlet-Units (inkl. VPN-Sidecar), Skripte,
Monitoring-Bereich (Collector, Dashboard).
@@ -2,8 +2,8 @@
**Dokumenten-ID:** GNENC-001-PLAN
**Titel:** CPU-basiertes Video-Encoding auf dem KI-Server
**Stand:** 2026-10-19
**Status:** Finaler Plan nach Planungsabschluss am 19.10.2026; die operative Pipeline ist in GNENC-002 spezifiziert, das host-weite Monitoring in GNMON-001
**Stand:** 2026-10-30
**Status:** Finaler Plan nach Planungsabschluss am 19.10.2026; externe Abhängigkeiten (CT-101, PVE-Host-NFS) umgesetzt (GNAI-019); die operative Pipeline ist in GNENC-002 spezifiziert, das host-weite Monitoring in GNMON-001
## 1. Zweck und Abgrenzung
@@ -40,10 +40,10 @@ beschrieben.
| Download-Stufe | jDownloader2-Container (`jlesage/jdownloader-2`, gepinnter Digest) liest `.dlc` aus `input/<Profil>/`; Event-Scripter verschiebt den Release-Ordner atomar in die Queue | Betreiberentscheidung 19.10.2026 |
| VPN | der gesamte jDownloader2-Verkehr läuft über einen ProtonVPN-WireGuard-Tunnel: gluetun-Sidecar (`qmcgaw/gluetun`, gepinnt) unter `gn-download`, JD2 teilt dessen Netzwerk-Namespace, Kill Switch aktiv (kein Traffic ohne Tunnel); WireGuard-Credentials server-lokal in `/etc/ghostnet-download/vpn.env`, nicht in git | Betreiberentscheidung 19.10.2026 |
| Anwendung | Worker-Image als Eigenbau auf Basis des gepinnten HandBrake-Images `linuxserver/handbrake:1.11.2-ls48` (`sha256:fda92bd1…48a3c7`) mit python3 und ffmpeg; die Digests von Worker- und VPN-Image werden nach dem Bau gepinnt | Betreiberentscheidung 19.10.2026 |
| Speicherort | Pipeline-Daten liegen auf CT-101 (Samba/NAS, 10.0.0.9): dort liegen die Medienbibliothek und der Plattenverbund; ghostnet-ki selbst hat nur eine 2-TB-NVMe (OS + LLM) | Betreiberentscheidung 19.10.2026 |
| Ein-/Ausgabe | NFS-Export `/media/datenhdd3/Encoding` von CT-101 (10.0.0.9), gemountet auf `/var/lib/ghostnet-encoding`; Verzeichnislayout `input/`, `jd/`, `queue/`, `work/`, `output/`, `state/` | Betreiberentscheidung 19.10.2026; Server, IP und Export-Pfad festgelegt |
| Speicherort | Pipeline-Daten liegen auf dem PVE-Host-Medienverbund (`/media/datenhdd3`; per LXC-Mount auch in CT-101 sichtbar): dort liegt die Medienbibliothek; ghostnet-ki selbst hat nur eine 2-TB-NVMe (OS + LLM) | Betreiberentscheidung 19.10.2026; NFS seit 30.10.2026 auf dem PVE-Host (GNAI-019 Entscheidung 2) |
| Ein-/Ausgabe | NFS-Export `10.0.0.2:/media/datenhdd3/Encoding` (PVE-Host, Rolle `pve_nfs_export`, NFSv4-only, nur für 10.0.0.90, `root_squash`), gemountet auf `/var/lib/ghostnet-encoding`; Verzeichnislayout `input/`, `jd/`, `queue/`, `work/`, `output/`, `state/` | Betreiberentscheidung 19.10.2026; Umsetzung GNAI-019 (Revision 30.10.2026); Mount-Abnahme durch das Encoding-Ansible ausstehend |
| Abholung | fertige Outputs per SMB über CT-101: Share `[Encode]` (`output/`, RW für `ghost`, lesend für `daidalaw`/`debugofen`) — Entnahme per `mv` in die Bibliotheks-Shares räumt `output/` auf; optionaler Clean-Job löscht Dateien nach 30 Tagen aus `output/`; kein smbd auf `ghostnet-ki` | Betreiberentscheidung 19.10.2026 |
| Samba-Integration (CT-101) | CT-101 wird ins Infrastructure-Repository aufgenommen (GNAI-017): NFS-Export nur für 10.0.0.90, Shares `[Encode]`/`[Encode-In]`, Gruppe `gn-media` (GID 970) auf CT-101 mit `ghost` als Mitglied (UID/GID-Abgleich); `.dlc`-Drop über `[Encode-In]` | Betreiberentscheidung 19.10.2026; GNAI-017 |
| Samba-Integration (CT-101) | CT-101 ist per Ansible adoptiert (GNAI-019; verifiziert 30.10.2026, `ok=47 changed=0`): Shares `[Encode]`/`[Encode-In]`/`[Encoding]`, Gruppe `gn-media` (GID 970) mit `ghost` als Mitglied; `.dlc`-Drop über `[Encode-In]`. NFS liegt nicht auf CT-101 (PVE-Host); die guest-seitige GID 970 gleicht die Host-GID 970 wegen des LXC-idmap nicht ab — Berechtigungsmodell: Mode 2777 auf den SMB-berührten Verzeichnissen (Betreiberentscheidung 30.10.2026, GNENC-002 Abschnitt 4) | Betreiberentscheidung 19.10.2026; GNAI-017/GNAI-019 |
| Profile | drei versionierte HandBrake-Presets (SVT-AV1 10-bit, MKV, Audio-Passthrough) unter `llm-server/encoding/profiles/`; Auswahl über gleichnamige Ordner unter `input/` bzw. `queue/` | Betreiberentscheidung 19.10.2026; Presets versioniert |
| Warteschlange | dateibasiert: `.dlc`-Drop in `input/<Profilname>/`, jDownloader2 befüllt `queue/<Profilname>/<Release>/`, der Worker arbeitet die Queue mit genau einem gleichzeitigen Encode ab | Betreiberentscheidung 19.10.2026 |
| Filter | Nicht-Video-Dateien und Dateien < 100 MB werden ignoriert; alle übrigen Videodateien eines Releases werden encodet (keine Hauptdatei-Auswahl) | Betreiberentscheidung 19.10.2026 |
@@ -65,7 +65,7 @@ flowchart LR
ENC[gn-encoding\nrootless Podman]
DL[gn-download\nrootless Podman]
DASH[gn-dashboard\nrootless Podman]
NAS[CT-101 Samba/NFS\n10.0.0.9]
NAS[PVE-Host NFS 10.0.0.2\nCT-101 SMB 10.0.0.9]
GPU[beide GPUs]
CPU[CPU / I-O Budget]
TIMER[nächtliche Fensterlogik\nim Worker]
@@ -233,18 +233,28 @@ anschließend in den rootless Store von `gn-encoding` gezogen; der Pull
bestätigte den Manifest-Digest.
Am 19.10.2026 wurde die Planung abgeschlossen (Abschnitte 2 und 7). Die
Implementierungsphase baut als Nächstes auf: der NFS-Export und die Shares
`[Encode]`/`[Encode-In]` auf CT-101 (GNAI-017), die Konten `gn-download` und
`gn-dashboard` samt Gruppe `gn-media` (GID 970, auch auf CT-101), der NFS-Mount
auf ghostnet-ki, die Image-Bauten mit Digest-Pinning (Worker, VPN-Sidecar,
Dashboard), die Quadlet-Units für jDownloader2, VPN-Sidecar, Worker und
Dashboard, der host-seitige Metrics-Collector sowie die Skripte aus `scripts/`.
Die Rolle `video_encoding` stellt bis dahin sicher, dass weder Quadlet-Dateien
noch Container für `gn-encoding` existieren.
externen Abhängigkeiten sind umgesetzt: CT-101 ist per Ansible adoptiert
(GNAI-019, verifiziert 30.10.2026), der NFS-Export läuft auf dem PVE-Host
(Rolle `pve_nfs_export`); der PVE-Host ist konvergiert (Export-Root
`100000:970 2775`, NFSv4-only wirksam, `verify-production` `ok=17 changed=0`,
Idempotenz `changed=0`; autorisierter Lauf 30.10.2026). Das
Berechtigungsmodell für die SMB-Schreibpfade ist entschieden (Mode 2777,
GNENC-002 Abschnitt 4); offener Restpunkt ist die NFSv4.2-Mount-Abnahme von
ghostnet-ki. Die Implementierungsphase auf
ghostnet-ki baut als Nächstes auf: die Konten `gn-download` und `gn-dashboard`
samt Gruppe `gn-media` (GID 970), den NFS-Mount von `10.0.0.2`, die
Image-Bauten mit Digest-Pinning (Worker, VPN-Sidecar, Dashboard), die
Quadlet-Units für jDownloader2, VPN-Sidecar, Worker und Dashboard, den
host-seitigen Metrics-Collector sowie die Skripte aus `scripts/`. Die Rolle
`video_encoding` stellt bis dahin sicher, dass weder Quadlet-Dateien noch
Container für `gn-encoding` existieren.
## 7. Offene Entscheidungen
1. Feinjustierung der Ressourcenlimits nach einem repräsentativen Encoding-Test
unter gleichzeitiger Inferenzlast (Abschnitt 4).
Diese Werte werden nicht vorab in Playbooks angenommen.
Diese Werte werden nicht vorab in Playbooks angenommen. Die am 30.10.2026
offenen Punkte Berechtigungsmodell (Mode 2777, GNENC-002 Abschnitt 4) und
PVE-Host-Konvergenz (GNAI-017 Abschnitt 6.9) sind entschieden beziehungsweise
erledigt.
@@ -2,11 +2,11 @@
**Dokumenten-ID:** GNENC-002-PLAN
**Titel:** Encoding-Pipeline: Komponenten, Konten, Verzeichnislayout und Datenfluss
**Stand:** 2026-10-19
**Status:** Finaler Plan nach Betreiberentscheidungen vom 19.10.2026
**Stand:** 2026-10-30
**Status:** Finaler Plan nach Betreiberentscheidungen vom 19.10.2026; externe Abhängigkeiten umgesetzt (GNAI-019)
**Vorgänger:** [GNENC-001-PLAN_Architecture.md](GNENC-001-PLAN_Architecture.md)
**Monitoring:** [GNMON-001-PLAN_Architecture.md](../monitoring/GNMON-001-PLAN_Architecture.md)
**Samba/NFS (CT-101):** [GNAI-017-PLAN_Samba-NFS-Export.md](../../proxmox-server/lxc/ct-101-samba/GNAI-017-PLAN_Samba-NFS-Export.md)
**Samba/NFS:** [GNAI-017](../../proxmox-server/lxc/ct-101-samba/GNAI-017-PLAN_Samba-NFS-Export.md), [GNAI-019](../../proxmox-server/lxc/ct-101-samba/GNAI-019-DEC_Ansible-Migration.md) — SMB auf CT-101, Kernel-NFS auf dem PVE-Host
## 1. Architekturprinzip
@@ -38,28 +38,35 @@ Dashboard und Metrics-Collector werden im Monitoring-Bereich betrieben
| `gn-dashboard` | 984 | 624288–689823 | `/var/lib/ghostnet-dashboard` | `/etc/ghostnet-dashboard` | `gn-media` (nur lesend) |
Gruppe `gn-media`: gemeinsame Gruppe der drei Konten für die Übergabe-
Verzeichnisse und den lesenden Zugriff auf `state/`; GID 970, auf `ghostnet-ki`
und CT-101 identisch angelegt (GNAI-017). Alle Konten sind gesperrt
(Passwort `!`, Shell `/usr/sbin/nologin`, Linger aktiv).
Verzeichnisse und den lesenden Zugriff auf `state/`; GID 970. Alle Konten sind
gesperrt (Passwort `!`, Shell `/usr/sbin/nologin`, Linger aktiv).
**Anmerkung 30.10.2026 (LXC-idmap):** Die guest-seitige Gruppe `gn-media`
(GID 970) in CT-101 erscheint auf dem Host als GID 100970 und gleicht die
reale Host-GID 970 der Pipeline nicht ab — die Gruppen-Alignment wirkt nur
innerhalb von ghostnet-ki. Die SMB-Schreibpfade aus CT-101 laufen über
guest-root (Host-UID 100000, da `admin users` Dateioperationen als root
ausführt); siehe Abschnitt 11.
## 4. Verzeichnislayout
```text
/var/lib/ghostnet-encoding/ (NFS-Mount: 10.0.0.9:/media/datenhdd3/Encoding, CT-101)
├── input/<Profil>/ gn-media 2770 Drop-Ziel, nur .dlc
├── jd/ gn-download JD2-Arbeitsverzeichnis
/var/lib/ghostnet-encoding/ (NFS-Mount: 10.0.0.2:/media/datenhdd3/Encoding, PVE-Host)
├── input/ gn-media 2777 SMB-Drop ([Encode-In])
│ └── <Profil>/ gn-media 2777 nur .dlc
├── jd/ gn-media 2770 JD2-Arbeitsverzeichnis (gn-download)
│ ├── <Release>/ Download + Entpacken
│ ├── dlc_done/ erfolgreich abgearbeitete .dlc
│ └── failed/ .dlc mit Download-Fehler
├── queue/<Profil>/<Release>/ gn-media 2770 Roh-Queue, atomar befüllt
├── work/<Release>/ gn-encoding 0750 Encode-Ziele in Arbeit
├── output/
│ ├── <Profil>/<Release>/ gn-encoding Erfolge bis Abholung
│ └── _failed/<Release>/ gn-encoding Quarantäne
└── state/
├── jobs/<job_id>.json gn-encoding Status pro Videodatei
├── tmp/ gn-encoding atomare Schreib-Zwischenlage
└── system.json Collector Systemmetriken (Monitoring)
├── output/ gn-media 2777 Abholung ([Encode])
│ ├── <Profil>/<Release>/ gn-media 2777 Erfolge bis Abholung
│ └── _failed/<Release>/ gn-media 2777 Quarantäne
└── state/ gn-media 2750 Status (Dashboard liest)
├── jobs/<job_id>.json gn-encoding 0750 Status pro Videodatei
├── tmp/ gn-encoding 0750 atomare Schreib-Zwischenlage
└── system.json Collector 0644 Systemmetriken (Monitoring)
```
`state/` ist `gn-encoding:gn-media` mit Mode `2750`, damit `gn-dashboard` lesen
@@ -71,8 +78,12 @@ Handover-Regeln:
- Übergabe immer per atomarem `mv` innerhalb des Mounts; Work-Dateien liegen
nie in Übergabe-Ordnern.
- `input/`, `jd/`, `queue/` mit Mode `2770` (setgid), damit neue Dateien die
Gruppe `gn-media` erben.
- `jd/`, `queue/` mit Mode `2770` (setgid); `state/` mit `2750` (setgid).
- `input/` (inkl. Profil-Ordner) und der gesamte `output/`-Baum (inkl.
Release- und `_failed/`-Verzeichnisse, vom Worker angelegt) mit Mode
`2777` (setgid) — Welt-Schreibrecht für den SMB-Schreibpfad aus CT-101
(Betreiberentscheidung 30.10.2026, siehe unten). Neue Dateien erben die
Gruppe `gn-media`.
- jDownloader2 läuft mit `UMASK=022`, damit der Worker die Dateien lesen kann.
- Der Worker löscht Quelldateien und geleerte Release-Ordner aus `queue/`;
Löschrechte folgen aus dem Schreibrecht der Gruppe am Verzeichnis (kein
@@ -80,6 +91,18 @@ Handover-Regeln:
- `work/` wird pro Lauf geleert; `state/tmp/` dient nur atomaren
Schreibzugriffen.
**Berechtigungsmodell (Betreiberentscheidung 30.10.2026):** Die SMB-Zugriffe
aus CT-101 laufen über guest-root (Host-UID 100000; `admin users` führt
Dateioperationen als root aus). Da die Pipeline-Verzeichnisse via NFS den
realen UIDs 982/983:970 gehören und diese im LXC-idmap nicht abgebildet sind
(im Gast: `nobody:nogroup`), tragen `input/` und der `output/`-Baum Mode
`2777`; `jd/`, `queue/`, `work/` und `state/` bleiben eng (2770/0750).
**Layout-Anlage:** Wegen `root_squash` auf dem Export kann Ansible als root
keine chowned-Verzeichnisse anlegen; die Struktur wird als `gn-encoding`
angelegt (runuser; Muster der Rolle `video_encoding`) oder vom Worker beim
Start erzeugt und geprüft.
**Abholung:** Die fertigen Outputs werden über CT-101 per SMB abgeholt: Share
`[Encode]` (Pfad `/media/datenhdd3/Encoding/output`, RW für `ghost`, lesend für
`daidalaw`/`debugofen`). Die Entnahme per `mv` in die Bibliotheks-Shares
@@ -231,9 +254,10 @@ die Container gemountet (Updates ohne Image-Rebuild, versioniert über git).
## 11. Offene Punkte
1. Feinjustierung der Ressourcenlimits nach Lasttest unter Inferenzlast
1. NFSv4.2-Mount-Abnahme von `ghostnet-ki` gegen `10.0.0.2` — inkl.
Schreib-/Lesetest als UID 982/983 über den Mount und mv-Simulation als
`ghost` über SMB; mit der Encoding-Implementierung.
2. Feinjustierung der Ressourcenlimits nach Lasttest unter Inferenzlast
(GNENC-001 Abschnitt 4).
2. Rootless-TUN-Verifizierung für den VPN-Sidecar auf dem Host (Fallback:
3. Rootless-TUN-Verifizierung für den VPN-Sidecar auf dem Host (Fallback:
host-seitiger WireGuard mit Policy-Routing).
3. UID/GID-Abgleich: Gruppe `gn-media` (GID 970) muss auf CT-101 identisch
existieren; `ghost` Mitglied für die Abholung per `mv` (GNAI-017).
@@ -2,7 +2,7 @@
**Dokumenten-ID:** GNAI-017-PLAN
**Titel:** CT 101 Samba: Aufnahme ins Repository, NFS-Export und Shares für die Encoding-Pipeline
**Stand:** 2026-10-21
**Stand:** 2026-10-30
**Status:** Plan; bestehende Shares produktiv und bislang manuell verwaltet; Ansible-Projekt gebaut (GNAI-019), Adoption des produktiven LXC ausstehend
**Referenzen:** [GNENC-001](../../../llm-server/encoding/GNENC-001-PLAN_Architecture.md), [GNENC-002](../../../llm-server/encoding/GNENC-002-PLAN_Pipeline.md), [GNMON-001](../../../llm-server/monitoring/GNMON-001-PLAN_Architecture.md), [GNAI-011](../../GNAI-011-SEC_LXC-SSH-Architecture.md), [GNAI-018](GNAI-018-REQ_Encoding-Pipeline-Integration.md), [GNAI-019](GNAI-019-DEC_Ansible-Migration.md)
@@ -60,8 +60,9 @@ guests = yes`, `obey pam restrictions = yes`.
### 4.1 NFS-Export
**Korrektur 30.10.2026:** Der Export läuft als **Kernel-NFS
(`nfs-kernel-server`) auf dem PVE-Host** — umgesetzt via
`Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`)` (idempotent, versioniert im Repo).
(`nfs-kernel-server`) auf dem PVE-Host** — umgesetzt über das
Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`; idempotent,
versioniert im Repo).
Zuvor war Ganesha-in-CT-101 geplant; das ist in einem unprivileged LXC nicht
möglich (`open_by_handle_at` braucht CAP_DAC_READ_SEARCH in der init-userns
und liefert dort immer EPERM — verifiziert 30.10.2026 auf Kernel
@@ -91,6 +92,21 @@ Reproduzierbarkeit bleibt durch das versionierte Script gewährleistet.
Dafür SMB-Freigaben `[Encode]`, `[Encode-In]` und `[Encoding]` (Root) für die
Pipeline und die Kontrolle von anderen Geräten.
**Verifikation 30.10.2026 (read-only, von der Admin-Workstation):** CT 101:
`verify-production` `ok=47 changed=0 failed=0`; keine Ganesha-Reste (kein
Quadlet-Verzeichnis, keine Ganesha-Units), passdb unverändert (`ghost`,
`daidalaw`, `debugofen`). PVE-Host: `exportfs -v` zeigt den Export live
(`10.0.0.90/32`, `rw`, `root_squash`), nft-Tabelle `ghostnet_host_nfs` mit
2049 tcp/udp nur für `10.0.0.90`. Das `verify-production` des Host-Projekts
**schlug fehl (`failed=1`)**: Der Export-Root ist live `root:root 2777` statt
deklariert `100000:970 2775`; zudem läuft der nfsd noch mit NFSv3
(`/proc/fs/nfsd/versions`: `+3 +4 +4.1 +4.2`) — die `RPCNFSDARGS`-Änderung
(NFSv4-only) wurde nach dem Edit nicht wirksam (fehlender Dienst-Restart; die
Rolle hat dafür keinen Handler). pve-firewall ist disabled/running — die
Netzrestriktion von 2049 beruht praktisch nur auf `/etc/exports`. **Korrektur
erledigt (30.10.2026, autorisiert):** Rollen-Fix und Konvergenz — Details in
Abschnitt 6.9; Berechtigungsmodell entschieden (Abschnitt 6.10).
### 4.2 Gruppen- und UID-Abgleich
- Gruppe `gn-media` mit **GID 970** auf CT-101 anlegen (identisch zu
@@ -130,6 +146,18 @@ write list = ghost
force group = gn-media
create mask = 0664
directory mask = 0775
[Encoding]
comment = Encoding-Pipeline: Root (Verwaltung/Kontrolle per SMB)
path = /media/datenhdd3/Encoding
public = no
writeable = yes
valid users = ghost
admin users = ghost
write list = ghost
force group = gn-media
create mask = 0664
directory mask = 0775
```
- `[Encode]`: RW für `ghost` — die Entnahme per `mv` in die Bibliotheks-Shares
@@ -270,3 +298,34 @@ GNENC-002 Abschnitt 4): `input/`, `jd/`, `queue/`, `work/`, `output/`,
funktionsneutral (mit `valid users` ist Gastzugriff ohnehin verweigert).
Ebenfalls angeglichen: `[printers]` trägt im Template nun `browseable = no`
wie live (Sichtbarkeit im anonymen Listing).
9. **PVE-Host-Konvergenz — erledigt (30.10.2026, autorisierter Lauf):**
Rollen-Fix: Restart-Handler plus selbstheilende Versionsprüfung; NFSv4-only
wird auf Debian 13 über `/etc/nfs.conf` (`[nfsd] vers2=n`, `vers3=n`)
erzwungen, weil die systemd-Unit nfsd über `nfsdctl autostart` ohne
EnvironmentFile startet und `RPCNFSDARGS` in
`/etc/default/nfs-kernel-server` ignoriert (die wirkungslose Zeile wurde
entfernt). Konvergenz: Export-Root auf `100000:970 2775` gesetzt, nfsd neu
gestartet; danach `/proc/fs/nfsd/versions`: `-3 +4 +4.1 +4.2` (NFSv4-only
wirksam); `verify-production` (mit neuen Assertions zu Export-Root und
nfsd-Versionen) `ok=17 changed=0 failed=0`; Idempotenz-Lauf `changed=0`.
Präzisierung zu GNAI-019 Entscheidung 3: Die Stock-Unit hält
`nfs-mountd.service` als Required-Dienst und wanted `rpcbind.socket` —
mountd läuft also weiterhin, wird von NFSv4-Clients aber nicht genutzt.
Offen bleibt der reale NFSv4.2-Mount-Test von `ghostnet-ki` (mit der
Encoding-Implementierung).
10. **Berechtigungsmodell Pipeline-vs-SMB (30.10.2026)** — Die SMB-Schreibpfade
(`[Encode-In]` → `input/<Profil>/`, `[Encode]` → `output/...`) laufen über
guest-root (Host-UID 100000, da `admin users` Dateioperationen als root
ausführt); die Pipeline-Verzeichnisse gehören via NFS aber den realen
UIDs 982/983:970, die im idmap des unprivileged LXC nicht abgebildet sind
(im Gast: `nobody:nogroup`). Verzeichnisse mit Mode 2770/2750 sind für den
SMB-Pfad daher nicht schreibbar; die guest-seitige Gruppe `gn-media`
(GID 970 → Host-GID 100970) gleicht die Host-GID 970 nicht ab. Offene
Entscheidung: world-write (2777) auf den ghost-berührten Verzeichnissen
(aktuelles Ist-Verhalten des Export-Roots) oder Host-seitige ACLs;
Festlegung in GNENC-002 Abschnitt 11 vor der Encoding-Implementierung.
**Entschieden (Betreiber, 30.10.2026):** world-write — Mode `2777` auf dem
`input/`-Baum und dem gesamten `output/`-Baum (inkl. Release- und
`_failed/`-Verzeichnisse, vom Worker angelegt); `jd/`, `queue/`, `work/`
und `state/` bleiben eng (2770/2750/0750). Festgehalten in GNENC-002
Abschnitt 4.
@@ -3,7 +3,7 @@
**Dokumenten-ID:** GNAI-018-REQ
**Titel:** Requirements der LLM-Server-Encoding-Pipeline an CT 101 — Spezifikation für den Ansible-Rebuild
**Stand:** 2026-10-19
**Status:** Übergabedokument; verbindliche Anforderungsliste für den ausführenden Agenten
**Status:** Erfüllt am 30.10.2026 — Umsetzung und Revisionen in [GNAI-019](GNAI-019-DEC_Ansible-Migration.md) dokumentiert (R1 durch Kernel-NFS auf dem PVE-Host ersetzt; Abnahme-Nachweise in GNAI-017 Abschnitt 4.1 und 6.9/6.10)
**Adressat:** Ansible-Rebuild CT 101 (ausführendes Projekt: `proxmox/lxc/ct-101-samba/ansible/`)
**Quellen:** [GNAI-017](GNAI-017-PLAN_Samba-NFS-Export.md), [GNENC-001](../../../llm-server/encoding/GNENC-001-PLAN_Architecture.md), [GNENC-002](../../../llm-server/encoding/GNENC-002-PLAN_Pipeline.md), [GNMON-001](../../../llm-server/monitoring/GNMON-001-PLAN_Architecture.md)
@@ -1,7 +1,7 @@
# CT 101 – Samba-Dateiserver: Entwurfsentscheidungen der Ansible-Migration
**Dokumenten-ID:** GNAI-019-DEC
**Titel:** CT 101 Samba: Design-Entscheidungen für die Ansible-Migration (natives Samba, NFS-Ganesha als Quadlet, Fresh-State-Rebuild)
**Titel:** CT 101 Samba: Design-Entscheidungen für die Ansible-Migration (natives Samba, Kernel-NFS auf dem PVE-Host, Fresh-State-Rebuild)
**Stand:** 2026-10-21
**Status:** Entwurfsentscheidungen verbindlich; im Projekt `proxmox/lxc/ct-101-samba/` umgesetzt und lokal verifiziert (Syntax-Checks, Check-Mode-Smoke); die Adoption des produktiven LXC steht aus und erfordert Betreiber-Autorisierung
**Referenzen:** [GNAI-017](GNAI-017-PLAN_Samba-NFS-Export.md), [GNAI-018](GNAI-018-REQ_Encoding-Pipeline-Integration.md), [GNAI-011](../../GNAI-011-SEC_LXC-SSH-Architecture.md), [GNAI-016](../ct-102-keycloak/GNAI-016-PLAN_Keycloak-Ansible-Rebuild.md), [GNENC-001](../../../llm-server/encoding/GNENC-001-PLAN_Architecture.md), [GNENC-002](../../../llm-server/encoding/GNENC-002-PLAN_Pipeline.md), [GNMON-001](../../../llm-server/monitoring/GNMON-001-PLAN_Architecture.md); Projektkonventionen: `proxmox/lxc/ct-100-dns/` und `proxmox/lxc/ct-102-keycloak/`
@@ -72,8 +72,8 @@ und anonymer `smbclient -L`-Abfrage.
(GNAI-018 R1) läuft als **Kernel-NFS (`nfs-kernel-server`) auf dem
Proxmox-Host**, exportiert `/media/datenhdd3/Encoding` exklusiv für
`ghostnet-ki` (`10.0.0.90/32`), NFSv4-only — umgesetzt durch das idempotente,
versionierte Script `Host-Projekt `proxmox/pve-host/ansible/` (Rolle `pve_nfs_export`)` (siehe
`scripts/README.md`). CT 101 kennt NFS nicht mehr: keine `samba_nfs`-Rolle,
versionierte Host-Projekt `proxmox/pve-host/ansible/` (Rolle
`pve_nfs_export`; siehe dessen README). CT 101 kennt NFS nicht mehr: keine `samba_nfs`-Rolle,
kein Podman, keine 2049-Firewall-Regel, kein `lxc.seccomp.profile:`-Eintrag.
Dafür stellt CT 101 die SMB-Freigaben `[Encode]`, `[Encode-In]` und
`[Encoding]` (Root) für die Pipeline bzw. die Kontrolle von anderen Geräten.
@@ -217,8 +217,10 @@ hand-editierten Zustand auf dem Ziel:
- `nftables.conf` plus systemd-Drop-in (Ghostnet-eigene Tabelle
`inet ghostnet_filter`, Netavark-Tabellen bleiben unberührt; `nft --check`
vor Installation).
- `ganesha.conf` (NFSv4-only, siehe Entscheidung 3).
- Quadlet `ghostnet-samba-nfs.container` (siehe Entscheidung 2).
(Korrektur 30.10.2026: Die Ganesha-Ära-Einträge `ganesha.conf` und Quadlet
`ghostnet-samba-nfs.container` sind mit der NFS-Verlagerung auf den PVE-Host
entfallen — siehe Entscheidung 2.)
`verify-production.yml` rendert die Templates per `lookup` erneut und
vergleicht sie mit den Live-Dateien (Drift-Erkennung).
@@ -310,9 +312,10 @@ dieselbe Person auf Medien-/SMB-Ebene ist nicht erforderlich.
- **GNAI-017 Abschnitt 2** (System-Baseline) wird um OS-Version (Debian 13 nach
Upgrade) und Hostname (Erfassung per `preflight.yml`) ergänzt; Abschnitt 6
(offene Punkte) wird um die Entscheidungen dieses Dokuments aktualisiert.
- **GNAI-018 R1** wird revidiert: NFS-Ganesha-Quadlet statt
`nfs-kernel-server`; Export-Root `root:gn-media 2775` statt `root:root 0755`
(begründete Abweichung, siehe Entscheidung 2).
- **GNAI-018 R1** wird revidiert (Revision 30.10.2026): Kernel-NFS auf dem
PVE-Host statt `nfs-kernel-server` in CT 101; Export-Root
`100000:970 2775` statt `root:root 0755` (begründete Abweichung, siehe
Entscheidung 2).
- **GNAI-018 Abschnitt 4** (Abnahme): Punkt 2 (`showmount`) wird als realer
NFSv4.2-Mount-Test von `ghostnet-ki` interpretiert (Entscheidung 3); Punkt 8
nennt `ghostnet-samba-nfs.service` statt `nfs-kernel-server`.
@@ -370,3 +373,19 @@ dieselbe Person auf Medien-/SMB-Ebene ist nicht erforderlich.
GNMON-001; eigener Collector später).
8. Erweiterung der SMB-Allowlist auf das Admin-VPN (`10.8.0.0/24`) —
Betreiberentscheidung, aktuell nicht geöffnet.
9. **PVE-Host-Konvergenz-Nachweis — erledigt (30.10.2026, autorisierter
Lauf):** Rollen-Fix (Restart-Handler, selbstheilende Versionsprüfung;
NFSv4-only via `/etc/nfs.conf` `[nfsd] vers2=n`/`vers3=n`, da die
Debian-13-Unit `nfsdctl autostart` ohne EnvironmentFile startet und
`RPCNFSDARGS` ignoriert) und Konvergenz: Export-Root
`100000:970 2775`, `/proc/fs/nfsd/versions` danach
`-3 +4 +4.1 +4.2`, `verify-production` `ok=17 changed=0 failed=0`
(jetzt mit Assertions zu Export-Root und nfsd-Versionen), Idempotenz
`changed=0`. Siehe GNAI-017 Abschnitt 6.9. Präzisierung zu Entscheidung 3:
Die Stock-Unit hält `nfs-mountd.service` als Required-Dienst — mountd
läuft weiterhin, wird von NFSv4-Clients aber nicht genutzt.
10. **Berechtigungsmodell für SMB-Schreibpfade — entschieden
(Betreiber, 30.10.2026):** world-write (Mode 2777) auf dem `input/`-Baum
und dem gesamten `output/`-Baum der Pipeline; `jd/`, `queue/`, `work/`
und `state/` bleiben eng. Begründung und Umsetzung: GNAI-017
Abschnitt 6.10, GNENC-002 Abschnitt 4.