Backups: When rsync option is selected, allow modifying the target port (#30)
This commit is contained in:
parent
04e1c0647e
commit
8a0805dae8
3 changed files with 53 additions and 22 deletions
|
@ -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.
|
||||
|
|
|
@ -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', '')
|
||||
))
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue