a37631c501
8 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| a37631c501 |
Fehler #1: Repository unter /tmp macht den Dienst startunfaehig
Gemeldet wurde ein Abbruch der Einrichtung mit "Der Dienst meldet sich nicht als
betriebsbereit". Der Diagnosebericht enthielt die Ursache woertlich:
syncova-api.service: Failed to set up mount namespacing:
/tmp/syncova-repository: No such file or directory
status=226/NAMESPACE
Die Diensteinheit setzt PrivateTmp=yes. Der Dienst bekommt damit ein eigenes
/tmp, und der in ReadWritePaths genannte Ablageort existiert in seiner Sicht
nicht — systemd bricht ab, bevor das Programm ueberhaupt laeuft.
Der technische Fehler ist der kleinere. Der groessere ist, dass setup.sh einen
Ablageort unter /tmp ueberhaupt angenommen hat: systemd-tmpfiles raeumt dort
regelmaessig auf, und auf einem tmpfs ist nach einem Neustart nichts mehr da.
Ein Backupsystem, das jede Nacht Erfolg meldet und keine Daten hat, ist
schlimmer als gar keines.
Deshalb:
- Fluechtige Ablageorte werden abgelehnt: /tmp, /var/tmp, /dev/shm, /run und
jedes tmpfs oder ramfs. Geprueft wird VOR der Datenbankeinrichtung — ein
unbeaufsichtigter Lauf scheitert damit in Sekunden statt nach Minuten und
einem Rueckbau.
- SYNCOVA_SETUP_ALLOW_VOLATILE_REPOSITORY=ja laesst es ausdruecklich zu; dann
wird PrivateTmp abgeschaltet, sonst startet der Dienst nie. Real geprueft:
Einheit traegt PrivateTmp=no, Dienst laeuft.
- Kommt der Dienst nicht hoch, liefert setup.sh die letzten Journalzeilen gleich
mit und erklaert 226/NAMESPACE. Der Verweis auf journalctl allein war
wertlos: Beim Rueckbau ist der Dienst weg, und der Meldende brauchte einen
zweiten Anlauf, um ueberhaupt zu erfahren, was los war.
Regressionstest vorhanden und als fangend geprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|||
| 0b5ce96c51 |
CHANGELOG: Abschnitt fuer rc2
Was seit rc1 dazukam und was daran eine Korrektur ist, nicht nur eine Ergaenzung — PostgreSQL 15 statt 17 und die nicht existierende Umgebungsvariable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 4762fa29c3 |
Fehlervorlage und ein Diagnoseskript, das sie fuellt
Eine Vorlage allein bringt wenig — sie stellt Fragen, die der Meldende meist nicht beantworten kann. Deshalb zwei Teile: diagnose.sh sammelt in einem Zug, was zur Analyse gebraucht wird: Fassungen aller acht Programme, Betriebssystem, Container ja/nein, Dateisystem des Repositorys, PostgreSQL-Fassung, Schemastand, Dienstzustand, Gesundheitsbericht (der auch bei 503 den vollstaendigen Bericht traegt), Bestand, die letzten nicht erfolgreichen Laeufe mit Fehlercode UND Fehlerklasse, die gemessene Durchsetzungsstufe und die letzten Fehlerzeilen. Es liest nur. Geheimnisse kommen nicht hinein, und der Weg dahin ist umgekehrt: Es gibt eine Liste der Werte, die gezeigt werden duerfen. Eine Sperrliste vergaesse den naechsten neuen Wert. Zusaetzlich werden die tatsaechlichen Geheimnisse gelesen und aus JEDER Ausgabe entfernt — auch aus Protokollzeilen, in die sie auf einem unvorhergesehenen Weg geraten sind. Real geprueft: weder Datenbankpasswort noch Schluessel noch Administratorpasswort stehen im Bericht. Die Vorlage beginnt mit sieben Faellen, die wie ein Fehler aussehen und gewolltes Verhalten sind — "advisory" statt "filesystem", ein Teilfehler, "geloescht aber nichts frei", 503 mit vollstaendigem Bericht. Das ist keine Abwehr, sondern spart beiden Seiten einen halben Tag. Pflichtfelder sind Beobachtung, Erwartung, Schritte, Bereich, Datenrisiko, Haeufigkeit und der Diagnosebericht; Fehlercode und request_id stehen eigens da, weil sie die beiden wertvollsten Angaben sind. Beim Erproben zwei Funde: - Die Installationsanleitung verlangte PostgreSQL 17. setup.sh installiert auf Debian 12 aber 15 — und alles lief, bis hin zu einem echten Sicherungslauf. Die Anforderung lautet jetzt 15 (geprueft gegen 17 in CI und Entwicklung, gegen 15 auf Debian 12), und setup.sh lehnt aeltere Fassungen ab statt sie stillschweigend zu nehmen. - Ein Repository auf der Platte, das nicht in der Control Plane eingetragen ist, faellt niemandem auf: Die Sicherung laeuft nie, weil der Server das Ziel nicht kennt. Der Bericht benennt diesen Fall jetzt ausdruecklich. Gegen das echte v1.0.0-rc1-Paket gefahren: Installation, erzeugte Stoerung (ALL_SOURCES_FAILED / source), Bericht zeigt Code, Klasse, "overlayfs" und "nie gemessen". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 0c5a106a83 |
setup.sh, update.sh und uninstall.sh
Drei Betriebsskripte fuer Linux, im Auslieferungspaket neben den Programmen. setup.sh richtet eine Anlage vollstaendig ein: PostgreSQL auf Wunsch mit (apt/dnf/yum/zypper/pacman), Dienstkonto, Verschluesselungsschluessel, Schema, erster Administrator, gehaertetes Repository, gehaertete systemd-Einheit. Jeder Schritt vermerkt, was er angelegt hat; bricht der Lauf ab, wird genau das zurueckgebaut und nichts sonst. Eine bestehende Installation wird nicht ueberschrieben — dafuer gibt es update.sh, und der Unterschied ist, dass ein Update vorher sichert. update.sh haelt die Reihenfolge ein, um die es geht: sichern, anhalten, tauschen, migrieren, starten, pruefen. Kommt der Dienst danach nicht hoch, holt es die vorige Fassung zurueck. Ohne pg_dump wird gar nicht erst begonnen — ohne Sicherung gibt es nach einer misslungenen Migration keinen Weg zurueck. Repository und Verschluesselungsschluessel bleiben unberuehrt. uninstall.sh entfernt standardmaessig NUR Dienst und Programme. Datenbank, Repository und Konfiguration bleiben liegen; jede dieser Loeschungen verlangt ein woertlich getipptes Bestaetigungswort an einem Terminal. Ein Deinstallationsskript, das nebenbei die Backups mitnimmt, vernichtet genau das, wofuer jemand jahrelang Speicher bezahlt hat. Gegen Debian 12 im Container gefahren — Installation, Anmeldung, Repository eingetragen, Loeschschutz gemessen (advisory auf overlayfs, richtig), echter Sicherungslauf, Update mit unveraendertem Bestand, beide Abbauarten. Drei Fehler dabei gefunden und behoben, alle derselben Art: - "tr </dev/urandom | head -c 32" und "psql | grep -q": Der frueh geschlossene Pipe schickt dem Schreiber SIGPIPE, und mit "set -o pipefail" bricht das Skript mitten in der Einrichtung ab, ohne erkennbaren Grund. - update.sh las die laufende Fassung mit "grep -o" aus der Antwort von /health/ready. Die enthaelt gar kein Versionsfeld; grep endet mit 1, und das Skript nahm ein GELUNGENES Update wieder zurueck — wegen einer Zeile, die nur der Ausgabe dient. Dazu: SYNCOVA_ADMIN_PASSWORD stand in der Doku und existiert nicht — das Passwort kommt ueber die Standardeingabe. Und "syncova-repo break-lock" fehlte zwar nicht mehr, aber der Test auf die Uebereinstimmung der drei Skripte ist neu: Drei Skripte, die sich ueber den Installationsort uneinig sind, ergeben eine Anlage, die sich nicht mehr entfernen laesst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| e1fd31e9c8 |
CI: Schema vor den Tests anlegen
Der vorige Commit setzte SYNCOVA_TEST_DATABASE_URL, damit die Datenbanktests in der CI nicht mehr still uebersprungen werden. Das haette die CI rot gemacht: Die Tests laufen dort **vor** dem Migrationsschritt, die Datenbank ist zu dem Zeitpunkt leer, und neun Testdateien scheitern an einem fehlenden Schema. Aufgefallen ist es beim Nachbau der CI-Umgebung in einem Container — nicht in der CI selbst, weil die Actions-API dieser Gitea-Fassung nicht erreichbar ist. Jetzt: - "Schema vor den Tests anlegen" laeuft als eigener Schritt vor den Tests. - Der Migrationszyklus (down/up) bleibt danach. Zwischen down und up fehlt eine Migration; ein Test in genau diesem Moment scheiterte an einem Schemastand, den es im Betrieb nie gibt. Die Verbindungszeichenkette des CI-Containers traegt secretscan:erlaubt — in derselben Zeile, nicht darueber, sonst greift der Vermerk nicht. Nachgewiesen gegen eine frische PostgreSQL 17 in der exakten Reihenfolge der CI: gofmt, go vet, Schema, Tests mit Race-Detector, Migrationszyklus, cross-build — alle sechs Schritte bestanden. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| c4f0b3e665 |
Anleitung zum Veroeffentlichen und Testen des Systems
Zwei Teile: Release bauen und in Gitea veroeffentlichen, und das System in vier Stufen durchtesten — Rauchtest, Rundlauf, Agent, Proxmox. Jede Stufe endet mit dem, was danach belegt ist, und der Rundlauf hat eine Gegenprobe: nicht leeres Ziel, rm -rf gegen ein gehaertetes Repository und ein gekippter Block muessen scheitern beziehungsweise erkannt werden. Ein Test, der nur den Erfolgsfall zeigt, belegt wenig. Der Vorschlag fuer den ersten Tag ist v1.0.0-rc1, nicht v1.0.0: Solange Windows-Dienst, systemd-Einheit und der Proxmox-Boot ungeprueft sind, waere 1.0.0 eine Zusage, die diese drei Punkte nicht deckt. Jeder genannte Endpunkt wurde gegen den eingefrorenen API-Vertrag gehalten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 9c48cb1c1c |
CI: Loeschschutz messen statt annehmen, Datenbanktests wirklich fahren
Der Angriffstest auf ein gehaertetes Repository scheiterte in der CI: "rm -rf auf ein geschuetztes Repository gelang vollstaendig". Der Befund ist richtig — und der Fehler lag im Test, nicht im Produktivcode. immutableFlagSupported() sagt nur, ob das Betriebssystem das Unveraenderlich-Kennzeichen *kennt*; unter Linux gibt es immer "ja" zurueck. Ob es auch *durchgesetzt* wird, haengt am Dateisystem und an CAP_LINUX_IMMUTABLE. In einem Container auf overlayfs ist beides nicht gegeben: Das Setzen scheitert still, und der Angriff gelingt. Die Anlage selbst macht es richtig — sie ist beim Setzen nachsichtig (ein Backup ohne technischen Loeschschutz ist besser als gar keines) und sagt die Wahrheit ueber die gemessene Stufe. Der Test tut das jetzt auch: Er misst zuerst und prueft nur dort, wo es etwas zu pruefen gibt. Nachgewiesen in beide Richtungen — auf macOS laeuft der Angriff wirklich, im Container wird mit Begruendung uebersprungen. Zwei Luecken in der CI dabei gefunden: - SYNCOVA_TEST_DATABASE_URL fehlte. Neun Testdateien uebersprangen ihre Datenbanktests still, darunter der Upgrade- und der Rollback-Test. Ein uebersprungener Test sieht in der Zusammenfassung aus wie ein bestandener. - make cross-build lief nicht mit. Genau daran ist in Phase 5 monatelang unbemerkt geblieben, dass der Agent sich fuer Windows gar nicht uebersetzen liess. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 610719c316 |
Syncova Backups V1
Enterprise-Backup-, Recovery-, Verification-, Security- und Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme. Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes geht in keine Bewertung als "gut" ein. Umfang (Phasen 0-23): - Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll, Katalogaufbau allein aus den Manifesten — ohne Datenbank - Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck - Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell) - Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive - Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit - Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center, Ransomware-Heuristik (meldet, handelt nie) - Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing - Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository - Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64 Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs. Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md und docs/release-candidate.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |