#!/usr/bin/python3 # vim: shiftwidth=4 softtabstop=4 tabstop=4 expandtab # pylint: disable=too-few-public-methods """backup.py This module contains the backup functionality of xbackup. """ import os from xbackup.utils import POSITIVE_ANSWERS,shell def backup(generic_cfg, paths_cfg, scripted): """perform a file-based full system backup""" # generate all necessary paths based on config paths = Filepaths(generic_cfg, paths_cfg) print(paths) # get confirmation from user if not in scripted execution mode if not scripted: answer = input("\nDo you want to continue? [y/N] ") if answer not in POSITIVE_ANSWERS: print("\nTerminated.") return # init borg repository (accepting failure on already existing repo) shell(f"borg init -e none {paths.borg_repo}", panic=False) # run backup run_backup(paths) class Filepaths(): """A Container Class to hold Filepaths for the Borg Backup Tool""" def __init__(self, generic_cfg, paths_cfg): """The Constructor""" # parse backup source (usually / for system backups) self.backup_root = paths_cfg["backup_root"] # parse folder for borg repositories self.borg_repos_folder = generic_cfg["borg_repos_folder"] # path to the borg repository hostname = os.uname()[1] self.borg_repo = os.path.join(self.borg_repos_folder, hostname) # create blacklist of folders to be excluded from the backup self.blacklist = [] for entry in paths_cfg["blacklist"]: self.blacklist.append(os.path.join(self.backup_root, entry)) # avoid matroska-style backups of backups (yes, it is important) self.blacklist.append(self.borg_repos_folder) def __str__(self): """Converts an Object based on this Class to a String""" retval = "" retval += "\nbackup_root:\n" + self.backup_root + "\n" retval += "\nblacklist:\n" for item in self.blacklist: retval += item + "\n" retval += "\nborg_repo:\n" + self.borg_repo return retval def run_backup(paths): """Execute the Borg Backup""" # base command command = "borg create -v --stats --compression zstd \\" # set repository path command += \ f"{paths.borg_repo}::'{{hostname}}-{{user}}-{{now:%Y-%m-%d_%H:%M:%S}}' \\" # set backup source command += f"\n {paths.backup_root} \\" # append blacklist elements for key,value in enumerate(paths.blacklist): command += f"\n --exclude '{value}'" if key != len(paths.blacklist) -1: command += " \\" # run command shell(command)