backups: Simplify checking repository capabilities using flags

Also make storage_type an abstract property so that derived classes are forced
to override it.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2019-08-27 23:42:16 -07:00 committed by James Valleroy
parent 5136304212
commit b5d7a910dd
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
4 changed files with 23 additions and 16 deletions

View File

@ -18,11 +18,11 @@
Remote and local Borg backup repositories Remote and local Borg backup repositories
""" """
import abc
import io import io
import json import json
import logging import logging
import os import os
from abc import ABC
from uuid import uuid1 from uuid import uuid1
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -78,9 +78,10 @@ KNOWN_ERRORS = [{
}] }]
class BaseBorgRepository(ABC): class BaseBorgRepository(abc.ABC):
"""Base class for all kinds of Borg repositories.""" """Base class for all kinds of Borg repositories."""
uuid = None uuid = None
flags = {}
is_mounted = True is_mounted = True
def __init__(self, uuid=None, path=None, credentials=None, **kwargs): def __init__(self, uuid=None, path=None, credentials=None, **kwargs):
@ -107,6 +108,11 @@ class BaseBorgRepository(ABC):
def name(self): def name(self):
return self._path return self._path
@abc.abstractmethod
def storage_type(self):
"""Return the storage type of repository."""
raise NotImplementedError
@property @property
def repo_path(self): def repo_path(self):
"""Return the repository that the backups action script should use.""" """Return the repository that the backups action script should use."""
@ -137,17 +143,17 @@ class BaseBorgRepository(ABC):
"""Get archives with additional information as needed by the view""" """Get archives with additional information as needed by the view"""
repository = { repository = {
'name': self.name, 'name': self.name,
'type': self.storage_type, 'storage_type': self.storage_type,
'error': '' 'flags': self.flags,
'error': None,
} }
try: try:
error = ''
repository['mounted'] = self.is_mounted repository['mounted'] = self.is_mounted
if repository['mounted']: if repository['mounted']:
repository['archives'] = self.list_archives() repository['archives'] = self.list_archives()
except (BorgError, ActionError) as err: except (BorgError, ActionError) as err:
error = str(err) repository['error'] = str(err)
repository['error'] = error
return repository return repository
def remove_repository(self): def remove_repository(self):
@ -308,6 +314,7 @@ class BorgRepository(BaseBorgRepository):
"""General Borg repository implementation.""" """General Borg repository implementation."""
KNOWN_CREDENTIALS = ['encryption_passphrase'] KNOWN_CREDENTIALS = ['encryption_passphrase']
storage_type = 'disk' storage_type = 'disk'
flags = {'removable': True}
@property @property
def name(self): def name(self):
@ -327,6 +334,7 @@ class SshBorgRepository(BaseBorgRepository):
'ssh_keyfile', 'ssh_password', 'encryption_passphrase' 'ssh_keyfile', 'ssh_password', 'encryption_passphrase'
] ]
storage_type = 'ssh' storage_type = 'ssh'
flags = {'removable': True, 'mountable': True}
@property @property
def repo_path(self): def repo_path(self):

View File

@ -60,14 +60,14 @@
<h3>{% trans 'Existing Backups' %}</h3> <h3>{% trans 'Existing Backups' %}</h3>
{% include "backups_repository.inc" with repository=root_repository uuid='root' storage_type='root' editable=False %} {% include "backups_repository.inc" with repository=root_repository uuid='root' %}
{% for uuid,repository in ssh_repositories.items %} {% for uuid,repository in ssh_repositories.items %}
{% include "backups_repository.inc" with editable=True storage_type='ssh' %} {% include "backups_repository.inc" %}
{% endfor %} {% endfor %}
{% for uuid,repository in disk_repositories.items %} {% for uuid,repository in disk_repositories.items %}
{% include "backups_repository.inc" with editable=True storage_type='disk' %} {% include "backups_repository.inc" %}
{% endfor %} {% endfor %}
<a title="{% trans 'Add a backup location' %}" <a title="{% trans 'Add a backup location' %}"

View File

@ -34,14 +34,10 @@
{{ repository.name }} {{ repository.name }}
<span class="pull-right"> <span class="pull-right">
{% if editable %} {% if repository.flags.mountable %}
{% if storage_type != 'disk' %}
{% if repository.mounted %} {% if repository.mounted %}
<!-- With GET redirects, the browser URL points to the
redirected page (bad when reloading) - use POST instead.
-->
<form action="{% url 'backups:repository-umount' uuid %}" method="POST" <form action="{% url 'backups:repository-umount' uuid %}" method="POST"
class="inline-block" > class="inline-block" >
{% csrf_token %} {% csrf_token %}
@ -63,8 +59,11 @@
</form> </form>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if repository.flags.removable %}
<a title="{% trans 'Remove Backup Location. This will not delete the remote backup.' %}" <a title="{% trans 'Remove Backup Location. This will not delete the remote backup.' %}"
role="button" class="repository-remove btn btn-sm btn-default" role="button" class="repository-remove btn btn-sm btn-default"
href="{% url 'backups:repository-remove' uuid %}"> href="{% url 'backups:repository-remove' uuid %}">

View File

@ -84,7 +84,7 @@ class CreateArchiveView(SuccessMessageMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
"""Create the archive on valid form submission.""" """Create the archive on valid form submission."""
repository = create_repository(form.cleaned_data['repository']) repository = create_repository(form.cleaned_data['repository'])
if hasattr(repository, 'mount'): if repository.flags.get('mountable'):
repository.mount() repository.mount()
name = datetime.now().strftime('%Y-%m-%d:%H:%M') name = datetime.now().strftime('%Y-%m-%d:%H:%M')