mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-26 12:46:08 +00:00
backups: When restoring, only list apps included in backup
Signed-off-by: James Valleroy <jvalleroy@mailbox.org> Reviewed-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
This commit is contained in:
parent
2a9a220770
commit
481a299250
@ -25,6 +25,7 @@ import glob
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import tarfile
|
||||||
|
|
||||||
REPOSITORY = '/var/lib/freedombox/borgbackup'
|
REPOSITORY = '/var/lib/freedombox/borgbackup'
|
||||||
|
|
||||||
@ -62,6 +63,12 @@ def parse_arguments():
|
|||||||
list_exports.add_argument('--location', required=True,
|
list_exports.add_argument('--location', required=True,
|
||||||
help='location to check')
|
help='location to check')
|
||||||
|
|
||||||
|
get_export_apps = subparsers.add_parser(
|
||||||
|
'get-export-apps',
|
||||||
|
help='Get list of apps included in exported archive file')
|
||||||
|
get_export_apps.add_argument(
|
||||||
|
'--filename', help='Tarball file name', required=True)
|
||||||
|
|
||||||
restore = subparsers.add_parser(
|
restore = subparsers.add_parser(
|
||||||
'restore', help='Restore files from an exported archive')
|
'restore', help='Restore files from an exported archive')
|
||||||
restore.add_argument('--filename', help='Tarball file name', required=True)
|
restore.add_argument('--filename', help='Tarball file name', required=True)
|
||||||
@ -144,6 +151,23 @@ def subcommand_list_exports(arguments):
|
|||||||
print(json.dumps(exports))
|
print(json.dumps(exports))
|
||||||
|
|
||||||
|
|
||||||
|
def subcommand_get_export_apps(arguments):
|
||||||
|
"""Get list of apps included in exported archive file."""
|
||||||
|
manifest = None
|
||||||
|
with tarfile.open(arguments.filename) as t:
|
||||||
|
filenames = t.getnames()
|
||||||
|
for name in filenames:
|
||||||
|
if 'var/lib/plinth/backups-manifests/' in name \
|
||||||
|
and name.endswith('.json'):
|
||||||
|
manifest_data = t.extractfile(name).read()
|
||||||
|
manifest = json.loads(manifest_data)
|
||||||
|
break
|
||||||
|
|
||||||
|
if manifest:
|
||||||
|
for app in manifest:
|
||||||
|
print(app['name'])
|
||||||
|
|
||||||
|
|
||||||
def subcommand_restore(arguments):
|
def subcommand_restore(arguments):
|
||||||
"""Restore files from an exported archive."""
|
"""Restore files from an exported archive."""
|
||||||
prev_dir = os.getcwd()
|
prev_dir = os.getcwd()
|
||||||
|
|||||||
@ -140,7 +140,7 @@ def get_export_files():
|
|||||||
return export_files
|
return export_files
|
||||||
|
|
||||||
|
|
||||||
def _find_exported_archive(disk_label, archive_name):
|
def find_exported_archive(disk_label, archive_name):
|
||||||
"""Return the full path for the exported archive file."""
|
"""Return the full path for the exported archive file."""
|
||||||
path = None
|
path = None
|
||||||
locations = get_export_locations()
|
locations = get_export_locations()
|
||||||
@ -155,9 +155,16 @@ def _find_exported_archive(disk_label, archive_name):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def get_export_apps(filename):
|
||||||
|
"""Get list of apps included in exported archive file."""
|
||||||
|
output = actions.superuser_run(
|
||||||
|
'backups', ['get-export-apps', '--filename', filename])
|
||||||
|
return output.splitlines()
|
||||||
|
|
||||||
|
|
||||||
def restore_exported(label, name, apps=None):
|
def restore_exported(label, name, apps=None):
|
||||||
"""Restore files from exported backup archive."""
|
"""Restore files from exported backup archive."""
|
||||||
filename = _find_exported_archive(label, name)
|
filename = find_exported_archive(label, name)
|
||||||
if filename:
|
if filename:
|
||||||
# TODO: Use backups API.
|
# TODO: Use backups API.
|
||||||
actions.superuser_run(
|
actions.superuser_run(
|
||||||
|
|||||||
@ -67,9 +67,8 @@ class RestoreForm(forms.Form):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize the form with selectable apps."""
|
"""Initialize the form with selectable apps."""
|
||||||
|
apps = kwargs.pop('apps')
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
apps = _list_of_all_apps_for_backup()
|
|
||||||
# TODO: Only list apps included in the backup file.
|
|
||||||
self.fields['selected_apps'].choices = [
|
self.fields['selected_apps'].choices = [
|
||||||
(app[0], app[1].name) for app in apps]
|
(app[0], app[1].name) for app in apps]
|
||||||
self.fields['selected_apps'].initial = [app[0] for app in apps]
|
self.fields['selected_apps'].initial = [app[0] for app in apps]
|
||||||
|
|||||||
@ -30,6 +30,7 @@ from django.views.generic import FormView, TemplateView
|
|||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from plinth.modules import backups
|
from plinth.modules import backups
|
||||||
|
from . import find_exported_archive, get_export_apps
|
||||||
from .backups import _list_of_all_apps_for_backup
|
from .backups import _list_of_all_apps_for_backup
|
||||||
from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm
|
from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm
|
||||||
|
|
||||||
@ -133,6 +134,31 @@ class RestoreView(SuccessMessageMixin, FormView):
|
|||||||
success_url = reverse_lazy('backups:index')
|
success_url = reverse_lazy('backups:index')
|
||||||
success_message = _('Restored files from backup.')
|
success_message = _('Restored files from backup.')
|
||||||
|
|
||||||
|
def collect_data(self, label, name):
|
||||||
|
"""Save some data used to instantiate the form."""
|
||||||
|
self.label = unquote(label)
|
||||||
|
self.name = unquote(name)
|
||||||
|
self.filename = find_exported_archive(self.label, self.name)
|
||||||
|
self.installed_apps = _list_of_all_apps_for_backup()
|
||||||
|
self.included_apps = get_export_apps(self.filename)
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
"""Save request parameters for later."""
|
||||||
|
self.collect_data(kwargs['label'], kwargs['name'])
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
"""Save request parameters for later."""
|
||||||
|
self.collect_data(kwargs['label'], kwargs['name'])
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
"""Pass additional keyword args for instantiating the form."""
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs['apps'] = [
|
||||||
|
x for x in self.installed_apps if x[0] in self.included_apps]
|
||||||
|
return kwargs
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
"""Return additional context for rendering the template."""
|
"""Return additional context for rendering the template."""
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user