diff options
Diffstat (limited to 'modules/zfssnap/zfssnap.py')
-rw-r--r-- | modules/zfssnap/zfssnap.py | 45 |
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) |