fleshed out prune module

This commit is contained in:
John Lancaster
2024-05-27 12:49:36 -05:00
parent 8792a34e80
commit 26a94aa02d

View File

@@ -1,33 +1,64 @@
import json
import logging import logging
import re import re
import subprocess import subprocess
import sys
from rich.logging import RichHandler
from restic.console import console, logger from restic.console import console, logger
from restic.loki import send_to_loki
field_regex = re.compile(
r'^(?P<name>[\w ]+):\s+(?P<blobs>\d+) blobs \/ (?P<size>\d+(\.\d+)? (M|G)iB)', re.MULTILINE
)
def main(dry_run: bool = False): def convert_size(size_str: str) -> int:
base_size = float(size_str.split(' ')[0])
if size_str.endswith('GiB'):
scale = 8589934592
elif size_str.endswith('MiB'):
scale = 8388608
return int(round(base_size * scale))
def field_gen(result_str: str):
for m in field_regex.finditer(result_str):
d = m.groupdict()
d['blobs'] = int(d['blobs'])
d['size'] = convert_size(d['size'])
yield d
def prune(loki_url: str = None, dry_run: bool = False):
cmd = ['restic', 'prune'] cmd = ['restic', 'prune']
if dry_run: if dry_run:
cmd.append('-n') cmd.append('--dry-run')
logger.debug(f'Running cmd [bright_black]{" ".join(cmd)}[/]') logger.debug(f'Running cmd [bright_black]{" ".join(cmd)}[/]')
with console.status('Pruning...'): with console.status('Pruning...'):
result = subprocess.run(cmd, capture_output=True, text=True) result = subprocess.run(cmd, capture_output=True, text=True)
if m := re.search(r'total prune:\s+(.*?)$', result.stdout, re.MULTILINE): if result.returncode != 0:
pruned_data = m.group(1).split(' / ')[1] logger.error(result.stderr)
logger.info(f'Pruned {pruned_data}') sys.exit(1)
if m := re.search(r'remaining:\s+(.*?)$', result.stdout, re.MULTILINE): d = {f['name']: {'blobs': f['blobs'], 'size': f['size']} for f in field_gen(result.stdout)}
remaining = m.group(1).split(' / ')[1] console.print(d)
logger.info(f'{remaining} remaining')
if loki_url is not None and not dry_run:
send_to_loki(loki_url, line=json.dumps(d), backup='prune')
if __name__ == '__main__': def main():
from rich.logging import RichHandler
logging.basicConfig( logging.basicConfig(
level='DEBUG', format='%(message)s', handlers=[RichHandler(markup=True, console=console)] level='DEBUG', format='%(message)s', handlers=[RichHandler(markup=True, console=console)]
) )
prune(dry_run=True)
if __name__ == '__main__':
main() main()