From af9ef186b3a0761efe0661254c54fe82dcb89887 Mon Sep 17 00:00:00 2001 From: David Duque Date: Fri, 10 Jul 2020 15:48:37 +0100 Subject: [PATCH] Add manual backup option --- management/backup.py | 26 ++++++++++++++++------ management/daemon.py | 13 +++++++++++ management/templates/system-backup.html | 29 +++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/management/backup.py b/management/backup.py index 90a6458..cbc2ff5 100755 --- a/management/backup.py +++ b/management/backup.py @@ -10,7 +10,7 @@ import os, os.path, shutil, glob, re, datetime, sys import dateutil.parser, dateutil.relativedelta, dateutil.tz import rtyaml -from exclusiveprocess import Lock +from exclusiveprocess import Lock, CannotAcquireLock from utils import load_environment, shell, wait_for_service, fix_boto @@ -20,7 +20,7 @@ rsync_ssh_options = [ ] def backup_status(env): - # If backups are dissbled, return no status. + # If backups are disabled, return no status. config = get_backup_config(env) if config["target"] == "off": return { } @@ -210,13 +210,21 @@ def get_target_type(config): protocol = config["target"].split(":")[0] return protocol -def perform_backup(full_backup): +def perform_backup(full_backup, user_initiated=False): env = load_environment() # Create an global exclusive lock so that the backup script # cannot be run more than one. - Lock(die=True).forever() - + lock = Lock(die=(not user_initiated)) + if user_initiated: + # God forgive me for what I'm about to do + try: + lock._acquire() + except CannotAcquireLock: + return "Another backup is already being done!" + else: + lock.forever() + config = get_backup_config(env) backup_root = os.path.join(env["STORAGE_ROOT"], 'backup') backup_cache_dir = os.path.join(backup_root, 'cache') @@ -329,8 +337,12 @@ def perform_backup(full_backup): # backup. Since it checks that dovecot and postfix are running, block for a # bit (maximum of 10 seconds each) to give each a chance to finish restarting # before the status checks might catch them down. See #381. - wait_for_service(25, True, env, 10) - wait_for_service(993, True, env, 10) + if user_initiated: + # God forgive me for what I'm about to do + lock._release() # We don't need to restart the services + else: + wait_for_service(25, True, env, 10) + wait_for_service(993, True, env, 10) def run_duplicity_verification(): env = load_environment() diff --git a/management/daemon.py b/management/daemon.py index 26c7166..2731bb1 100755 --- a/management/daemon.py +++ b/management/daemon.py @@ -509,6 +509,19 @@ def backup_set_custom(): request.form.get('min_age', '') )) +@app.route('/system/backup/new', methods=["POST"]) +@authorized_personnel_only +def backup_new(): + from backup import perform_backup, get_backup_config + + # If backups are disabled, don't perform the backup + config = get_backup_config(env) + if config["target"] == "off": + return "Backups are disabled in this machine. Nothing was done." + + msg = perform_backup(request.form.get('full', False) == 'true', True) + return "OK" if msg is None else msg + @app.route('/system/privacy', methods=["GET"]) @authorized_personnel_only def privacy_status_get(): diff --git a/management/templates/system-backup.html b/management/templates/system-backup.html index 81915fd..f24f48c 100644 --- a/management/templates/system-backup.html +++ b/management/templates/system-backup.html @@ -140,6 +140,10 @@ + + + +