- Sicherung von Datenbank und Schlüsseln auf eine Anbindung (scrypt+Fernet),
Seite „Sicherung“, /healthz/backup, netmover backup/restore
- metrics in /healthz und /healthz/rule/<id> für Kuma-JSON-Abfragen
- .gitea/workflows/ci.yml; jede Migration auf befüllter DB getestet
- HTTP im internen Netz als bewusste Entscheidung dokumentiert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zusätzliche Kopie ins Archiv (Anbindung oder lokaler Pfad, Ablage wie Quelle
oder nach Datum). Buchführung verhindert doppelte Archivkopien bei Neuversuch;
im Archiv wird nie überschrieben. Migration 0004 mit Tests auf befüllten
Datenbanken (inkl. Downgrade).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zwei Netzlisten statt Modusauswahl; fremde Netze werden abgewiesen, wenn
„mit Passwort“ ausgefüllt ist; /healthz bleibt erreichbar; Schutz vor
Aussperren; reset-password hebt Sperren auf.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seite „Zugangsdaten“ (vorher „Schlüssel“) mit Passwörtern und SSH-Schlüsseln;
Anbindungen wählen gespeicherte Passwörter aus, ein neues Passwort gilt
sofort für alle. /keys leitet auf /credentials um.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Quell-Abstraktion (LocalSource, SftpSource): Scan, frische Zustände,
Lesen, Löschen und Quarantäne über eine Schnittstelle. Verbindungsabbrüche
brechen den Lauf als gestörte Anbindung ab. Bei SFTP-Quellen mindestens
2 s Stabilitätsfenster (Zeiten nur sekundengenau).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wartezustand mit einem Protokolleintrag statt eines Fehlers alle 30 s,
automatisches Fortsetzen; Meldung einmal pro Anbindung mit betroffenen
Regeln (auch beim Aushängen von außen). Migration 0003 mit Tests auf
befüllten Datenbanken.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Formulare zeigen nur passende Felder; Jinja-maskierte Attribute behoben;
Web-Fixtures nach conftest.py.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Migration 0002 scheiterte auf einer Datenbank mit verknüpften Daten
(FOREIGN KEY constraint failed beim Neuaufbau von credentials) und
hinterließ einen halben Zustand, weil SQLite-DDL nicht transaktional lief.
Eigene Migrationsverbindung: foreign_keys=OFF, BEGIN IMMEDIATE,
transactional_ddl, foreign_key_check vor dem Commit. Tests mit echten,
verknüpften Daten und mit Abbruch mitten in der Migration.
update.sh: beim Zurückstufen keinen Changelog-Auszug.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installation als Git-Klon unter /opt/netmover/src; install.sh installiert
git und das Update-Skript. Skripte mit shellcheck geprüft.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gespeicherte SSH-Schlüssel (erzeugen oder importieren, auch mit
Passphrase), von mehreren Anbindungen nutzbar; der Benutzername gehört
zur Anbindung. Migration 0002: credentials.managed, mounts.username.
Gespeicherte Schlüssel werden beim Löschen einer Anbindung nie mitgelöscht.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bootet die VM schneller als das NAS (Stromausfall), käme die Freigabe sonst
nie zurück. Ein Scheduler-Job prüft fällige Neuversuche jede Minute, auch
für Anbindungen ohne Regel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ein NAS-Neustart dauert länger als die drei Wiederherstellungsversuche.
Von NetMover selbst ausgehängte Mounts mit auto_mount werden höchstens
einmal pro Minute erneut eingehängt, mit Entwarnung per Webhook. Von außen
ausgehängte bleiben unangetastet. Hinweistexte werden nicht mehr
mitgeschwärzt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CIFS lieferte per stat() sekundenlang eine veraltete Größe einer noch
wachsenden Datei; erst open() erzwingt frische Attribute. Gesperrte
Dateien gelten als in Benutzung.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ProtectSystem/PrivateTmp/ProtectControlGroups erzeugen einen Namespace als
slave; Mounts blieben dort gefangen (auf der Test-VM nachgewiesen) und
verschwanden bei jedem Neustart. MountFlags=shared hilft nicht. Nur noch
Härtungen ohne Namespace.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Unit mit StateDirectory/RuntimeDirectory, ProtectSystem=full und
MountFlags=shared; compose mit SYS_ADMIN, DAC_READ_SEARCH,
apparmor:unconfined und rshared-Bind für /mnt/netmover (Propagation zum
Host im Container getestet).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Watcher, die nur auf IN_MOVED_TO/IN_CLOSE_WRITE lauschen, sehen damit neue
Dateien wie bei os.replace. Dateisysteme ohne renameat2 (NFS, CIFS) nutzen
weiter link() + unlink() bzw. prüfen + rename.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FastAPI + Jinja2 + lokal eingebundenes htmx, strikte CSP, Ersteinrichtung
mit Einrichtungscode aus dem Log, Argon2, Sperre nach Fehlversuchen,
Status-, Anbindungs-, Regel-, Protokoll- und Einstellungsseite,
/healthz.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Formularprüfung und Speichern unabhängig vom Web-Framework; Passwörter
leer = unverändert, SFTP-Schlüsselpaar wird erzeugt. Export/Import als
JSON ohne Zugangsdaten und Webhook-URL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
APScheduler-Jobs je Regel mit Startversatz und Jitter, Protokoll in
runs/run_items mit Regelzählern, Aufräumen nach Aufbewahrungsfrist,
Health-Auswertung für /healthz und Verdrahtung des Dienststarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Einstellungen in der Tabelle settings; generischer Webhook mit Vorlage
(JSON-sicher), Modus bei jedem Fehler oder nach N Fehlern in Folge,
optionale Entwarnung, Versand im Hintergrund.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RuleRunner prüft Anbindungen vor jedem Lauf, baut das Ziel auf und führt
die Engine im Worker mit Inaktivitäts-Watchdog aus. Der Lock wird erst
beim echten Ende des Workers freigegeben.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lokale/Kernel-Mount- und SFTP-Ziele schreiben in .part, fsyncen, prüfen
Größe und Quelle und benennen ohne Überschreiben um; erst dann wird die
Quelle gelöscht. Stabilitätsfenster, Platzprüfung, Metadaten,
Berechtigungen, Kopiermodus mit Gedächtnis, Quarantäne.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kandidatensuche mit Filtern und Ausschlüssen (versteckt, unfertig,
Synology-Ordner, Symlinks), Kollisionsnamen, Ledger für copied_files und
file_failures, Inaktivitäts-Watchdog mit CancelToken.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MountBackend-Interface mit LinuxMountBackend (Argumentliste, kurzlebige
Credentials-Datei) und FakeMountBackend; MountManager für Einhängen,
Aushängen, Start-Wiederherstellung, Drei-Schritt-Test mit Root-Squash-
Erkennung, Lebenszeichen und umount -l/Neu-Einhängen; SFTP-Anbindung mit
festgehaltenem Hostschlüssel. Tests inkl. echtem SFTP-Server im Prozess.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Strikte Validierung von Server, Freigabe, Pfaden und Mount-Optionen
(Allowlist, gesperrte Zugangsdaten-Schlüssel), Fernet-Schlüssel mit 0600,
Ed25519-Schlüsselerzeugung, Schwärzung von Geheimnissen und Dateizugriffe
mit Zeitlimit in Daemon-Threads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Neuer Anbindungstyp sftp (share = entfernter Basispfad, port, host_key),
credentials.kind (password|ssh_key) und public_key. Migration 0001 vor
dem ersten Release angepasst.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schritt 1: src-Layout mit FastAPI-Stack, SQLAlchemy-2.x-Modell inkl.
Buchführung für Kopiermodus und Quarantäne, Alembic-Migration 0001,
strukturierte Logs, CLI (migrate/version), Changelog und Devlog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>