mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-09-19 04:59:01 +00:00
backups: Use paths from selected apps
Signed-off-by: James Valleroy <jvalleroy@mailbox.org> Reviewed-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
This commit is contained in:
parent
e72fb62008
commit
b272020e94
@ -41,7 +41,8 @@ def parse_arguments():
|
|||||||
|
|
||||||
create = subparsers.add_parser('create', help='Create archive')
|
create = subparsers.add_parser('create', help='Create archive')
|
||||||
create.add_argument('--name', help='Archive name', required=True)
|
create.add_argument('--name', help='Archive name', required=True)
|
||||||
create.add_argument('--path', help='Path to archive', required=True)
|
create.add_argument(
|
||||||
|
'--path', help='Paths to include in archive', nargs='+')
|
||||||
|
|
||||||
delete = subparsers.add_parser('delete', help='Delete archive')
|
delete = subparsers.add_parser('delete', help='Delete archive')
|
||||||
delete.add_argument('--name', help='Archive name', required=True)
|
delete.add_argument('--name', help='Archive name', required=True)
|
||||||
@ -91,8 +92,7 @@ def subcommand_create(arguments):
|
|||||||
"""Create archive."""
|
"""Create archive."""
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'borg', 'create', '--json', REPOSITORY + '::' + arguments.name,
|
'borg', 'create', '--json', REPOSITORY + '::' + arguments.name,
|
||||||
arguments.path
|
] + arguments.path, check=True)
|
||||||
], check=True)
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_delete(arguments):
|
def subcommand_delete(arguments):
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import json
|
|||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from .backups import backup_apps
|
||||||
from plinth import actions
|
from plinth import actions
|
||||||
from plinth.menu import main_menu
|
from plinth.menu import main_menu
|
||||||
from plinth.modules import udiskie
|
from plinth.modules import udiskie
|
||||||
@ -67,9 +68,15 @@ def get_archive(name):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def create_archive(name, path):
|
def _backup_handler(packet):
|
||||||
|
"""Performs backup operation on packet."""
|
||||||
|
paths = packet.directories + packet.files
|
||||||
actions.superuser_run('backups',
|
actions.superuser_run('backups',
|
||||||
['create', '--name', name, '--path', path])
|
['create', '--name', packet.label, '--path'] + paths)
|
||||||
|
|
||||||
|
|
||||||
|
def create_archive(name, app_names):
|
||||||
|
backup_apps(_backup_handler, app_names, name)
|
||||||
|
|
||||||
|
|
||||||
def delete_archive(name):
|
def delete_archive(name):
|
||||||
|
|||||||
@ -63,7 +63,7 @@ def _validate_directories_and_files(df):
|
|||||||
class Packet:
|
class Packet:
|
||||||
"""Information passed to a handlers for backup/restore operations."""
|
"""Information passed to a handlers for backup/restore operations."""
|
||||||
|
|
||||||
def __init__(self, operation, scope, root, manifests=None):
|
def __init__(self, operation, scope, root, manifests=None, label=None):
|
||||||
"""Initialize the packet.
|
"""Initialize the packet.
|
||||||
|
|
||||||
operation is either 'backup' or 'restore.
|
operation is either 'backup' or 'restore.
|
||||||
@ -80,6 +80,7 @@ class Packet:
|
|||||||
self.scope = scope
|
self.scope = scope
|
||||||
self.root = root
|
self.root = root
|
||||||
self.manifests = manifests
|
self.manifests = manifests
|
||||||
|
self.label = label
|
||||||
|
|
||||||
self.directories = []
|
self.directories = []
|
||||||
self.files = []
|
self.files = []
|
||||||
@ -95,7 +96,7 @@ class Packet:
|
|||||||
self.files += backup[x]['files']
|
self.files += backup[x]['files']
|
||||||
|
|
||||||
|
|
||||||
def backup_full(backup_handler):
|
def backup_full(backup_handler, label=None):
|
||||||
"""Backup the entire system."""
|
"""Backup the entire system."""
|
||||||
if not _is_snapshot_available():
|
if not _is_snapshot_available():
|
||||||
raise Exception('Full backup is not supported without snapshots.')
|
raise Exception('Full backup is not supported without snapshots.')
|
||||||
@ -103,7 +104,7 @@ def backup_full(backup_handler):
|
|||||||
snapshot = _take_snapshot()
|
snapshot = _take_snapshot()
|
||||||
backup_root = snapshot['mount_path']
|
backup_root = snapshot['mount_path']
|
||||||
|
|
||||||
packet = Packet('backup', 'full', backup_root)
|
packet = Packet('backup', 'full', backup_root, label)
|
||||||
_run_operation(backup_handler, packet)
|
_run_operation(backup_handler, packet)
|
||||||
|
|
||||||
_delete_snapshot(snapshot)
|
_delete_snapshot(snapshot)
|
||||||
@ -122,7 +123,7 @@ def restore_full(restore_handler):
|
|||||||
_switch_to_subvolume(subvolume)
|
_switch_to_subvolume(subvolume)
|
||||||
|
|
||||||
|
|
||||||
def backup_apps(backup_handler, app_names=None):
|
def backup_apps(backup_handler, app_names=None, label=None):
|
||||||
"""Backup data belonging to a set of applications."""
|
"""Backup data belonging to a set of applications."""
|
||||||
if not app_names:
|
if not app_names:
|
||||||
apps = _list_of_all_apps_for_backup()
|
apps = _list_of_all_apps_for_backup()
|
||||||
@ -141,7 +142,7 @@ def backup_apps(backup_handler, app_names=None):
|
|||||||
backup_root = '/'
|
backup_root = '/'
|
||||||
snapshotted = False
|
snapshotted = False
|
||||||
|
|
||||||
packet = Packet('backup', 'apps', backup_root, manifests)
|
packet = Packet('backup', 'apps', backup_root, manifests, label)
|
||||||
_run_operation(backup_handler, packet)
|
_run_operation(backup_handler, packet)
|
||||||
|
|
||||||
if snapshotted:
|
if snapshotted:
|
||||||
|
|||||||
@ -38,10 +38,6 @@ class CreateArchiveForm(forms.Form):
|
|||||||
help_text=_('Apps to include in the backup'),
|
help_text=_('Apps to include in the backup'),
|
||||||
widget=forms.CheckboxSelectMultiple)
|
widget=forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
path = forms.CharField(label=_('Path'), strip=True, help_text=_(
|
|
||||||
'Disk path to a folder on this server that will be archived into '
|
|
||||||
'backup repository.'))
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize the form with selectable apps."""
|
"""Initialize the form with selectable apps."""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|||||||
@ -71,7 +71,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."""
|
||||||
backups.create_archive(form.cleaned_data['name'],
|
backups.create_archive(form.cleaned_data['name'],
|
||||||
form.cleaned_data['path'])
|
form.cleaned_data['selected_apps'])
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user