{"id":21236662,"url":"https://github.com/maxg87/butterbackup","last_synced_at":"2025-07-07T22:09:11.048Z","repository":{"id":39899176,"uuid":"351204803","full_name":"MaxG87/ButterBackup","owner":"MaxG87","description":"Vollautomatisierung verschlüsselter inkrementeller Backups","archived":false,"fork":false,"pushed_at":"2025-06-30T05:38:50.000Z","size":1318,"stargazers_count":4,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-30T06:31:50.386Z","etag":null,"topics":["backup-utility","btrfs-snapshots","encryption","rsync-backup"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MaxG87.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-24T19:49:14.000Z","updated_at":"2025-06-29T11:30:24.000Z","dependencies_parsed_at":"2023-11-25T11:21:20.266Z","dependency_job_id":"550089bb-b44e-47fa-8379-6caf2b0f40fa","html_url":"https://github.com/MaxG87/ButterBackup","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/MaxG87/ButterBackup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxG87%2FButterBackup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxG87%2FButterBackup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxG87%2FButterBackup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxG87%2FButterBackup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MaxG87","download_url":"https://codeload.github.com/MaxG87/ButterBackup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxG87%2FButterBackup/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264152667,"owners_count":23564950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup-utility","btrfs-snapshots","encryption","rsync-backup"],"created_at":"2024-11-21T00:13:11.733Z","updated_at":"2025-07-07T22:09:11.042Z","avatar_url":"https://github.com/MaxG87.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat\u0026labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0)\n\n\u003cimg src=\"logo.png\" alt=\"ButterBackup-Logo\" height=\"150px\" align=\"right\"\u003e\n\n# ButterBackup - Backups so geschmeidig wie Butter!\n\n**Inkrementelle Vollbackups dank BtrFS**\n\n## Installation\n\n    uv build\n    pipx install dist/butter-backup-\u003cversion\u003e.whl\n\n## Benutzung\n\n[![asciicast](https://asciinema.org/a/HTFzRxEWw8ltCoP6NDNo6tITP.svg)](https://asciinema.org/a/HTFzRxEWw8ltCoP6NDNo6tITP)\n\n## Gefährdungsszenario\n\nButterBackup wurde entworfen, um gegen eine Reihe spezieller\nGefährdungsszenarien zu schützen. Die konkreten Bedrohungen und die\nentsprechenden Gegenmaßnahmen gibt die folgende Tabelle an. Auf die\nÜbersichtstabelle folgt eine etwas ausführlichere Diskussion der Maßnahmen.\n\n| Bedrohung                                          | Gegenmaßnahme                        |\n| -------------------------------------------------- | ------------------------------------ |\n| Dateien verschlüsselnde Schadsoftware              | physikalisch getrennte Aufbewahrung  |\n| fehlerhafte Sicherungskopien durch Fehlbenutzung   | sehr einfache Benutzung              |\n| Verlust des Datenträgers                           | Vollverschlüsselung des Datenträgers |\n| Zerstörung des Datenträgers durch Spannungsspitzen | physikalisch getrennte Aufbewahrung  |\n| zu seltene Sicherungskopien                        | sehr einfache Benutzung              |\n\nDiese Bedrohungen werden dadurch reduziert, dass eine sehr einfache Benutzung\ndie physikalisch getrennte Aufbewahrung des die Sicherungskopien enthaltenen\nDatenträgers ermöglicht.\n\nEine einfach umzusetzende und verlässliche Maßnahme, um den Datenträger\nvor Zerstörung durch Spannungsspitzen zu schützen, ist, ihn vom Computer\nphysikalisch getrennt aufzubewahren. Gleichzeitig schützt diese Maßnahme\nauch sehr gut vor der Zerstörung der Sicherungskopien durch Schadsoftware, da\nsich die Sicherungskopien außerhalb des Zugriffs der Schadsoftware befinden.\n\nDurch die physikalisch getrennte Aufbewahrung ergibt sich aber eine Bedrohung\ndurch Bequemlichkeit. Ein Prozess, für dessen Durchführung manuelle\nSchritte nötig sind, ist fehleranfällig und läuft Gefahr, im Zweifel\nnicht ausgeführt zu werden. Das Anlegen von Sicherungskopien stellt hier\nkeine Ausnahme dar.\n\nButterBackup begegnet dieser Gefahr dadurch, dass es das Anlegen einer\nSicherungskopie auf zwei manuelle Schritte reduziert. Es genügt, die\nFestplatte mit dem Computer zu verbinden und das Programm zu starten. Alle\nweiteren Schritte, z.B. Entschlüsselung, Kopie der Daten und Unmounten,\nwerden von ButterBackup übernommen.\n\nInsgesamt ermöglicht ButterBackup, Sicherungskopien so sicher wie möglich\naufzubewahren ohne dabei zu verkomplizieren, neue Sicherungskopien anzulegen.\n\n## Ausführung der Tests\n\nButterBackup hat eine umfangreiche Testsuite, die viele relevanten Aspekte des\nProgramms abdeckt. Diese wird ergänzt durch die ähnlich umfangreichen\nTestsuites der Abhängigkeiten `storage-device-managers` und `shell-interface`.\nDiese beiden Abhängigkeiten sind aus ButterBackup hervorgegangen, womit deren\nTestsuite weitere für ButterBackup wichtige Aspekte gründlich abdeckt.\n\nFür die schnelle Ausführung während der Entwicklung bietet es sich an, die\nTestsuite direkt auszuführen. Dies ist wird im Abschnitt \"schnell\" erläutert.\nSpätestens vor einem Release sollten aber auch die distributionsübergreifenden\nTests ausgeführt werden, da diese garantieren, dass ButterBackup auch unter\nArch und allen unterstützten Pythonversionen funktioniert.\n\n\n### Schnell\n\n#### Direkt\n\n    uv run ruff check .\n    uv run mypy .\n    uv run pytest\n\n#### Mittels Makefile\n\n    make check-format check-linters run-undockered-tests\n\n### Plattformübergreifende Tests\n\nEs existiert eine umfassende Testsuite, die auch gewisse\nPlattformabhängigkeiten erkennen kann. Die Docker-Tests existieren überhaupt\nnur, weil es Probleme mit Arch gab.\n\nDie Testsuite kann mittels `make` ausgeführt werden. Es ist auch eine\nParallelisierung mittels `make -j N` möglich, wobei N die Anzahl der Prozesse\nangibt.\n\nDiese Tests werden ergänzt durch eine Testmatrix auf Github. Diese Testmatrix\ndeckt Ubuntu mit allen unterstützten Pythonversionen ab. Dies erlaubt ggf., die\nsehr lang laufende Docker-Testsuite seltener auszuführen.\n\n## Designentscheidungen\n\n### Beibehaltung von nicht mehr vermerkten Zielordnern und -dateien\n\nIn den Konfigurationen müssen Zielordner und Dateien angegeben werden. Nun ist\nes denkbar, dass einige dieser Ziele umbenannt oder entfernt werden. Als\nBeispiel diene hier das Backup des Ordners `Videos-Quelle` nach `Videos-Ziel`.\nEin Nutzer könnte sich nun entscheiden, aus Platzgründen `Videos-Quelle` auf\neine externe Festplatte auszulagern. Die Backup-Anweisung könnte damit entfernt\nwerden.\n\nIn diesem Fall wird ButterBackup `Videos-Ziel` nicht löschen. Der\noffensichtlichste Grund ist, dass dies das Programm verkomplizieren würde. Es\nist ohne weiteres möglich, über `butter-backup open` die Sicherungskopien zu\nöffnen und nicht mehr benötigte Ordner händisch zu löschen.\n\nAußerdem ist es vorstellbar, dass die Quelle zwar gelöscht wurde, aber im\nBackup archiviert werden soll. Dieser Anwendungsfall würde unmöglich gemacht,\nwürden nicht mehr gelistete Ziele aus der Sicherungskopie entfernt.\n\n## Ausstehende Aufgaben\n\n- README schreiben und übersetzen\n- Testsuite umstellen von Docker auf virtuelle Maschinen\n- Alias für Einzelkonfigurationen?\n- butter-backup exec / run\n  - nimmt Befehl als Zeichenkette und führt diesen im BackupRootDir aus\n  - butter-backup exec [\u003cuuid\u003e] \u003ccmd\u003e --\u003e open; cd; cmd; cd -; close\n  - sollte Mapping auf Umgebungsvariablen unterstützen, z.B. RepoPassCmd -\u003e RESTIC_PASSWORD_COMMAND\n- Verbesserte Fehlermeldungen\n  - wenn unmount nicht möglich ist\n  - wenn BackupRepository nicht vorhanden ist\n- SudoPassCmd\n- Konfiguration der gewünschten Kompression ermöglichen (zlib, zstd, none, etc.)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxg87%2Fbutterbackup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxg87%2Fbutterbackup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxg87%2Fbutterbackup/lists"}