summaryrefslogtreecommitdiff
path: root/modules/zfssnap
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2022-02-19 18:29:57 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2022-02-19 18:29:57 +0100
commit8212379d03ed69326dc17d649f2f2ea0cd0ddf56 (patch)
treecd4f167a30eef1e2cc515a59199b764bc0a1aebf /modules/zfssnap
parentea31ce7efbebfab8323a625f6ab72688ff2b0315 (diff)
downloadnixos-8212379d03ed69326dc17d649f2f2ea0cd0ddf56.tar
nixos-8212379d03ed69326dc17d649f2f2ea0cd0ddf56.tar.gz
nixos-8212379d03ed69326dc17d649f2f2ea0cd0ddf56.tar.bz2
nixos-8212379d03ed69326dc17d649f2f2ea0cd0ddf56.tar.xz
nixos-8212379d03ed69326dc17d649f2f2ea0cd0ddf56.zip
zfssnap: ...
Diffstat (limited to 'modules/zfssnap')
-rw-r--r--modules/zfssnap/zfssnap.py45
1 files changed, 21 insertions, 24 deletions
diff --git a/modules/zfssnap/zfssnap.py b/modules/zfssnap/zfssnap.py
index 4e7188f9..9a536258 100644
--- a/modules/zfssnap/zfssnap.py
+++ b/modules/zfssnap/zfssnap.py
@@ -46,10 +46,9 @@ def _get_items():
46 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc: 46 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc:
47 text_stdout = io.TextIOWrapper(proc.stdout) 47 text_stdout = io.TextIOWrapper(proc.stdout)
48 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE) 48 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE)
49 for row in reader: 49 Row = namedtuple('Row', ['name', 'setting'])
50 name = row[0] 50 for row in map(Row._make, reader):
51 setting = bool(strtobool(row[1])) 51 items[row.name] = bool(strtobool(row.setting))
52 items[name] = setting
53 52
54 return items 53 return items
55 54
@@ -62,16 +61,15 @@ def prune(config, dry_run, keep_newest):
62 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc: 61 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc:
63 text_stdout = io.TextIOWrapper(proc.stdout) 62 text_stdout = io.TextIOWrapper(proc.stdout)
64 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE) 63 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE)
65 for row in reader: 64 Row = namedtuple('Row', ['name', 'timestamp'])
66 name = row[0] 65 for row in map(Row._make, reader):
67 timestamp = int(row[1]) 66 creation = datetime.fromtimestamp(int(row.timestamp), timezone.utc)
68 creation = datetime.fromtimestamp(timestamp, timezone.utc) 67 base_name, _, _ = row.name.rpartition('@')
69 base_name, _, _ = name.rpartition('@')
70 expected_name = _snap_name(base_name, time=creation) 68 expected_name = _snap_name(base_name, time=creation)
71 if expected_name != name: 69 if expected_name != row.name:
72 # logger.debug(f'Skipping ‘{name}’ since it does not conform to naming scheme') 70 # logger.debug(f'Skipping ‘{row.name}’ since it does not conform to naming scheme')
73 continue 71 continue
74 items[base_name].append(Snap(name=name, creation=creation)) 72 items[base_name].append(Snap(name=row.name, creation=creation))
75 73
76 keep = set() 74 keep = set()
77 kept_count = defaultdict(lambda: defaultdict(lambda: 0)) 75 kept_count = defaultdict(lambda: defaultdict(lambda: 0))
@@ -162,29 +160,28 @@ def rename(snapshots, destroy=False):
162 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc: 160 with subprocess.Popen(args, stdout=subprocess.PIPE) as proc:
163 text_stdout = io.TextIOWrapper(proc.stdout) 161 text_stdout = io.TextIOWrapper(proc.stdout)
164 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE) 162 reader = csv.reader(text_stdout, delimiter='\t', quoting=csv.QUOTE_NONE)
165 for row in reader: 163 Row = namedtuple('Row', ['name', 'timestamp'])
166 name = row[0] 164 for row in map(Row._make, reader):
167 timestamp = int(row[1]) 165 creation = datetime.fromtimestamp(int(row.timestamp), timezone.utc)
168 creation = datetime.fromtimestamp(timestamp, timezone.utc) 166 base_name, _, _ = row.name.rpartition('@')
169 base_name, _, _ = name.rpartition('@')
170 new_name = _snap_name(base_name, time=creation) 167 new_name = _snap_name(base_name, time=creation)
171 if new_name == name: 168 if new_name == row.name:
172 logger.debug(f'Not renaming ‘{name}’ since name is already correct') 169 logger.debug(f'Not renaming ‘{row.name}’ since name is already correct')
173 continue 170 continue
174 171
175 if new_name in renamed_to: 172 if new_name in renamed_to:
176 if destroy: 173 if destroy:
177 logger.warning(f'Destroying ‘{name}’ since ‘{new_name}’ was already renamed to') 174 logger.warning(f'Destroying ‘{row.name}’ since ‘{new_name}’ was already renamed to')
178 args = ['zfs', 'destroy', name] 175 args = ['zfs', 'destroy', row.name]
179 _log_cmd(*args) 176 _log_cmd(*args)
180 subprocess.run(args, check=True) 177 subprocess.run(args, check=True)
181 else: 178 else:
182 logger.info(f'Skipping ‘{name}’ since ‘{new_name}’ was already renamed to') 179 logger.info(f'Skipping ‘{row.name}’ since ‘{new_name}’ was already renamed to')
183 180
184 continue 181 continue
185 182
186 logger.info(f'Renaming ‘{name}’ to ‘{new_name}’') 183 logger.info(f'Renaming ‘{row.name}’ to ‘{new_name}’')
187 args = ['zfs', 'rename', name, new_name] 184 args = ['zfs', 'rename', row.name, new_name]
188 _log_cmd(*args) 185 _log_cmd(*args)
189 subprocess.run(args, check=True) 186 subprocess.run(args, check=True)
190 renamed_to.add(new_name) 187 renamed_to.add(new_name)