From 00bf9f3eafff6f29b4fcf18d7c1f2ab2b1310c16 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 15 Feb 2020 11:05:43 +0100 Subject: Rename bupper to lbup. bupper already exists. lbup is a randomly chosen word containing bup --- lbup/repository.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 lbup/repository.py (limited to 'lbup/repository.py') diff --git a/lbup/repository.py b/lbup/repository.py new file mode 100644 index 0000000..0cb1161 --- /dev/null +++ b/lbup/repository.py @@ -0,0 +1,81 @@ +import fcntl +import os +import os.path +import subprocess + +class StepResult: + retcode = None + output = None + def __init__(self, retcode = 0, output = None): + self.retcode = retcode + self.output = output + +class BackupResult: + target_results = None + par2_result = None + + def __init__(self): + self.target_results = [] + self.par2_result = StepResult() + + @property + def all_ok(self): + return (all(map(lambda tgtres: tgtres.retcode == 0, self.target_results)) and + self.par2_result.retcode == 0) + + +class Repo: + """ + A single Bup repository into which the data will be backed up, plus a + separate directory for extra runtime data. + + :param str bup_dir: path to the bup repository, defaults to BUP_DIR or ~/.bup + :param str data_dir: path to the directory for storing the runtime data, + defaults to ~/.local/var/lbup + """ + bup_dir = None + data_dir = None + lock_name = 'lock' + + def __init__(self, bup_dir = None, data_dir = None): + if bup_dir is None: + if 'BUP_DIR' in os.environ: + bup_dir = os.environ['BUP_DIR'] + else: + bup_dir = os.path.expanduser('~/.bup') + + if data_dir is None: + data_dir = os.path.expanduser('~/.local/var/lbup/') + + # create the data dir, if it does not already exist + os.makedirs(data_dir, 0o700, exist_ok = True) + + self.bup_dir = bup_dir + self.data_dir = data_dir + + def backup(self, tgts, gen_par2 = True): + """ + Backup the supplied targets. + + :param list of Target tgts: List of targets to back up. + :param bool gen_par2: Whether to generate par2 recovery information + after the backup concludes' + """ + with open(os.path.join(self.data_dir, self.lock_name), 'w') as lockfile: + result = BackupResult() + + fcntl.lockf(lockfile, fcntl.LOCK_EX) + try: + for tgt in tgts: + res = tgt.save(self.data_dir) + result.target_results.append(res) + + if gen_par2: + res = subprocess.run(['bup', 'fsck', '-g'], + capture_output = True) + result.par2_result = StepResult(res.returncode, + res.stderr + res.stdout) + finally: + fcntl.lockf(lockfile, fcntl.LOCK_UN) + + return result -- cgit v1.2.3