mirror of
https://github.com/kevinveenbirkenbach/docker-volume-backup.git
synced 2026-10-26 07:52:09 +00:00
Compare commits
4
Commits
v7.1.0
..
1a50eea187
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a50eea187 | ||
|
|
be7a3987b0 | ||
|
|
cff906f073 | ||
|
|
b54b402ebf |
No files matched your search
@@ -1,19 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [7.1.0] - 2026-10-17
|
||||
|
||||
Fixed:
|
||||
|
||||
- Backup: rsync -a stored no xattrs, ACLs or hardlinks; now -aHAX
|
||||
- Restore: restore_volume_files had the same gap; now -aHAX too
|
||||
- An OpenCloud volume lost its storage metadata through a DR drill
|
||||
|
||||
Upgrade notes:
|
||||
|
||||
- First backup re-copies every attribute-carrying volume once in full
|
||||
- A destination without xattr support now fails the backup run outright
|
||||
- exFAT, xattr-less NFS and object-storage FUSE mounts must move first
|
||||
|
||||
## [7.0.2] - 2026-09-23
|
||||
|
||||
* Backup: failed live pre-copy no longer aborts when a stopped copy follows
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "backup-docker-to-local"
|
||||
version = "7.1.0"
|
||||
version = "7.0.2"
|
||||
description = "Backup Docker volumes to local with rsync and optional DB dumps."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
@@ -19,7 +19,7 @@ dependencies = [
|
||||
[project.optional-dependencies]
|
||||
# Pinned: a ruff minor bump changes which rules fire, and `make test` gates on
|
||||
# a clean run, so an unpinned lint would fail the suite on an unrelated day.
|
||||
lint = ["ruff==0.16.7"]
|
||||
lint = ["ruff==0.17.0"]
|
||||
|
||||
[project.scripts]
|
||||
baudolo = "baudolo.backup.__main__:main"
|
||||
|
||||
@@ -75,7 +75,7 @@ def backup_volume(
|
||||
pathlib.Path(dest).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
last = get_last_backup_dir(versions_dir, volume_name, dest)
|
||||
cmd = ["rsync", "-aHAX", "-P", "--no-D", "--delete", "--delete-excluded"]
|
||||
cmd = ["rsync", "-aP", "--no-D", "--delete", "--delete-excluded"]
|
||||
if authoritative:
|
||||
cmd.append("--checksum")
|
||||
if last:
|
||||
|
||||
@@ -59,6 +59,6 @@ def restore_volume_files(volume_name: str, backup_files_dir: str) -> int:
|
||||
# rsync reads "dir/" as its contents and "dir" as the directory itself.
|
||||
src = f"{Path(backup_files_dir)}{os.sep}"
|
||||
dest = f"{Path(mountpoint)}{os.sep}"
|
||||
run(["rsync", "-aHAX", "-vv", "--delete", src, dest])
|
||||
run(["rsync", "-avv", "--delete", src, dest])
|
||||
print("File restore complete.")
|
||||
return 0
|
||||
@@ -46,12 +46,9 @@ class TestBackupVolume(unittest.TestCase):
|
||||
def test_it_carries_no_kernel_objects_into_a_generation(self) -> None:
|
||||
self.assertIn("--no-D", self.copy())
|
||||
|
||||
def test_it_stores_the_metadata_a_restore_has_to_give_back(self) -> None:
|
||||
self.assertIn("-aHAX", self.copy())
|
||||
|
||||
def test_it_keeps_no_twin_of_what_the_second_pass_replaces(self) -> None:
|
||||
command = self.copy(authoritative=True)
|
||||
self.assertEqual(command[:3], ["rsync", "-aHAX", "-P"])
|
||||
self.assertEqual(command[:2], ["rsync", "-aP"])
|
||||
self.assertNotIn("--backup", command)
|
||||
|
||||
def test_it_creates_the_destination(self) -> None:
|
||||
|
||||
Reference in new issue
Block a user