Backups: When rsync option is selected, allow modifying the target port (#30)

This commit is contained in:
David Duque 2021-10-19 11:20:41 +01:00 committed by GitHub
parent 04e1c0647e
commit 8a0805dae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 22 deletions

View file

@ -14,10 +14,20 @@ from exclusiveprocess import Lock, CannotAcquireLock
from utils import load_environment, shell, wait_for_service, fix_boto, get_php_version, get_os_code
rsync_ssh_options = [
"--ssh-options= -i /root/.ssh/id_rsa_miab",
"--rsync-options= -e \"/usr/bin/ssh -oStrictHostKeyChecking=no -oBatchMode=yes -p 22 -i /root/.ssh/id_rsa_miab\"",
]
def rsync_ssh_options(port = 22, direct = False):
# Just in case we pass a string
try:
port = int(port)
except Exception:
port = 22
if direct:
return f"/usr/bin/ssh -oStrictHostKeyChecking=no -oBatchMode=yes -p {port} -i /root/.ssh/id_rsa_miab"
else:
return [
f"--ssh-options= -i /root/.ssh/id_rsa_miab -p {port}",
f"--rsync-options= -e \"/usr/bin/ssh -oStrictHostKeyChecking=no -oBatchMode=yes -p {port} -i /root/.ssh/id_rsa_miab\"",
]
def backup_status(env):
# If backups are disabled, return no status.
@ -65,7 +75,7 @@ def backup_status(env):
"--gpg-options", "--cipher-algo=AES256",
"--log-fd", "1",
config["target"],
] + rsync_ssh_options,
] + rsync_ssh_options(port = config["target_rsync_port"]),
get_env(env),
trap=True)
if code != 0:
@ -284,7 +294,7 @@ def perform_backup(full_backup, user_initiated=False):
env["STORAGE_ROOT"],
config["target"],
"--allow-source-mismatch"
] + rsync_ssh_options,
] + rsync_ssh_options(port = config["target_rsync_port"]),
get_env(env))
finally:
# Start services again.
@ -302,7 +312,7 @@ def perform_backup(full_backup, user_initiated=False):
"--archive-dir", backup_cache_dir,
"--force",
config["target"]
] + rsync_ssh_options,
] + rsync_ssh_options(port = config["target_rsync_port"]),
get_env(env))
# From duplicity's manual:
@ -317,7 +327,7 @@ def perform_backup(full_backup, user_initiated=False):
"--archive-dir", backup_cache_dir,
"--force",
config["target"]
] + rsync_ssh_options,
] + rsync_ssh_options(port = config["target_rsync_port"]),
get_env(env))
# Change ownership of backups to the user-data user, so that the after-bcakup
@ -361,7 +371,7 @@ def run_duplicity_verification():
"--exclude", backup_root,
config["target"],
env["STORAGE_ROOT"],
] + rsync_ssh_options, get_env(env))
] + rsync_ssh_options(port = config["target_rsync_port"]), get_env(env))
def run_duplicity_restore(args):
env = load_environment()
@ -372,7 +382,7 @@ def run_duplicity_restore(args):
"restore",
"--archive-dir", backup_cache_dir,
config["target"],
] + rsync_ssh_options + args,
] + rsync_ssh_options(port = config["target_rsync_port"]) + args,
get_env(env))
def list_target_files(config):
@ -397,7 +407,7 @@ def list_target_files(config):
rsync_command = [ 'rsync',
'-e',
'/usr/bin/ssh -i /root/.ssh/id_rsa_miab -oStrictHostKeyChecking=no -oBatchMode=yes',
rsync_ssh_options(config["target_rsync_port"], direct = True),
'--list-only',
'-r',
rsync_target.format(
@ -423,8 +433,8 @@ def list_target_files(config):
elif 'Could not resolve hostname' in listing:
reason = "The hostname {} cannot be resolved.".format(target.hostname)
else:
reason = "Unknown error." \
"Please check running 'management/backup.py --verify'" \
reason = "Unknown error. " \
"Please check running 'management/backup.py --verify' " \
"from mailinabox sources to debug the issue."
raise ValueError("Connection to rsync host failed: {}".format(reason))
@ -504,16 +514,23 @@ def list_target_files(config):
raise ValueError(config["target"])
def backup_set_custom(env, target, target_user, target_pass, min_age):
def backup_set_custom(env, target, target_user, target_pass, target_rsync_port, min_age):
config = get_backup_config(env, for_save=True)
# min_age must be an int
if isinstance(min_age, str):
min_age = int(min_age)
if isinstance(target_rsync_port, str):
try:
target_rsync_port = int(target_rsync_port)
except:
target_rsync_port = 22
config["target"] = target
config["target_user"] = target_user
config["target_pass"] = target_pass
config["target_rsync_port"] = target_rsync_port
config["min_age_in_days"] = min_age
# Validate.
@ -536,6 +553,7 @@ def get_backup_config(env, for_save=False, for_ui=False):
config = {
"min_age_in_days": 3,
"target": "local",
"target_rsync_port": 22
}
# Merge in anything written to custom.yaml.

View file

@ -663,6 +663,7 @@ def backup_set_custom():
request.form.get('target', ''),
request.form.get('target_user', ''),
request.form.get('target_pass', ''),
request.form.get('target_rsync_port', ''),
request.form.get('min_age', '')
))

