Allow setting the S3 region name in backup settings to pass to duplicity

It's stuffed inside the username portion of the target URL. We already mangle the target before passing it to duplicity so there wasn't a need for a new field.

Fixes the issue raised in #2200, #2216.
pull/2260/head
Joshua Tauberer 1 year ago
parent e828d63a85
commit 51ed030917
  1. 1
      CHANGELOG.md
  2. 13
      management/backup.py
  3. 31
      management/templates/system-backup.html

@ -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.

@ -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 []

@ -5,7 +5,7 @@
<h2>Backup Status</h2>
<p>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).</p>
<p>The box makes an incremental backup each night. You can store the backup on any Amazone Web Services S3-compatible service, or other options.</p>
<h3>Configuration</h3>
@ -70,7 +70,7 @@
<div class="small" style="margin-top: 2px">
Copy the Public SSH Key above, and paste it within the <tt>~/.ssh/authorized_keys</tt>
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.
</div>
</div>
<div id="copy_pub_key_div" class="col-sm">
@ -98,13 +98,19 @@
<div class="form-group backup-target-s3">
<label for="backup-target-s3-host" class="col-sm-2 control-label">S3 Host / Endpoint</label>
<div class="col-sm-8">
<input type="text" placeholder="Endpoint" class="form-control" rows="1" id="backup-target-s3-host">
<input type="text" placeholder="https://s3.backuphost.com" class="form-control" rows="1" id="backup-target-s3-host">
</div>
</div>
<div class="form-group backup-target-s3">
<label for="backup-target-s3-path" class="col-sm-2 control-label">S3 Path</label>
<label for="backup-target-s3-region-name" class="col-sm-2 control-label">S3 Region Name <span style="font-weight: normal">(if required)</span></label>
<div class="col-sm-8">
<input type="text" placeholder="your-bucket-name/backup-directory" class="form-control" rows="1" id="backup-target-s3-path">
<input type="text" placeholder="region.name" class="form-control" rows="1" id="backup-target-s3-region-name">
</div>
</div>
<div class="form-group backup-target-s3">
<label for="backup-target-s3-path" class="col-sm-2 control-label">S3 Bucket &amp; Path</label>
<div class="col-sm-8">
<input type="text" placeholder="bucket-name/backup-directory" class="form-control" rows="1" id="backup-target-s3-path">
</div>
</div>
<div class="form-group backup-target-s3">
@ -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();

Loading…
Cancel
Save