diff --git a/actions/backups b/actions/backups index 1a37e213c..c80719127 100755 --- a/actions/backups +++ b/actions/backups @@ -45,7 +45,7 @@ def parse_arguments(): 'setup', help='Create repository if it does not already exist') init = subparsers.add_parser('init', help='Initialize a repository') - init.add_argument('--encryption', help='Enryption of the repository', + init.add_argument('--encryption', help='Encryption of the repository', required=True) info = subparsers.add_parser('info', help='Show repository information') @@ -151,7 +151,6 @@ def _extract(archive_path, destination, locations=None, env=None): """Extract archive contents.""" if not env: env = dict(os.environ) - # TODO: is LANG necessary? env['LANG'] = 'C.UTF-8' prev_dir = os.getcwd() diff --git a/actions/sshfs b/actions/sshfs index c0a4771a4..11077b584 100755 --- a/actions/sshfs +++ b/actions/sshfs @@ -48,8 +48,8 @@ def parse_arguments(): help='unmount an ssh filesystem') umount.add_argument('--mountpoint', help='Mountpoint to unmount', required=True) - is_mounted = subparsers.add_parser('is-mounted', - help='Check whether an sshfs is mouned') + is_mounted = subparsers.add_parser( + 'is-mounted', help='Check whether a mountpoint is mounted') is_mounted.add_argument('--mountpoint', help='Mountpoint to check', required=True) @@ -83,7 +83,7 @@ def subcommand_mount(arguments): def subcommand_umount(arguments): - """Show repository information.""" + """Unmount a mountpoint.""" run(['umount', arguments.mountpoint]) diff --git a/plinth/modules/backups/errors.py b/plinth/modules/backups/errors.py index e7d88d4cd..e7e13b534 100644 --- a/plinth/modules/backups/errors.py +++ b/plinth/modules/backups/errors.py @@ -26,3 +26,8 @@ class BorgError(PlinthError): class BorgRepositoryDoesNotExistError(BorgError): """Borg access to a repository works but the repository does not exist""" pass + + +class SshfsError(PlinthError): + """Generic sshfs errors""" + pass diff --git a/plinth/modules/backups/forms.py b/plinth/modules/backups/forms.py index b38030648..d4d2205c1 100644 --- a/plinth/modules/backups/forms.py +++ b/plinth/modules/backups/forms.py @@ -142,8 +142,9 @@ class AddRepositoryForm(forms.Form): path = cleaned_data.get("repository") credentials = self.get_credentials() - self.repository = SshBorgRepository(path=path, credentials=credentials) try: + self.repository = SshBorgRepository(path=path, + credentials=credentials) self.repository.get_info() except BorgRepositoryDoesNotExistError: pass diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py index f139c9c3d..861df2784 100644 --- a/plinth/modules/backups/repository.py +++ b/plinth/modules/backups/repository.py @@ -21,6 +21,7 @@ Remote and local Borg backup repositories import json import logging import os +from uuid import uuid1 from django.utils.translation import ugettext_lazy as _ @@ -30,7 +31,7 @@ from plinth.errors import ActionError from . import api, network_storage, _backup_handler, ROOT_REPOSITORY_NAME, \ ROOT_REPOSITORY_UUID, ROOT_REPOSITORY, restore_archive_handler, \ zipstream -from .errors import BorgError, BorgRepositoryDoesNotExistError +from .errors import BorgError, BorgRepositoryDoesNotExistError, SshfsError logger = logging.getLogger(__name__) @@ -53,6 +54,17 @@ KNOWN_ERRORS = [{ "errors": ["not a valid repository", "does not exist"], "message": _("Repository not found"), "raise_as": BorgRepositoryDoesNotExistError, + }, + { + "errors": [("passphrase supplied in BORG_PASSPHRASE or by " + "BORG_PASSCOMMAND is incorrect")], + "message": _("Incorrect encryption passphrase"), + "raise_as": BorgError, + }, + { + "errors": [("Connection reset by peer")], + "message": _("SSH access denied"), + "raise_as": SshfsError, }] @@ -192,23 +204,23 @@ class SshBorgRepository(BorgRepository): Provide a uuid to instanciate an existing repository, or 'ssh_path' and 'credentials' for a new repository. """ - if uuid: - self.uuid = uuid - # If all data are given, instanciate right away. - if path and credentials: - self._path = path - self.credentials = credentials - else: - self._load_from_kvstore() - # No uuid given: new instance. - elif path and credentials: + is_new_instance = not bool(uuid) + if not uuid: + uuid = str(uuid1()) + self.uuid = uuid + + if path and credentials: self._path = path self.credentials = credentials else: - raise ValueError('Invalid arguments.') + if is_new_instance: + # Either a uuid, or both a path and credentials must be given + raise ValueError('Invalid arguments.') + else: + self._load_from_kvstore() + if automount: - if self.uuid and not self.is_mounted: - self.mount() + self.mount() @property def repo_path(self): @@ -273,6 +285,9 @@ class SshBorgRepository(BorgRepository): self.uuid = network_storage.update_or_add(storage) def mount(self): + if self.is_mounted: + return + arguments = ['mount', '--mountpoint', self.mountpoint, '--path', self._path] arguments, kwargs = self._append_sshfs_arguments(arguments, @@ -280,6 +295,8 @@ class SshBorgRepository(BorgRepository): self._run('sshfs', arguments, kwargs=kwargs) def umount(self): + if not self.is_mounted: + return self._run('sshfs', ['umount', '--mountpoint', self.mountpoint]) def remove_repository(self): diff --git a/plinth/modules/backups/templates/backups_repository_add.html b/plinth/modules/backups/templates/backups_repository_add.html index e5c31adcb..db2977294 100644 --- a/plinth/modules/backups/templates/backups_repository_add.html +++ b/plinth/modules/backups/templates/backups_repository_add.html @@ -31,10 +31,11 @@ {{ form|bootstrap }} - + value="{% trans "Create Repository" %}"/> + + {% trans "Abort" %} + {% endblock %} diff --git a/plinth/modules/backups/templates/backups_repository_remove.html b/plinth/modules/backups/templates/backups_repository_remove.html index 6513f1cb2..8329a328e 100644 --- a/plinth/modules/backups/templates/backups_repository_remove.html +++ b/plinth/modules/backups/templates/backups_repository_remove.html @@ -25,11 +25,12 @@
- {% trans "Are you sure that you want to remove the repository" %}
-
- {{ repository.path }}?
-
+ {% trans "Are you sure that you want to remove this repository?" %}
+ {{ repository.name }} +
+