View file

@ -42,10 +42,18 @@
</div>
</div>
<div class="form-group backup-target-rsync">
<label for="backup-target-rsync-host" class="col-sm-2 control-label">Hostname</label>
<div class="col-sm-8">
<input type="text" placeholder="hostname.local" class="form-control" rows="1" id="backup-target-rsync-host">
</div>
<table class="col-sm-8">
<tr style="width: 100%;">
<td style="width: 75%;" class="col-sm-8">
<label for="backup-target-rsync-host" class="control-label">Hostname</label>
<input type="text" placeholder="hostname.local" class="form-control" rows="1" id="backup-target-rsync-host">
</td>
<td style="width: 25%;" class="col-sm-8">
<label for="backup-target-rsync-port" class="control-label">Port</label>
<input type="number" class="form-control" id="backup-target-rsync-port" placeholder="22">
</td>
</tr>
</table>
</div>
<div class="form-group backup-target-rsync">
<label for="backup-target-rsync-path" class="col-sm-2 control-label">Path</label>
@ -270,11 +278,14 @@ function show_custom_backup() {
$("#backup-target-type").val("off");
} else if (r.target.substring(0, 8) == "rsync://") {
$("#backup-target-type").val("rsync");
var path = r.target.substring(8).split('//');
var host_parts = path.shift().split('@');
let uri = r.target.substring(8)
let i = uri.indexOf("/")
let path = [uri.slice(0, i), uri.slice(i + 1)];
let host_parts = path.shift().split('@');
$("#backup-target-rsync-user").val(host_parts[0]);
$("#backup-target-rsync-host").val(host_parts[1]);
$("#backup-target-rsync-path").val('/'+path[0]);
$("#backup-target-rsync-path").val(path[0]);
$("#backup-target-rsync-port").val(r.target_rsync_port)
} else if (r.target.substring(0, 5) == "s3://") {
$("#backup-target-type").val("s3");
var hostpath = r.target.substring(5).split('/');
@ -299,6 +310,7 @@ function set_custom_backup() {
var target_type = $("#backup-target-type").val();
var target_user = $("#backup-target-user").val();
var target_pass = $("#backup-target-pass").val();
let target_port = $("#backup-target-rsync-port").val();
var target;
if (target_type == "local" || target_type == "off")
@ -316,7 +328,6 @@ function set_custom_backup() {
target_pass = '';
}
var min_age = $("#min-age").val();
api(
"/system/backup/config",
@ -325,6 +336,7 @@ function set_custom_backup() {
target: target,
target_user: target_user,
target_pass: target_pass,
target_rsync_port: target_port,
min_age: min_age
},
function(r) {