restic-backups/restic_many.py

128 lines
3.8 KiB
Python
Executable File

#!/bin/python3
import os
import sys
import json
import shlex
import subprocess
import argparse
import pathlib
import socket
import traceback
import time
restic_bin = 'restic'
init_command = "restic -r %s init"
command = "restic -r %s backup --verbose %s"
hostname = socket.gethostname()
print("This machine's hostname is " + hostname)
def do_backup(repo_name, paths):
result = subprocess.run([restic_bin, '-r', repo_name, 'backup', '--verbose'] + paths)
def init_repo(repo_name):
result = subprocess.run([restic_bin, '-r', repo_name, 'init'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
any_errors = len(result.stderr) > 0
already_existed = result.stderr.decode('utf-8').strip().endswith('config already exists')
if any_errors and not already_existed:
print(result.stderr.decode('utf-8').strip())
return False
if already_existed:
print("Repo already exists")
return True
print(result.stdout.decode('utf-8').strip())
print("Repo was created.")
return True
def cmd_backup():
result_info = []
with open('backup-config.json') as json_file:
data = json.load(json_file)
repo_name_prefix = data['repo_name_prefix']
for repo in data['repos']:
if repo['hostname'] != hostname:
print('(skipping ' + repo['name'] + ' since this machine is not ' + repo['hostname'] + ')')
continue
repo_name = repo_name_prefix + repo['name']
print('Repo: ' + repo_name)
paths_to_backup = [shlex.quote(p) for p in repo['paths']]
print('Backing up paths: ' + ", ".join(paths_to_backup))
init_result = init_repo(repo_name)
if not init_result:
print('Skipping backup of %s.' % repo_name)
continue
do_backup(repo_name, paths_to_backup)
def cmd_mount():
processes = []
mount_points = []
with open('backup-config.json') as json_file:
data = json.load(json_file)
repo_name_prefix = data['repo_name_prefix']
mount_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mnt_restic")
for repo in data['repos']:
repo_name = repo_name_prefix + repo['name']
repo_mount_path = os.path.join(mount_root, repo['name'])
pathlib.Path(repo_mount_path).mkdir(parents=True, exist_ok=True)
mount_process = subprocess.Popen([restic_bin, '-r', repo_name, 'mount', '--verbose', repo_mount_path])
processes.append(mount_process)
mount_points.append(repo_mount_path)
try:
print("mounts starting. press ctrl+c to kill all mounts")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("ctrl+c pressed. killing subprocesses")
for proc in processes:
proc.kill()
print("you'll also want to umount these mount points:")
for mp in mount_points:
print("umount " + mp)
except:
print("unhandled exception")
traceback.print_exc()
def cmd_list():
with open('backup-config.json') as json_file:
data = json.load(json_file)
repo_name_prefix = data['repo_name_prefix']
for repo in data['repos']:
repo_name = repo_name_prefix + repo['name']
print("restic -r %s " % repo_name)
parser = argparse.ArgumentParser(description = "backup or mount many paths using restic")
parser.add_argument('command', help='command to run (backup, mount, umount)')
parser.add_argument('--resticbin', help='restic binary location, if not on PATH')
args = parser.parse_args()
# call function with the name.
fn_name = "cmd_" + args.command
if not fn_name in globals():
print("Command doesn't exist")
parser.print_help()
exit(1)
if args.resticbin:
restic_bin = args.resticbin
globals()[fn_name]()