29e516559aa453acdefbfee19a836edf01db3417
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
06e924daf5 |
fix: die Sicherung liess den Papierkorb aus -- ein Versprechen, das sie nicht halten konnte
GEFUNDEN BEIM NACHSEHEN, nicht beim Suchen: das Sicherungsskript packte
tar czf ... -C /data files -C /data/.sicherung media.db
also die Bilder und die Datenbank. Die EINTRAEGE des Papierkorbs stehen in
media.db und waren damit laengst gesichert -- die DATEIEN lagen unter
/data/papierkorb und waren es nicht.
Nach einem Zurueckspielen haette der Papierkorb also Zeilen gezeigt, deren
"zurueckholen" ins Leere greift: die Oberflaeche verspricht etwas, das die
Platte nicht hergibt. Genau die Sorte stiller Abweichung, wegen der dieses
Projekt Sicherungen ueberhaupt gegenprueft.
Er ist jetzt im Archiv, und er kostet fast nichts: was darin liegt, ist
hoechstens 30 Tage alt, danach raeumt der Dienst selbst auf. Die Abfrage
`if [ -d /data/papierkorb ]` davor ist noetig -- hat noch nie jemand etwas
geloescht, gibt es den Ordner gar nicht, und tar braeche mit "Cannot stat" ab.
Ein `mkdir` als Ausweg ginge nicht: das Volume haengt nur lesend.
Gemessen an einem echten Lauf, nicht angenommen:
d4rk_media-2026-08-11-2307.tar.gz -- 311,9 MB
in der Sicherung: 4452 Medieneintraege, 4452 Dateien, 2 Token, 2 Benutzer
hochgeladen (201), zurueckgeholt und verglichen: identisch
Inhalt: 4459 files/ 1 media.db 1 papierkorb/
UND DER PAPIERKORB SAGT ES JETZT SELBST. Die Liste prueft je Zeile, ob die
Datei wirklich noch daliegt (hoechstens 500 stat-Aufrufe), und zeigt fehlende
durchgestrichen samt Erklaerung. Die Sicherung nimmt ihn zwar inzwischen mit --
aber ein Papierkorb, der etwas verspricht, muss es halten koennen, und wenn
nicht, soll er es SAGEN statt es beim Druecken herauszufinden.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5d35381952 |
feat: Dateien aus der Nextcloud uebernehmen
tools/uebernehmen.ps1 holt einen Nextcloud-Ordner in den Dienst. Unterordner
bleiben erhalten, -Probe zeigt erst nur, was passieren wuerde.
UEBER DAS DASHBOARD UND NICHT UEBER DIE TOKEN-API. Nextcloud-Dateien heissen
"Brand Logo (final).PNG" -- checkPath lehnt das mit Recht ab. Der
Dashboard-Weg biegt den Namen bereits vorhersagbar zurecht. Dieselbe Regel an
einer Stelle ist besser als dieselbe Regel an zweien, von denen eine irgendwann
abweicht.
WIEDERHOLBAR ueber overwrite=false: was schon da ist, meldet der Dienst je
Datei als "Pfad ist belegt". Nachgemessen mit 57 Marken -- zweiter Lauf: 0
uebernommen, 57 waren schon da.
DREI FEHLER BEIM BAUEN, alle durch Messen gefunden:
1. Ein kaputter Formular-Rumpf ergab einen NACKTEN 500, aufgefangen nur von der
Auffanglinie. Jetzt 400 mit Grund.
2. PowerShells `Invoke-RestMethod -Form` scheitert am Dienst. Ich hatte die
Ursache zuerst falsch: nicht (nur) die Grenzmarkierung in
Anfuehrungszeichen, die RFC 2046 erlaubt und die wir jetzt vertragen --
sondern der Rumpf selbst. Mitgeschnitten:
Content-Disposition: form-data; name=file; filename=a.png
RFC 7578 verlangt name="file" MIT Anfuehrungszeichen, .NET laesst sie weg,
und Nodes Parser besteht darauf. Das steht im RUMPF; dafuer braeuchte es
einen eigenen Multipart-Parser, und der waere unverhaeltnismaessig. Die
Werkzeuge nehmen deshalb curl.exe -F.
3. PowerShell-Falle: curl.exe gibt zeilenweise ein ARRAY zurueck, und
-match/-notmatch darauf FILTERT, statt zu pruefen. Ein nicht-leeres Ergebnis
gilt als wahr -- damit meldete das Skript "Kein Verzeichnis gefunden" bei
einer tadellosen Antwort mit HTTP 207. Jetzt wird vorher zusammengefuegt,
auch in sichern.ps1, wo dieselbe Falle nur deshalb nicht zuschlug, weil die
Ausgabe eine Zeile hat.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4e613dd40d |
feat: ein Einstellungen-Tab -- und die Sicherung meldet sich zurueck
Die Zugangsdaten der Sicherung standen in einer Textdatei auf der Platte. Jetzt
stehen sie im Panel, zusammen mit der Discord-Einrichtung, die vom Konto
dorthin umgezogen ist.
DER EIGENTLICHE GEWINN IST NICHT DIE BEQUEMLICHKEIT. Eine Textdatei sagt
niemandem, ob die Sicherung heute Nacht gelaufen ist -- und eine Sicherung, die
still aufhoert zu laufen, ist der eigentliche Schaden, nicht die eine Nacht, in
der sie fehlt. Das Skript schreibt sein Ergebnis deshalb nach jedem Lauf in die
Datenbank, und die Karte zeigt es als Erstes: wann, ob erfolgreich, wie viele
Dateien, wie gross, und ob es in der Nextcloud gelandet ist oder nur lokal.
Nachgemessen: {"dateien":228,"groesse":12063419,"hoch":false,"ok":true}.
DAS PASSWORT GEHT NICHT UEBER DIE API. Das Skript laeuft auf dem Wirt, nicht im
Dienst -- es liest die Werte per `docker exec` DIREKT aus media.db. Ueber HTTP
geht das Passwort nur beim Eintragen im Browser, und das ueber TLS. Zurueck gibt
die API nur "hatPasswort: true", wie beim Discord-Geheimnis.
nextcloud.txt neben den Sicherungen gilt weiter und hat VORRANG: wer sie
angelegt hat, soll nicht suchen muessen, warum sie ploetzlich ignoriert wird.
Zwei Fussangeln beim Melden, beide beim Bauen aufgefallen:
- Der JSON-Text geht ueber die STANDARDEINGABE in den Container und nicht als
Argument -- Anfuehrungszeichen ueberleben den Weg durch zwei Shells nicht.
- Auch dieses Hier-Dokument braucht das -replace "`r": dieselbe CRLF-Falle wie
bei der Pruefung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
74cf56ce81 |
feat: eine Startseite, und die Sicherung geht in die Nextcloud
STARTSEITE. Wer das Dashboard oeffnet, landete bisher in der Galerie -- mit 228 Kacheln und ohne Antwort auf die erste Frage, die man beim Oeffnen hat: laeuft alles? Jetzt zuerst eine Uebersicht: Zahlen, was heute dazukam, ein Bilderstreifen der letzten Uploads, die letzten acht Schritte aus dem Verlauf, die groessten Ordner, die Zugaenge -- und die ADRESSVORLAGE zum Kopieren, weil das die haeufigste Frage ueberhaupt ist. Die Galerie zieht auf /galerie um. Alles in EINER Antwort (/api/dash/uebersicht, gemessen 14 ms). Vier Einzelabfragen waeren vier Runden ueber den Proxy und koennten auseinander- laufen: Dateizahl aus der einen und letzte Ereignisse aus der naechsten Antwort sind zwei verschiedene Zeitpunkte. Der Router zog dabei nach src/router.ts um. Der Grund ist mehr als Geschmack: die Startseite braucht eine Navigationsfunktion, die anderen Seiten nicht -- und sobald EINE Seite eine Eigenschaft mehr hat, passt die gemeinsame Liste in App.tsx nicht mehr. Genau daran ist der erste Versuch gescheitert (TypeScript hat es gefangen). Als Modulfunktion hat wieder jede Seite dieselbe Signatur. SICHERUNG IN DIE NEXTCLOUD. Bisher lagen die Archive auf derselben Platte wie die Daten -- gegen einen Plattenausfall half das gar nicht. Jetzt gehen sie per WebDAV hinauf, mit curl statt rclone: Nextcloud spricht WebDAV, curl spricht WebDAV, und curl ist ohnehin da. Auch dort wird NACHGEZAEHLT: die Kopie wird zurueckgeholt und die Pruefsumme verglichen. Ein PUT, der 201 sagt, hat nichts bewiesen -- abgeschnittene Uebertragungen sehen genauso aus. Und ausgeduennt wird ebenfalls, sonst waechst die Nextcloud still voll. Die Zugangsdaten liegen NEBEN den Sicherungen (C:\backup\d4rk_media\ nextcloud.txt), nicht im Repo: sie gehoeren zur Maschine, nicht zum Code. Fehlt die Datei, sagt das Skript das einmal und sichert lokal weiter -- eine Sicherung, die wegen eines fehlenden Passworts GAR NICHT stattfindet, waere der schlechtere Tausch. Dabei einmal reingefallen: die Pruefung brach mit "sh: set: Illegal option -" ab, nachdem ein Werkzeug die Datei mit CRLF gespeichert hatte -- die Shell im Container liest dann "set -e\r". Sieht aus wie ein Tippfehler und ist keiner. Das Skript entfernt die Wagenruecklaeufe jetzt selbst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
aa2575bdf4 |
feat: Sicherung, Anmeldebremse, Vorschaubilder -- und Schritt 5
SICHERUNG (tools/sichern.ps1, taeglich 04:30 als geplante Aufgabe). Die Datenbank wird nicht kopiert, sondern ueber SQLites eigene Sicherungsschnittstelle herausgeholt (server/src/backup.ts): im WAL-Modus liegt das Zuletzte noch nicht in media.db, und selbst alle drei Dateien zu kopieren ist nicht sicher, wenn waehrenddessen geschrieben wird. Die Bilder kommen aus einem NUR LESEND eingehaengten Volume dazu. Und sie prueft sich selbst: auspacken, Datenbank oeffnen, Medien/Token/ Benutzer zaehlen, mit dem laufenden Dienst vergleichen, sonst Fehler. Einmal wirklich zurueckgespielt -- leeres Volume, zweiter Dienst, Anmeldung mit dem echten Passwort, Bild abgerufen, Byte fuer Byte identisch. Eine Sicherung, die nie zurueckgespielt wurde, ist eine Hoffnung. ANMELDEBREMSE. Das Formular steht oeffentlich, und scrypt macht einen Versuch teuer -- aber teuer ist nicht selten. Fuenf freie Versuche je Adresse, dann Sperre ab 30 s mit Verdopplung bis 15 min, 429 samt Retry-After und einem Text, der sagt wie lange. Erfolg setzt zurueck. Nur im Speicher: wer sich aussperrt, startet den Container neu. Durchgemessen bis zur Erholung. VORSCHAUBILDER. sharp erzeugt beim Upload eine 320er WebP-Fassung unter /data/thumbs, ausgeliefert unter /t/<pfad>. Gemessen: 131502 -> 13078 Bytes, Faktor 10; eine Galerieseite faellt von 7,5 MB auf 766 KB. KEINE Spalte in der Datenbank -- ob es eine Vorschau gibt, sagt das Dateisystem, und die Galerie faellt bei 404 aufs Vollbild zurueck. Eine zweite Wahrheit, die auseinander- laufen kann, gibt es damit gar nicht erst. Ein Knopf zieht Fehlendes nach und nennt Zahlen statt "fertig". SCHRITT 5. Die Fivemanage-Dateien liegen in legacy/ mit Erklaerung; unsere docker-compose.media.yml heisst jetzt docker-compose.yml. Drei Volumes und drei Abbilder geloescht, rund 670 MB -- nachgezaehlt war vorher, dass kein Bild darin lag. Nebenbefund: `npm i sharp` scheitert auf diesem Rechner nicht an sharp, sondern an better-sqlite3 -- der Host laeuft auf Node 24 (ABI 137), node-gyp uebernimmt und findet keine Bauwerkzeuge. Genau die Falle aus dem Dockerfile. Eingetragen wurde mit --package-lock-only, gebaut wird im Abbild auf Node 22. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |