Commit cf23f6b1 authored by James Valleroy's avatar James Valleroy

backups: When restoring, only list apps included in backup

Signed-off-by: James Valleroy's avatarJames Valleroy <>
parent fc70329d
......@@ -25,6 +25,7 @@ import glob
import json
import os
import subprocess
import tarfile
REPOSITORY = '/var/lib/freedombox/borgbackup'
......@@ -62,6 +63,12 @@ def parse_arguments():
list_exports.add_argument('--location', required=True,
help='location to check')
get_export_apps = subparsers.add_parser(
help='Get list of apps included in exported archive file')
'--filename', help='Tarball file name', required=True)
restore = subparsers.add_parser(
'restore', help='Restore files from an exported archive')
restore.add_argument('--filename', help='Tarball file name', required=True)
......@@ -144,6 +151,23 @@ def subcommand_list_exports(arguments):
def subcommand_get_export_apps(arguments):
"""Get list of apps included in exported archive file."""
manifest = None
with 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)
if manifest:
for app in manifest:
def subcommand_restore(arguments):
"""Restore files from an exported archive."""
prev_dir = os.getcwd()
......@@ -140,7 +140,7 @@ def get_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."""
path = None
locations = get_export_locations()
......@@ -155,9 +155,16 @@ def _find_exported_archive(disk_label, archive_name):
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):
"""Restore files from exported backup archive."""
filename = _find_exported_archive(label, name)
filename = find_exported_archive(label, name)
if filename:
# TODO: Use backups API.
......@@ -67,9 +67,8 @@ class RestoreForm(forms.Form):
def __init__(self, *args, **kwargs):
"""Initialize the form with selectable apps."""
apps = kwargs.pop('apps')
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 = [
(app[0], app[1].name) 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 plinth.modules import backups
from . import find_exported_archive, get_export_apps
from .backups import _list_of_all_apps_for_backup
from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm
......@@ -133,6 +134,31 @@ class RestoreView(SuccessMessageMixin, FormView):
success_url = reverse_lazy('backups:index')
success_message = _('Restored files from backup.')
def collect_data(self, label, name):
"""Save some data used to instantiate the form."""
self.label = unquote(label) = unquote(name)
self.filename = find_exported_archive(self.label,
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):
"""Return additional context for rendering the template."""
context = super().get_context_data(**kwargs)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment