backups: Rename network_storage module to store

Same module is being used to store/retrieve local disk repositories also.

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-28 11:03:36 -07:00 committed by James Valleroy
parent 5df34d1927
commit 0df07f5cf2
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 62 additions and 51 deletions

View File

@ -32,7 +32,7 @@ from django.utils.translation import ugettext_lazy as _
from plinth.modules.storage import get_disks
from plinth.utils import format_lazy
from . import ROOT_REPOSITORY_NAME, api, network_storage, split_path
from . import ROOT_REPOSITORY_NAME, api, split_path, store
logger = logging.getLogger(__name__)
@ -54,7 +54,7 @@ def _get_app_choices(apps):
def _get_repository_choices():
"""Return the list of available repositories."""
choices = [('root', ROOT_REPOSITORY_NAME)]
storages = network_storage.get_storages()
storages = store.get_storages()
for storage in storages.values():
if storage.get('verified'):
choices += [(storage['uuid'], storage['path'])]
@ -204,7 +204,7 @@ class AddRemoteRepositoryForm(EncryptedBackupsMixin, forms.Form):
@staticmethod
def _check_if_duplicate_remote(path):
"""Raise validation error if given path is a stored remote."""
for storage in network_storage.get_storages().values():
for storage in store.get_storages().values():
if storage['path'] == path:
raise forms.ValidationError(
_('Remote backup repository already exists.'))

View File

@ -31,8 +31,8 @@ from plinth import actions
from plinth.errors import ActionError
from . import (ROOT_REPOSITORY, ROOT_REPOSITORY_NAME, ROOT_REPOSITORY_UUID,
_backup_handler, api, get_known_hosts_path, network_storage,
restore_archive_handler)
_backup_handler, api, get_known_hosts_path,
restore_archive_handler, store)
from .errors import BorgError, BorgRepositoryDoesNotExistError, SshfsError
logger = logging.getLogger(__name__)
@ -127,7 +127,7 @@ class BaseBorgRepository(abc.ABC):
return {}
def _load_from_kvstore(self):
storage = network_storage.get(self.uuid)
storage = store.get(self.uuid)
try:
self.credentials = storage['credentials']
except KeyError:
@ -269,7 +269,7 @@ class BaseBorgRepository(abc.ABC):
create_subvolume=False, backup_file=archive_path,
encryption_passphrase=passphrase)
def _get_network_storage_format(self, store_credentials, verified):
def _get_storage_format(self, store_credentials, verified):
storage = {
'path': self._path,
'storage_type': self.storage_type,
@ -287,8 +287,8 @@ class BaseBorgRepository(abc.ABC):
Save the repository in network_storage (kvstore).
- store_credentials: Boolean whether credentials should be stored.
"""
storage = self._get_network_storage_format(store_credentials, verified)
self.uuid = network_storage.update_or_add(storage)
storage = self._get_storage_format(store_credentials, verified)
self.uuid = store.update_or_add(storage)
class RootBorgRepository(BaseBorgRepository):
@ -327,7 +327,7 @@ class BorgRepository(BaseBorgRepository):
def remove_repository(self):
"""Remove a repository from the kvstore and delete its mountpoint"""
network_storage.delete(self.uuid)
store.delete(self.uuid)
class SshBorgRepository(BaseBorgRepository):
@ -382,7 +382,7 @@ class SshBorgRepository(BaseBorgRepository):
def remove_repository(self):
"""Remove a repository from the kvstore and delete its mountpoint"""
self.umount()
network_storage.delete(self.uuid)
store.delete(self.uuid)
try:
if os.path.exists(self.mountpoint):
try:
@ -411,7 +411,7 @@ class SshBorgRepository(BaseBorgRepository):
def get_repositories():
"""Get all repositories of a given storage type."""
repositories = [create_repository(ROOT_REPOSITORY_UUID)]
for uuid in network_storage.get_storages():
for uuid in store.get_storages():
repositories.append(create_repository(uuid))
return [
@ -425,8 +425,8 @@ def create_repository(uuid):
if uuid == ROOT_REPOSITORY_UUID:
return RootBorgRepository(path=ROOT_REPOSITORY)
storage = network_storage.get(uuid)
storage = store.get(uuid)
if storage['storage_type'] == 'ssh':
return SshBorgRepository(uuid=uuid)
else:
return BorgRepository(uuid=uuid)
return BorgRepository(uuid=uuid)

View File

@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Manage remote (network) storage storages in plinths' KVStore.
Manage storage of repository information in KVStore table in database.
"""
import json
@ -23,32 +23,39 @@ from uuid import uuid1
from plinth import kvstore
# kvstore key for network storage
NETWORK_STORAGE_KEY = 'network_storage'
# kvstore key for repository store
STORAGE_KEY = 'network_storage'
REQUIRED_FIELDS = ['path', 'storage_type', 'added_by_module']
def get_storages(storage_type=None):
"""Get network storages"""
storages = kvstore.get_default(NETWORK_STORAGE_KEY, {})
"""Get all repositories from store."""
storages = kvstore.get_default(STORAGE_KEY, {})
if storages:
storages = json.loads(storages)
if storage_type:
storages = {uuid: storage for uuid, storage in storages.items() if
storage['storage_type'] == storage_type}
storages = {
uuid: storage
for uuid, storage in storages.items()
if storage['storage_type'] == storage_type
}
return storages
def get(uuid):
"""Return a repository with given UUID from store."""
storages = get_storages()
return storages[uuid]
def update_or_add(storage):
"""Update an existing or create a new network storage"""
"""Update an existing or create a new repository in store."""
for field in REQUIRED_FIELDS:
if field not in storage:
raise ValueError('missing storage parameter: %s' % field)
existing_storages = get_storages()
if 'uuid' in storage:
# Replace the existing storage
@ -57,12 +64,13 @@ def update_or_add(storage):
uuid = str(uuid1())
storage['uuid'] = uuid
existing_storages[uuid] = storage
kvstore.set(NETWORK_STORAGE_KEY, json.dumps(existing_storages))
kvstore.set(STORAGE_KEY, json.dumps(existing_storages))
return storage['uuid']
def delete(uuid):
"""Remove a network storage from kvstore"""
"""Remove a repository from store."""
storages = get_storages()
del storages[uuid]
kvstore.set(NETWORK_STORAGE_KEY, json.dumps(storages))
kvstore.set(STORAGE_KEY, json.dumps(storages))

View File

@ -20,26 +20,29 @@ Test network storage.
import pytest
from plinth.modules.backups import network_storage
from plinth.modules.backups import store
pytestmark = pytest.mark.django_db
_storages = [{
'path': 'test@nonexistent.org:~/',
'storage_type': 'ssh',
'added_by_module': 'test'
}, {
'path': 'test@nonexistent.org:~/tmp/repo/',
'storage_type': 'ssh',
'added_by_module': 'test'
}]
_storages = [
{
'path': 'test@nonexistent.org:~/',
'storage_type': 'ssh',
'added_by_module': 'test'
},
{
'path': 'test@nonexistent.org:~/tmp/repo/',
'storage_type': 'ssh',
'added_by_module': 'test'
},
]
def test_add():
"""Add a storage item"""
storage = _storages[0]
uuid = network_storage.update_or_add(storage)
_storage = network_storage.get(uuid)
uuid = store.update_or_add(storage)
_storage = store.get(uuid)
assert _storage['path'] == storage['path']
@ -50,7 +53,7 @@ def test_add_invalid():
'added_by_module': 'test'
}
with pytest.raises(ValueError):
network_storage.update_or_add(storage_with_missing_type)
store.update_or_add(storage_with_missing_type)
def test_remove():
@ -58,12 +61,12 @@ def test_remove():
storage = _storages[0]
uuid = None
for storage in _storages:
uuid = network_storage.update_or_add(storage)
uuid = store.update_or_add(storage)
storages = network_storage.get_storages()
storages = store.get_storages()
assert len(storages) == 2
network_storage.delete(uuid)
storages = network_storage.get_storages()
store.delete(uuid)
storages = store.get_storages()
assert len(storages) == 1
@ -71,11 +74,11 @@ def test_update():
"""Update existing storage items"""
uuid = None
for storage in _storages:
uuid = network_storage.update_or_add(storage)
uuid = store.update_or_add(storage)
storage = network_storage.get(uuid)
storage = store.get(uuid)
new_path = 'test@nonexistent.org:~/tmp/repo_new/'
storage['path'] = new_path
network_storage.update_or_add(storage)
_storage = network_storage.get(uuid)
store.update_or_add(storage)
_storage = store.get(uuid)
assert _storage['path'] == new_path

