128 lines
3.8 KiB
Python
Executable File
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]()
|