summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/zfssnap/zfssnap.py42
1 files changed, 38 insertions, 4 deletions
diff --git a/modules/zfssnap/zfssnap.py b/modules/zfssnap/zfssnap.py
index 360d7f25..6d9bc6de 100644
--- a/modules/zfssnap/zfssnap.py
+++ b/modules/zfssnap/zfssnap.py
@@ -25,6 +25,8 @@ from functools import cache
25 25
26from math import floor 26from math import floor
27 27
28import asyncio
29
28 30
29@cache 31@cache
30def _now(): 32def _now():
@@ -212,8 +214,33 @@ def rename(snapshots, destroy=False, set_is_auto=False):
212def autosnap(): 214def autosnap():
213 items = _get_items() 215 items = _get_items()
214 216
217 recursive, single = set(), set()
218
219 for item_name, is_included in items.items():
220 if not is_included:
221 continue
222
223 children = {sub_name for sub_name in items if sub_name.startswith(f'{item_name}/')}
224 is_recursive = all([items[sub_name] for sub_name in children])
225 if is_recursive and children:
226 recursive.add(item_name)
227 else:
228 single.add(item_name)
229
230 for item_name in recursive | single:
231 is_covered = any([item_name.startswith(f'{super_name}/') for super_name in recursive])
232 if is_covered:
233 try:
234 recursive.remove(item_name)
235 except KeyError:
236 pass
237 try:
238 single.remove(item_name)
239 except KeyError:
240 pass
241
215 all_snap_names = set() 242 all_snap_names = set()
216 def do_snapshot(*snap_items, recursive=False): 243 async def do_snapshot(*snap_items, recursive=False):
217 nonlocal items, all_snap_names 244 nonlocal items, all_snap_names
218 snap_names = {_snap_name(item) for item in snap_items} 245 snap_names = {_snap_name(item) for item in snap_items}
219 if recursive: 246 if recursive:
@@ -230,10 +257,17 @@ def autosnap():
230 _log_cmd(*args) 257 _log_cmd(*args)
231 subprocess.run(args, check=True) 258 subprocess.run(args, check=True)
232 259
233 260 tasks = []
234 do_snapshot(*items) 261 if single:
235 if not items: 262 tasks.append(do_snapshot(*single))
263 if recursive:
264 tasks.append(do_snapshot(*recursive, recursive=True))
265 if not tasks:
236 logger.warning('No snapshots to create') 266 logger.warning('No snapshots to create')
267 else:
268 async def run_tasks():
269 await asyncio.gather(*tasks)
270 asyncio.run(run_tasks())
237 for snap in all_snap_names: 271 for snap in all_snap_names:
238 logger.info(f'Created ‘{snap}’') 272 logger.info(f'Created ‘{snap}’')
239 if all_snap_names: 273 if all_snap_names: