diff options
-rw-r--r-- | modules/zfssnap/zfssnap.py | 42 |
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 | ||
26 | from math import floor | 26 | from math import floor |
27 | 27 | ||
28 | import asyncio | ||
29 | |||
28 | 30 | ||
29 | @cache | 31 | @cache |
30 | def _now(): | 32 | def _now(): |
@@ -212,8 +214,33 @@ def rename(snapshots, destroy=False, set_is_auto=False): | |||
212 | def autosnap(): | 214 | def 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: |