Add manual backup option
This commit is contained in:
parent
199c2c50ba
commit
af9ef186b3
3 changed files with 61 additions and 7 deletions
|
@ -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()
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -140,6 +140,10 @@
|
|||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button id="create-full-backup-button" class="btn btn-primary" onclick="do_backup(true)">Create Full Backup Now</button>
|
||||
<button id="create-incremental-backup-button" class="btn btn-primary" onclick="do_backup(false)">Create Incremental Backup Now</button>
|
||||
|
||||
<script>
|
||||
|
||||
function toggle_form() {
|
||||
|
@ -303,4 +307,29 @@ function init_inputs(target_type) {
|
|||
set_host($('#backup-target-s3-host-select').val());
|
||||
}
|
||||
}
|
||||
|
||||
function do_backup(is_full) {
|
||||
let disclaimer = "The backup process will pause some services (such as PHP, Postfix and Dovecot). Depending on the size of the data this can take a while."
|
||||
if (!is_full) {
|
||||
disclaimer += "\nDepending on the amount of incremental backups done after the last full backup, the box may decide to do a full backup instead."
|
||||
}
|
||||
show_modal_confirm("Warning!", disclaimer, "Start Backup", () => {
|
||||
api(
|
||||
"/system/backup/new",
|
||||
"POST",
|
||||
{
|
||||
full: is_full
|
||||
},
|
||||
function(r) {
|
||||
// use .text() --- it's a text response, not html
|
||||
show_modal_error("Backup configuration", $("<p/>").text(r), function() { if (r == "OK") show_system_backup(); }); // refresh after modal on success
|
||||
},
|
||||
function(r) {
|
||||
// use .text() --- it's a text response, not html
|
||||
show_modal_error("Backup configuration", $("<p/>").text(r));
|
||||
});
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue