From 6651c0468ed683c6648627d8bb1ac00fb866f02f Mon Sep 17 00:00:00 2001 From: Michael Pimmer Date: Sat, 1 Dec 2018 03:06:06 +0000 Subject: [PATCH] Backups: remove archive name when creating an archive - use datetime as archive name w/o asking user - updated functional tests Reviewed-by: James Valleroy --- functional_tests/config.ini | 1 + .../step_definitions/application.py | 4 ++-- functional_tests/step_definitions/system.py | 4 +++- functional_tests/support/system.py | 22 ++++++++++++------- plinth/modules/backups/forms.py | 18 +-------------- plinth/modules/backups/repository.py | 6 +++++ plinth/modules/backups/views.py | 14 +++--------- 7 files changed, 30 insertions(+), 39 deletions(-) diff --git a/functional_tests/config.ini b/functional_tests/config.ini index 047801387..77313c4e2 100644 --- a/functional_tests/config.ini +++ b/functional_tests/config.ini @@ -2,3 +2,4 @@ url = https://localhost:4430 username = tester password = testingtesting +delete_root_backup_archives = true diff --git a/functional_tests/step_definitions/application.py b/functional_tests/step_definitions/application.py index 417226953..49c1f82c5 100644 --- a/functional_tests/step_definitions/application.py +++ b/functional_tests/step_definitions/application.py @@ -221,12 +221,12 @@ def set_mediawiki_admin_password(browser, password): @when(parsers.parse('I enable message archive management')) -def set_mediawiki_admin_password(browser): +def mediawiki_enable_archive_management(browser): application.enable_ejabberd_message_archive_management(browser) @when(parsers.parse('I disable message archive management')) -def set_mediawiki_admin_password(browser): +def mediawiki_disable_archive_management(browser): application.disable_ejabberd_message_archive_management(browser) diff --git a/functional_tests/step_definitions/system.py b/functional_tests/step_definitions/system.py index 4142deba0..cc4405334 100644 --- a/functional_tests/step_definitions/system.py +++ b/functional_tests/step_definitions/system.py @@ -21,7 +21,7 @@ import time from pytest import fixture from pytest_bdd import given, parsers, then, when -from support import system +from support import config, system language_codes = { 'Deutsch': 'de', @@ -178,6 +178,8 @@ def dynamicdns_has_original_config(browser): @when(parsers.parse('I create a backup of the {app_name:w} app data')) def backup_create(browser, app_name): + if config.getboolean('DEFAULT', 'delete_root_backup_archives'): + system.backup_delete_root_archives(browser) system.backup_create(browser, app_name) diff --git a/functional_tests/support/system.py b/functional_tests/support/system.py index 6576a8c16..0cb4bbd38 100644 --- a/functional_tests/support/system.py +++ b/functional_tests/support/system.py @@ -187,14 +187,20 @@ def dynamicdns_change_config(browser): submit(browser) +def backup_delete_root_archives(browser): + """Delete all archives of the root borg repository""" + browser.visit(default_url + '/plinth/sys/backups/') + path = "//a[starts-with(@href,'/plinth/sys/backups/delete/root/')]" + while browser.find_by_xpath(path): + browser.find_by_xpath(path).first.click() + with wait_for_page_update(browser, + expected_url='/plinth/sys/backups/'): + submit(browser) + + def backup_create(browser, app_name): browser.visit(default_url) application.install(browser, 'backups') - delete = browser.find_link_by_href( - '/plinth/sys/backups/delete/root/_functional_test_' + app_name + '/') - if delete: - delete.first.click() - submit(browser) browser.find_link_by_href('/plinth/sys/backups/create/').first.click() browser.find_by_id('id_backups-name').fill('_functional_test_' + app_name) @@ -210,9 +216,9 @@ def backup_create(browser, app_name): def backup_restore(browser, app_name): browser.visit(default_url) nav_to_module(browser, 'backups') - browser.find_link_by_href( - '/plinth/sys/backups/restore-archive/root/_functional_test_' + - app_name + '/').first.click() + path = "//a[starts-with(@href,'/plinth/sys/backups/restore-archive/root/')]" + # assume that want to restore the last (most recently created) backup + browser.find_by_xpath(path).last.click() with wait_for_page_update(browser, expected_url='/plinth/sys/backups/'): submit(browser) diff --git a/plinth/modules/backups/forms.py b/plinth/modules/backups/forms.py index f58a224f4..f5c5b0c9f 100644 --- a/plinth/modules/backups/forms.py +++ b/plinth/modules/backups/forms.py @@ -19,12 +19,10 @@ Forms for backups module. """ from django import forms -from django.core import validators from django.core.validators import FileExtensionValidator from django.utils.translation import ugettext, ugettext_lazy as _ from plinth.utils import format_lazy -from plinth import cfg from . import api, network_storage, ROOT_REPOSITORY_NAME @@ -54,12 +52,6 @@ def _get_repository_choices(): class CreateArchiveForm(forms.Form): repository = forms.ChoiceField() - name = forms.CharField( - label=_('Archive name'), strip=True, - help_text=_('Name for new backup archive.'), validators=[ - validators.RegexValidator(r'^[^/]+$', _('Invalid archive name')) - ]) - selected_apps = forms.MultipleChoiceField( label=_('Included apps'), help_text=_('Apps to include in the backup'), widget=forms.CheckboxSelectMultiple) @@ -98,7 +90,7 @@ class UploadForm(forms.Form): class AddRepositoryForm(forms.Form): repository = forms.CharField( label=_('SSH Repository Path'), strip=True, - help_text=_('Path of the new repository. Example: ' + help_text=_('Path of a new or existing repository. Example: ' 'user@host:~/path/to/repo/')) ssh_password = forms.CharField( label=_('SSH server password'), strip=True, @@ -126,14 +118,6 @@ class AddRepositoryForm(forms.Form): widget=forms.PasswordInput(), required=False ) - store_credentials = forms.BooleanField( - label=_('Store passwords on FreedomBox'), - help_text=format_lazy( - _('Store the passwords on your {box_name}.' - '
You need to store passwords if you want to run ' - 'recurrent backups.'), box_name=_(cfg.box_name)), - required=False - ) def clean(self): cleaned_data = super(AddRepositoryForm, self).clean() diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py index 997618281..a4ac753c3 100644 --- a/plinth/modules/backups/repository.py +++ b/plinth/modules/backups/repository.py @@ -233,12 +233,17 @@ class SshBorgRepository(BorgRepository): return storage def create_repository(self, encryption): + """Initialize / create a borg repository.""" if encryption not in SUPPORTED_BORG_ENCRYPTION: raise ValueError('Unsupported encryption: %s' % encryption) self._run('backups', ['init', '--path', self.path, '--encryption', encryption]) def save(self, store_credentials=True): + """ + Save the repository in network_storage (kvstore). + - store_credentials: Boolean whether credentials should be stored. + """ storage = self._get_network_storage_format(store_credentials) self.uuid = network_storage.update_or_add(storage) @@ -314,6 +319,7 @@ def get_ssh_repositories(): def get_repository(uuid): + """Get a repository (BorgRepository or SshBorgRepository)""" if uuid == ROOT_REPOSITORY_UUID: return BorgRepository(path=ROOT_REPOSITORY) else: diff --git a/plinth/modules/backups/views.py b/plinth/modules/backups/views.py index 443afd4b4..19a519a3e 100644 --- a/plinth/modules/backups/views.py +++ b/plinth/modules/backups/views.py @@ -90,18 +90,11 @@ class CreateArchiveView(SuccessMessageMixin, FormView): context['subsubmenu'] = subsubmenu return context - def get_initial(self): - """Return the initial data to use for forms on this view.""" - initial = super().get_initial() - initial['name'] = 'FreedomBox_backup_' + datetime.now().strftime( - '%Y-%m-%d:%H:%M') - return initial - def form_valid(self, form): """Create the archive on valid form submission.""" repository = get_repository(form.cleaned_data['repository']) - repository.create_archive(form.cleaned_data['name'], - form.cleaned_data['selected_apps']) + name = datetime.now().strftime('%Y-%m-%d:%H:%M') + repository.create_archive(name, form.cleaned_data['selected_apps']) return super().form_valid(form) @@ -293,8 +286,7 @@ class AddRepositoryView(SuccessMessageMixin, FormView): repository.get_info() except BorgRepositoryDoesNotExistError: repository.create_repository(form.cleaned_data['encryption']) - repository.save( - store_credentials=form.cleaned_data['store_credentials']) + repository.save(store_credentials=True) return super().form_valid(form)