Architektur des Daemons
Der Daemon (pithyxd) ist der einzige privilegierte Prozess auf einer Pithyx-Box: eine C#-Binärdatei (.NET 10, ASP.NET Core) mit einer SQLite-Datenbank. Er liefert den Desktop und die API aus, führt jeden Systembefehl über einen einzigen Command Runner aus und verwaltet Speicher, Konten, Dateidienste, Apps und Docker. Der Desktop läuft nie mit erhöhten Rechten.
Überblick
Abschnitt betitelt „Überblick“Der Daemon ist ein modularer Monolith. Jedes Modul ist ein Ordner unter daemon/src/Pithyx.Daemon: Apps, Auth, Backup, Commands, Database, Errors, FileServices, Files, Health, Hosting, Installer, Jobs, Layouts, Localization, Logs, Monitoring, Network, Notifications, Permissions, Realtime, Shares, Storage, SystemSettings, Updates und Users. Die Solution ist daemon/Pithyx.slnx, die Tests liegen in daemon/tests/Pithyx.Daemon.Tests.
- Prozess.
pithyx.servicestartet/usr/lib/pithyx/daemon/pithyxd. Die Unit startet ihn bei einem Fehler nach 2 Sekunden neu, erlaubt 5 Starts in 120 Sekunden und startet bei den Exit-Codes 65 und 78 nicht neu. - Ports. Kestrel lauscht auf 7484. Im echten Modus spricht 7484 TLS (
Hosting/WebTransport): Eine Verbindung, deren erstes Byte kein TLS-Handshake ist, geht an reines HTTP und wird aufhttps://umgeleitet. Auf einer echten Box (Produktions-Build) lauscht er zusätzlich auf 443 (TLS) und 80 (ein Entwicklungs-Build auf den Ports ausPITHYX_DEV_PROXY_PORTS). Dort läuft zuerstReverseProxy/HostProxy: Es leitet die Domains der Proxy-Hosts mit YARPsIHttpForwarderweiter, leitet die der Weiterleitungs-Hosts um und überlässt jeden anderen NamenTransportRedirect, das auf 7484 umleitet, außer/api/install-idauf 80. Jeder TLS-Handshake bekommt sein Zertifikat nach Servernamen ausReverseProxy/ProxyService. Simulation und das Live-System des Installers liefern reines HTTP. Die Zertifikate kommen ausTls/BoxCertificates. - Anfragen. Jeder
/api-Endpunkt verlangt eine Sitzung, sofern er nicht als anonym markiert ist. Die Richtlinien heißenadmin,powerundappToken. - Statische Dateien. Der Daemon liefert den Desktop aus
/usr/lib/pithyx/desktop(oderPITHYX_DESKTOP_DIR) aus, mit einem Fallback auf die Single-Page-App. - Modi. Der echte Modus spricht mit dem System. Der Simulationsmodus (
PITHYX_SIMULATE=1) antwortet aus Fixtures; siehe Am Daemon entwickeln. - Installer-Modus. Mit
PITHYX_INSTALLER=1oder der Kernel-Kommandozeilenoptionpithyx.installergibt es nur die Endpunkte des Installers und der Einrichtung. - Exit-Codes. 1 bedeutet, dass die Datenbank fehlgeschlagen ist, 65, dass die Datenbank von einem neueren Daemon geschrieben wurde, 75 bittet systemd um einen Neustart (nach einer Wiederherstellung der Konfiguration) und 78 bedeutet eine zweite Installation (siehe unten).
Benutzer-IDs pro App kommen aus dem Bereich 40000 bis 49999, Benutzerkonten aus 20000 bis 29999 und Gruppen aus 30000 bis 39999. IDs werden nie wiederverwendet.
Apps laufen als Container: Der Daemon spricht mit Docker über dessen Unix-Socket und startet ein Backend als Job mit docker compose up --wait. Siehe Backends.
Der Daemon hat keinen Watchdog (sd_notify-Heartbeats) und kein Modul für virtuelle Maschinen.
Command Runner
Abschnitt betitelt „Command Runner“Jeder externe Befehl läuft über ICommandRunner. Code ruft zfs, zpool oder smartctl nie direkt auf.
RunAsync(CommandRequest, ct)liefert einCommandResult.StreamLinesAsyncist für langlebige Befehle: Das Timeout der Anfrage gilt dort nicht, und ein Abbruch beendet den Prozess.- Ein
CommandRequesthat den Dateinamen, eine Argumentliste (keine Shell), ein optionales Timeout, Indizes sensibler Argumente und optional die Standardeingabe. Die Standardeingabe wird einmal geschrieben, geschlossen und nie geloggt. - Das Standard-Timeout beträgt 1 Minute. Ein Timeout beendet den ganzen Prozessbaum.
- Der Runner setzt
LC_ALL=C.UTF-8und übergibt die aktuelle Trace-ID alsTRACEPARENT, sodass sich ein Befehl seiner Anfrage zuordnen lässt. - Jeder Aufruf wird mit Befehl, Argumenten, Exit-Code, Dauer und der auf 4096 Zeichen gekürzten Ausgabe geloggt. Sensible Argumente erscheinen als
***. - Im Simulationsmodus antwortet
FixtureCommandRunneraus einem Szenario-Ordner mit den Dateien<id>.json,<id>.stdout, optional<id>.stderrund<id>.stream. Neue Fixtures nimmst du mittools/fixtures/record.sh <scenario> <id> -- <command> [args...]auf; das Skript anonymisiert Seriennummern und WWNs.
Parser für Befehlsausgaben sind reine statische Funktionen mit Fixture-Tests, zum Beispiel LsblkParser, ZfsDatasetParser und ZfsSnapshotParser.
Storage-Backend
Abschnitt betitelt „Storage-Backend“IStorageBackend hat zwei Member: ReadAsync liefert die Pool-Liste und WatchAsync liefert einen Wert pro Änderung. ZfsBackend ist die einzige Implementierung; es gibt kein Btrfs- oder mdadm-Backend.
Darum herum liegen die Inventare für Festplatten und Pools, die Planer (StoragePlanner, DatasetPlanner, PoolImportScanner) und die Befehlspläne (ZfsPlans, SnapshotPlans, ZfsScrubPlans, ImportPlans), die dem Benutzer gezeigt werden, bevor sie laufen. DiskGuard lehnt zerstörerische Aktionen auf Festplatten mit Daten ab, solange der Benutzer nicht mit der Seriennummer der Festplatte bestätigt.
Der Speicherzustand erreicht die Clients über die Topics storage/disks, storage/pools und storage/alerts.
Datenbank und Migrationen
Abschnitt betitelt „Datenbank und Migrationen“Der Daemon nutzt SQLite über Dapper mit explizitem SQL, ohne ORM und ohne Repository-Schicht. Die Datenbank ist /var/lib/pithyx/pithyx.db oder der Pfad in PITHYX_DB. Sie läuft im WAL-Modus. Logs liegen in einer eigenen logs.db.
- Migrationen sind eingebettete Dateien
daemon/src/Pithyx.Daemon/Database/Migrations/NNNN_name.sql(heute 28). Jede läuft in einer eigenen Transaktion; ein Fehler beendet mit Code 1. Die Tabelleschema_versionhält fest, was gelaufen ist. - Bevor eine nicht leere Datenbank migriert wird, schreibt der Daemon mit
VACUUM INTOeine Kopie namenspithyx.db.pre-<NNNN>-<time>.bak, wobeiNNNNdie erste ausstehende Version ist. - Enthält die Datenbank Versionen, die der Daemon nicht kennt, loggt er eine kritische Meldung und beendet sich mit 65. Starte einen neueren Daemon oder richte
PITHYX_DBauf eine andere Datenbank. - Daten werden als UTC-Text nach ISO 8601 gespeichert.
- Die Konfigurationssicherung umfasst die Datenbank, die Samba-Passwortdatenbank, TLS-Zertifikate und SSH-Host-Schlüssel. Eine neue Tabelle muss zu einem Sicherungsteil gehören oder als Laufzeitzustand markiert werden.
Pfade auf der Box
Abschnitt betitelt „Pfade auf der Box“| Pfad | Inhalt |
|---|---|
/var/lib/pithyx/pithyx.db |
Die Datenbank (überschreibbar mit PITHYX_DB) |
/var/lib/pithyx/catalogs/ |
Ein Klon pro aktiviertem Katalog |
/var/lib/pithyx/tls/ |
Die Zertifizierungsstelle der Box, ihr eigenes und ein hochgeladenes Zertifikat (PEM, nur für root lesbar) |
/var/log/pithyx/ |
daemon.json und logs.db (überschreibbar mit PITHYX_LOG_DIR) |
/var/cache/pithyx/ |
Caches (überschreibbar mit PITHYX_CACHE_DIR) |
/usr/lib/pithyx/desktop/ |
Der gebaute Desktop |
/etc/pithyx/environment |
dev kennzeichnet eine Entwicklungsmaschine; alles andere bedeutet prod |
/<pool>/.pithyx/ |
App-Daten und Docker-Daten auf dem App-Pool, nie auf der Systemfestplatte |
Eine Maschine hat genau eine Pithyx-Installation. Ein Daemon, der aus einem Checkout ohne PITHYX_DB auf einer Maschine gestartet wird, die bereits /etc/pithyx/environment hat, verweigert den Start und beendet sich mit 78.