1
0
Fork 0
mirror of https://codeberg.org/Mo8it/dotfiles.git synced 2024-10-17 20:52:40 +00:00
dotfiles/.scripts/restic.py
2022-07-01 23:33:13 +02:00

131 lines
3.3 KiB
Python

import subprocess
from getpass import getpass
from os import environ
from pathlib import Path
CONFIG_PATH = Path.home() / ".config/restic_bk/"
def run(command: str, **kwargs):
return subprocess.run(command, shell=True, **kwargs)
def decorated_print(str: str):
print(f"\n<<-<>==={str}===<>->>\n")
def write_home_visible_includes():
home_visible_content = set(
run(
"fd -d 1 '.*' ~", check=True, stdout=subprocess.PIPE, text=True
).stdout.split()
)
home_visible_excludes = []
with open(CONFIG_PATH / "home_visible_excludes.txt") as f:
for line in f:
home_visible_excludes.append(line.strip())
home_visible_includes = home_visible_content.difference(home_visible_excludes)
with open(CONFIG_PATH / "home_visible_includes.txt", "w") as f:
for line in home_visible_includes:
f.write(line + "\n")
def mounted_backup_drive():
mounted_drives_path = Path("/run/media") / environ["USER"]
if not mounted_drives_path.is_dir():
raise Exception("No drives mounted!")
known_backup_drives = []
with open(CONFIG_PATH / "known_backup_drives.txt") as f:
for line in f:
known_backup_drives.append(line.strip())
mounted_backup_drives = []
for path in mounted_drives_path.iterdir():
if path.is_dir():
drive_name = path.parts[-1]
if drive_name in known_backup_drives:
mounted_backup_drives.append(drive_name)
if len(mounted_backup_drives) == 0:
raise Exception("No known backup drives found!")
ind = 0
if len(mounted_backup_drives) > 1:
decorated_print("Found multiple known backup drives")
for i, drive in enumerate(mounted_backup_drives):
print(f"{i}: {drive}")
ind = int(input("Enter index: "))
return mounted_drives_path / mounted_backup_drives[ind]
def pre_backup():
password = getpass("Restic repo password: ")
write_home_visible_includes()
repo = mounted_backup_drive() / "restic"
init_repo = False
if not repo.is_dir():
decorated_print(f"No repo found at {repo} !!")
ans = input("Initialize repo? [Y/n]: ")
if ans.strip().lower() not in ("", "y"):
raise Exception("No repo to work with!")
else:
init_repo = True
with open(CONFIG_PATH / "pre_backup_scripts.txt") as f:
for line in f:
line = line.strip()
decorated_print(f"Running {line}")
run(f"python {line}", stderr=subprocess.DEVNULL)
run("restic self-update", stderr=subprocess.DEVNULL)
env = environ.copy()
env["RESTIC_REPOSITORY"] = repo
env["RESTIC_PASSWORD"] = password
if init_repo:
run("restic init", env=env, check=True)
return env
def backup(env):
home_visible_includes = CONFIG_PATH / "home_visible_includes.txt"
includes = CONFIG_PATH / "includes.txt"
excludes = CONFIG_PATH / "excludes.txt"
run(
f"restic backup -v --files-from {home_visible_includes} --files-from {includes} --exclude-file {excludes}",
env=env,
check=True,
)
def post_backup(env):
run("restic check", env=env, check=True)
run("restic snapshots --compact", env=env)
def main():
env = pre_backup()
backup(env)
post_backup(env)
decorated_print("DONE")
if __name__ == "__main__":
main()