From ab9f9610913c72af3df887058ef729dba9e150b3 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Tue, 14 Aug 2018 18:41:59 -0400 Subject: [PATCH] backups: Simplify export of backup archive files - Allow selection of Root Filesystem or any removable drive. - Export to FreedomBox-backups folder in selection location. - Handle export location without / at the end Signed-off-by: James Valleroy Reviewed-by: Joseph Nuthalapati --- actions/backups | 4 ++++ plinth/modules/backups/__init__.py | 19 ++++++++++++++++++- plinth/modules/backups/forms.py | 14 +++++++++++--- plinth/modules/backups/views.py | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/actions/backups b/actions/backups index 2c7c0fbc7..252552215 100755 --- a/actions/backups +++ b/actions/backups @@ -104,6 +104,10 @@ def subcommand_extract(arguments): def subcommand_export(arguments): """Export archive contents as tarball.""" + path = os.path.dirname(arguments.filename) + if not os.path.exists(path): + os.makedirs(path) + subprocess.run([ 'borg', 'export-tar', REPOSITORY + '::' + arguments.name, arguments.filename diff --git a/plinth/modules/backups/__init__.py b/plinth/modules/backups/__init__.py index dae7dd23f..83ddb059f 100644 --- a/plinth/modules/backups/__init__.py +++ b/plinth/modules/backups/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth.menu import main_menu +from plinth.modules import udiskie version = 1 @@ -80,6 +81,22 @@ def extract_archive(name, destination): 'backups', ['extract', '--name', name, '--destination', destination]) -def export_archive(name, filename): +def export_archive(name, location): + if location[-1] != '/': + location += '/' + filename = location + 'FreedomBox-backups/' + name + '.tar.gz' actions.superuser_run('backups', ['export', '--name', name, '--filename', filename]) + + +def get_export_locations(): + """Return a list of storage locations for exported backup archives.""" + locations = [('/var/lib/freedombox/', _('Root Filesystem'))] + if udiskie.is_running(): + devices = udiskie.udisks2.list_devices() + for device in devices: + if 'mount_points' in device and len(device['mount_points']) > 0: + name = device['label'] or device['device'] + locations.append((device['mount_points'][0], name)) + + return locations diff --git a/plinth/modules/backups/forms.py b/plinth/modules/backups/forms.py index 88f65d86e..d8ec95b9c 100644 --- a/plinth/modules/backups/forms.py +++ b/plinth/modules/backups/forms.py @@ -22,6 +22,8 @@ from django import forms from django.core import validators from django.utils.translation import ugettext_lazy as _ +from . import get_export_locations + class CreateArchiveForm(forms.Form): name = forms.CharField( @@ -42,6 +44,12 @@ class ExtractArchiveForm(forms.Form): class ExportArchiveForm(forms.Form): - filename = forms.CharField( - label=_('Exported filename'), strip=True, - help_text=_('Name for the tar file exported from the archive.')) + disk = forms.ChoiceField( + label=_('Disk'), widget=forms.RadioSelect(), + help_text=_('Disk or removable storage where the backup archive will ' + 'be saved.')) + + def __init__(self, *args, **kwargs): + """Initialize the form with disk choices.""" + super().__init__(*args, **kwargs) + self.fields['disk'].choices = get_export_locations() diff --git a/plinth/modules/backups/views.py b/plinth/modules/backups/views.py index 673c52596..8ed56ca0a 100644 --- a/plinth/modules/backups/views.py +++ b/plinth/modules/backups/views.py @@ -132,5 +132,5 @@ class ExportArchiveView(SuccessMessageMixin, FormView): def form_valid(self, form): """Create the archive on valid form submission.""" backups.export_archive(self.kwargs['name'], - form.cleaned_data['filename']) + form.cleaned_data['disk']) return super().form_valid(form)