2
0
Эх сурвалжийг харах

Fix an error in the Btrfs hook when a "/" subvolume is configured in borgmatic's source directories (#959).

Dan Helfman 5 сар өмнө
parent
commit
d3409df84c

+ 4 - 0
NEWS

@@ -1,3 +1,7 @@
+1.9.6.dev0
+ * #959: Fix an error in the Btrfs hook when a "/" subvolume is configured in borgmatic's source
+   directories.
+
 1.9.5
  * #418: Backup and restore databases that have the same name but with different ports, hostnames,
    or hooks.

+ 5 - 7
borgmatic/hooks/data_source/btrfs.py

@@ -115,17 +115,15 @@ def get_subvolumes(btrfs_command, findmnt_command, source_directories=None):
 BORGMATIC_SNAPSHOT_PREFIX = '.borgmatic-snapshot-'
 
 
-def make_snapshot_path(subvolume_path):  # pragma: no cover
+def make_snapshot_path(subvolume_path):
     '''
     Given the path to a subvolume, make a corresponding snapshot path for it.
     '''
     return os.path.join(
         subvolume_path,
         f'{BORGMATIC_SNAPSHOT_PREFIX}{os.getpid()}',
-        # Included so that the snapshot ends up in the Borg archive at the "original" subvolume
-        # path.
-        subvolume_path.lstrip(os.path.sep),
-    )
+        # Included so that the snapshot ends up in the Borg archive at the "original" subvolume path.
+    ) + subvolume_path.rstrip(os.path.sep)
 
 
 def make_snapshot_exclude_path(subvolume_path):  # pragma: no cover
@@ -155,7 +153,7 @@ def make_snapshot_exclude_path(subvolume_path):  # pragma: no cover
     )
 
 
-def make_borg_source_directory_path(subvolume_path, source_directory):  # pragma: no cover
+def make_borg_source_directory_path(subvolume_path, source_directory):
     '''
     Given the path to a subvolume and a source directory inside it, make a corresponding path for
     the source directory within a snapshot path intended for giving to Borg.
@@ -181,7 +179,7 @@ def snapshot_subvolume(btrfs_command, subvolume_path, snapshot_path):  # pragma:
         + (
             'subvolume',
             'snapshot',
-            '-r',  # Read-only,
+            '-r',  # Read-only.
             subvolume_path,
             snapshot_path,
         ),

+ 1 - 1
pyproject.toml

@@ -1,6 +1,6 @@
 [project]
 name = "borgmatic"
-version = "1.9.5"
+version = "1.9.6.dev0"
 authors = [
   { name="Dan Helfman", email="witten@torsion.org" },
 ]

+ 35 - 0
tests/unit/hooks/data_source/test_btrfs.py

@@ -128,6 +128,41 @@ def test_get_subvolumes_without_source_directories_collects_all_subvolumes_from_
     )
 
 
+@pytest.mark.parametrize(
+    'subvolume_path,expected_snapshot_path',
+    (
+        ('/foo/bar', '/foo/bar/.borgmatic-snapshot-1234/foo/bar'),
+        ('/', '/.borgmatic-snapshot-1234'),
+    ),
+)
+def test_make_snapshot_path_includes_stripped_subvolume_path(
+    subvolume_path, expected_snapshot_path
+):
+    flexmock(module.os).should_receive('getpid').and_return(1234)
+
+    assert module.make_snapshot_path(subvolume_path) == expected_snapshot_path
+
+
+@pytest.mark.parametrize(
+    'subvolume_path,source_directory_path,expected_path',
+    (
+        ('/foo/bar', '/foo/bar/baz', '/foo/bar/.borgmatic-snapshot-1234/./foo/bar/baz'),
+        ('/foo/bar', '/foo/bar', '/foo/bar/.borgmatic-snapshot-1234/./foo/bar'),
+        ('/', '/foo', '/.borgmatic-snapshot-1234/./foo'),
+        ('/', '/', '/.borgmatic-snapshot-1234/./'),
+    ),
+)
+def test_make_borg_source_directory_path_includes_slashdot_hack_and_stripped_source_directory_path(
+    subvolume_path, source_directory_path, expected_path
+):
+    flexmock(module.os).should_receive('getpid').and_return(1234)
+
+    assert (
+        module.make_borg_source_directory_path(subvolume_path, source_directory_path)
+        == expected_path
+    )
+
+
 def test_dump_data_sources_snapshots_each_subvolume_and_updates_source_directories():
     source_directories = ['/foo', '/mnt/subvol1']
     config = {'btrfs': {}}