View File

@ -39,7 +39,7 @@ from plinth.errors import PlinthError
from plinth.modules import backups, storage
from . import (SESSION_PATH_VARIABLE, api, forms,
get_known_hosts_path, is_ssh_hostkey_verified, network_storage,
get_known_hosts_path, is_ssh_hostkey_verified, store,
split_path)
from .decorators import delete_tmp_backup_file
from .errors import BorgRepositoryDoesNotExistError
@ -329,7 +329,7 @@ class VerifySshHostkeyView(SuccessMessageMixin, FormView):
"""Fetch the repository data from DB only once."""
if not self.repo_data:
uuid = self.kwargs['uuid']
self.repo_data = network_storage.get(uuid)
self.repo_data = store.get(uuid)
return self.repo_data
@ -404,7 +404,7 @@ class VerifySshHostkeyView(SuccessMessageMixin, FormView):
messages.error(self.request, _('Repository removed.'))
# Delete the repository so that the user can have another go at
# creating it.
network_storage.delete(uuid)
store.delete(uuid)
return redirect(reverse_lazy('backups:add-remote-repository'))
@ -494,7 +494,7 @@ def umount_repository(request, uuid):
def mount_repository(request, uuid):
"""View to mount a remote SSH repository."""
# Do not mount unverified ssh repositories. Prompt for verification.
if not network_storage.get(uuid).get('verified'):
if not store.get(uuid).get('verified'):
return redirect('backups:verify-ssh-hostkey', uuid=uuid)
repository = SshBorgRepository(uuid=uuid)