Pārlūkot izejas kodu

Put LVM snapshots into a data structure for convenience (#80).

Dan Helfman 6 mēneši atpakaļ
vecāks
revīzija
cc11ed78e0

+ 13 - 9
borgmatic/hooks/data_source/lvm.py

@@ -171,7 +171,7 @@ def dump_data_sources(
 
         # Get the device path for the device path for the snapshot we just created.
         try:
-            (_, snapshot_device_path) = get_snapshots(
+            snapshot = get_snapshots(
                 hook_config.get('lvs_command', 'lvs'), snapshot_name=snapshot_name
             )[0]
         except IndexError:
@@ -193,7 +193,7 @@ def dump_data_sources(
             continue
 
         mount_snapshot(
-            hook_config.get('mount_command', 'mount'), snapshot_device_path, snapshot_mount_path
+            hook_config.get('mount_command', 'mount'), snapshot.device_path, snapshot_mount_path
         )
 
         # Update the path for each contained source directory, so Borg sees it within the
@@ -243,10 +243,14 @@ def delete_snapshot(lvremove_command, snapshot_device_path):  # pragma: no cover
     )
 
 
+Snapshot = collections.namedtuple(
+    'Snapshot', ('name', 'device_path'),
+)
+
+
 def get_snapshots(lvs_command, snapshot_name=None):
     '''
-    Given an lvs command to run, return all LVM snapshots as a sequence of (snapshot name, snapshot
-    device path) pairs.
+    Given an lvs command to run, return all LVM snapshots as a sequence of Snapshot instances.
 
     If a snapshot name is given, filter the results to that snapshot.
     '''
@@ -270,7 +274,7 @@ def get_snapshots(lvs_command, snapshot_name=None):
 
     try:
         return tuple(
-            (snapshot['lv_name'], snapshot['lv_path'])
+            Snapshot(snapshot['lv_name'], snapshot['lv_path'])
             for snapshot in snapshot_info['report'][0]['lv']
             if snapshot_name is None or snapshot['lv_name'] == snapshot_name
         )
@@ -345,15 +349,15 @@ def remove_data_source_dumps(hook_config, config, log_prefix, borgmatic_runtime_
     # Delete snapshots.
     lvremove_command = hook_config.get('lvremove_command', 'lvremove')
 
-    for snapshot_name, snapshot_device_path in get_snapshots(hook_config.get('lvs_command', 'lvs')):
+    for snapshot in get_snapshots(hook_config.get('lvs_command', 'lvs')):
         # Only delete snapshots that borgmatic actually created!
-        if not snapshot_name.split('_')[-1].startswith(BORGMATIC_SNAPSHOT_PREFIX):
+        if not snapshot.name.split('_')[-1].startswith(BORGMATIC_SNAPSHOT_PREFIX):
             continue
 
-        logger.debug(f'{log_prefix}: Deleting LVM snapshot {snapshot_name}{dry_run_label}')
+        logger.debug(f'{log_prefix}: Deleting LVM snapshot {snapshot.name}{dry_run_label}')
 
         if not dry_run:
-            delete_snapshot(lvremove_command, snapshot_device_path)
+            delete_snapshot(lvremove_command, snapshot.device_path)
 
 
 def make_data_source_dump_patterns(

+ 3 - 1
borgmatic/hooks/data_source/snapshot.py

@@ -14,7 +14,9 @@ def get_contained_directories(parent_directory, candidate_contained_directories)
     then /var is what we want to snapshot.
 
     Also mutate the given set of candidate contained directories to remove any actually contained
-    directories from it.
+    directories from it. That way, this function can be called multiple times, successively
+    processing candidate directories until none are left—and avoiding assigning any candidate
+    directory to more than one parent directory.
     '''
     if not candidate_contained_directories:
         return ()