diff --git a/CHANGELOG.md b/CHANGELOG.md index 837a9fd9..cb58c0c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Package updates: Control panel: +* Allow setting the backup location's S3 region name for non-AWS S3-compatible backup hosts. * Control panel pages can be opened in a new tab/window and bookmarked and browser history navigation now works. * Add a Copy button to put the rsync backup public key on clipboard. * Allow secondary DNS xfr: items added in the control panel to be hostnames too. diff --git a/management/backup.py b/management/backup.py index 99c3d60e..06285ba5 100755 --- a/management/backup.py +++ b/management/backup.py @@ -202,7 +202,9 @@ def get_duplicity_target_url(config): # the target URL must be the bucket name. The hostname is passed # via get_duplicity_additional_args. Move the first part of the # path (the bucket name) into the hostname URL component, and leave - # the rest for the path. + # the rest for the path. (The S3 region name is also stored in the + # hostname part of the URL, in the username portion, which we also + # have to drop here). target[1], target[2] = target[2].lstrip('/').split('/', 1) target = urlunsplit(target) @@ -230,10 +232,15 @@ def get_duplicity_additional_args(env): ] elif get_target_type(config) == 's3': # See note about hostname in get_duplicity_target_url. + # The region name, which is required by some non-AWS endpoints, + # is saved inside the username portion of the URL. from urllib.parse import urlsplit, urlunsplit target = urlsplit(config["target"]) - endpoint_url = urlunsplit(("https", target.netloc, '', '', '')) - return ["--s3-endpoint-url", endpoint_url] + endpoint_url = urlunsplit(("https", target.hostname, '', '', '')) + args = ["--s3-endpoint-url", endpoint_url] + if target.username: # region name is stuffed here + args += ["--s3-region-name", target.username] + return args return [] diff --git a/management/templates/system-backup.html b/management/templates/system-backup.html index 422b2a0e..f7305518 100644 --- a/management/templates/system-backup.html +++ b/management/templates/system-backup.html @@ -5,7 +5,7 @@

Backup Status

-

The box makes an incremental backup each night. By default the backup is stored on the machine itself, but you can also store it on S3-compatible services like Amazon Web Services (AWS).

+

The box makes an incremental backup each night. You can store the backup on any Amazone Web Services S3-compatible service, or other options.

Configuration

@@ -70,7 +70,7 @@
Copy the Public SSH Key above, and paste it within the ~/.ssh/authorized_keys of target user on the backup server specified above. That way you'll enable secure and - passwordless authentication from your mail-in-a-box server and your backup server. + passwordless authentication from your Mail-in-a-Box server and your backup server.
@@ -98,13 +98,19 @@
- +
- +
- + +
+
+
+ +
+
@@ -272,12 +278,12 @@ function show_custom_backup() { $("#backup-target-rsync-host").val(spec.host); $("#backup-target-rsync-path").val(spec.path); } else if (r.target.substring(0, 5) == "s3://") { + const spec = url_split(r.target); $("#backup-target-type").val("s3"); - var hostpath = r.target.substring(5).split('/'); - var host = hostpath.shift(); - $("#backup-target-s3-host-select").val(host); - $("#backup-target-s3-host").val(host); - $("#backup-target-s3-path").val(hostpath.join('/')); + $("#backup-target-s3-host-select").val(spec.host); + $("#backup-target-s3-host").val(spec.host); + $("#backup-target-s3-region-name").val(spec.user); // stuffing the region name in the username + $("#backup-target-s3-path").val(spec.path); } else if (r.target.substring(0, 5) == "b2://") { $("#backup-target-type").val("b2"); var targetPath = r.target.substring(5); @@ -301,7 +307,10 @@ function set_custom_backup() { if (target_type == "local" || target_type == "off") target = target_type; else if (target_type == "s3") - target = "s3://" + $("#backup-target-s3-host").val() + "/" + $("#backup-target-s3-path").val(); + target = "s3://" + + ($("#backup-target-s3-region-name").val() ? ($("#backup-target-s3-region-name").val() + "@") : "") + + $("#backup-target-s3-host").val() + + "/" + $("#backup-target-s3-path").val(); else if (target_type == "rsync") { target = "rsync://" + $("#backup-target-rsync-user").val() + "@" + $("#backup-target-rsync-host").val() + "/" + $("#backup-target-rsync-path").val();