Skip to content

Commit

Permalink
Implement borg v2 compatibility for most commands.
Browse files Browse the repository at this point in the history
Adjust available encryptions for borg v2.
Use `-r` for all/most commands. Implement `rinfo`.
Use `ssh://` style URL as a placeholder.
Implement compatibility for `borg extract`.
Adjust for beta3, use --match-archives for deletions

Co-authored-by: real-yfprojects <[email protected]>
Co-authored-by: Manu <[email protected]>
  • Loading branch information
real-yfprojects and m3nu committed Jan 21, 2023
1 parent fa3a6cf commit 2b2d61b
Show file tree
Hide file tree
Showing 17 changed files with 375 additions and 309 deletions.
539 changes: 269 additions & 270 deletions src/vorta/assets/UI/repoadd.ui

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/vorta/borg/borg_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def read_async(fd):
msg = (
f"{translate('BorgJob','Files')}: {parsed['nfiles']}, "
f"{translate('BorgJob','Original')}: {pretty_bytes(parsed['original_size'])}, "
f"{translate('BorgJob','Compressed')}: {pretty_bytes(parsed['compressed_size'])}, "
# f"{translate('BorgJob','Compressed')}: {pretty_bytes(parsed['compressed_size'])}, "
f"{translate('BorgJob','Deduplicated')}: {pretty_bytes(parsed['deduplicated_size'])}" # noqa: E501
)
self.app.backup_progress_event.emit(msg)
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/check.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Dict
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand Down Expand Up @@ -33,7 +34,10 @@ def prepare(cls, profile):
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ['borg', 'check', '--info', '--log-json', '--progress']
cmd.append(f'{profile.repo.url}')
if borg_compat.check('V2'):
cmd = cmd + ["-r", profile.repo.url]
else:
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
ret['cmd'] = cmd
Expand Down
7 changes: 5 additions & 2 deletions src/vorta/borg/compact.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ def prepare(cls, profile):
ret['message'] = trans_late('messages', 'This feature needs Borg 1.2.0 or higher.')
return ret

cmd = ['borg', '--info', '--log-json', 'compact', '--cleanup-commits', '--progress']
cmd.append(f'{profile.repo.url}')
cmd = ['borg', '--info', '--log-json', 'compact', '--progress']
if borg_compat.check('V2'):
cmd = cmd + ["-r", profile.repo.url]
else:
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
ret['cmd'] = cmd
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ def prepare(cls, profile):

# Add repo url and source dirs.
new_archive_name = format_archive_name(profile, profile.new_archive_name)
cmd.append(f"{profile.repo.url}::{new_archive_name}")

if borg_compat.check('V2'):
cmd += ["-r", profile.repo.url, new_archive_name]
else:
cmd.append(f"{profile.repo.url}::{new_archive_name}")

for f in SourceFileModel.select().where(SourceFileModel.profile == profile.id):
cmd.append(f.dir)
Expand Down
9 changes: 7 additions & 2 deletions src/vorta/borg/delete.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List
from vorta.store.models import RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand Down Expand Up @@ -33,8 +34,12 @@ def prepare(cls, profile, archives: List[str]):
return ret

cmd = ['borg', 'delete', '--info', '--log-json']
cmd.append(f'{profile.repo.url}::{archives[0]}')
cmd.extend(archives[1:])
if borg_compat.check('V2'):
cmd = cmd + ["-r", profile.repo.url, '-a']
cmd.append(f"re:({'|'.join(archives)})")
else:
cmd.append(f'{profile.repo.url}::{archives[0]}')
cmd.extend(archives[1:])

ret['archives'] = archives
ret['cmd'] = cmd
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ def prepare(cls, profile, archive_name_1, archive_name_2):
ret['cmd'].append('--json-lines')
ret['json_lines'] = True

ret['cmd'].extend([f'{profile.repo.url}::{archive_name_1}', f'{archive_name_2}'])
if borg_compat.check('V2'):
ret['cmd'].extend(['-r', profile.repo.url, archive_name_1, archive_name_2])
else:
ret['cmd'].extend([f'{profile.repo.url}::{archive_name_1}', archive_name_2])

ret['ok'] = True
ret['archive_name_older'] = archive_name_1
ret['archive_name_newer'] = archive_name_2
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/extract.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import tempfile
from PyQt5.QtCore import QModelIndex, Qt
from vorta.utils import borg_compat
from vorta.views.extract_dialog import ExtractTree, FileData
from vorta.views.partials.treemodel import FileSystemItem, path_to_str
from .borg_job import BorgJob
Expand All @@ -24,7 +25,10 @@ def prepare(cls, profile, archive_name, model: ExtractTree, destination_folder):
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ['borg', 'extract', '--list', '--info', '--log-json']
cmd.append(f'{profile.repo.url}::{archive_name}')
if borg_compat.check('V2'):
cmd += ['-r', profile.repo.url, archive_name]
else:
cmd.append(f'{profile.repo.url}::{archive_name}')

# process selected items
# all items will be excluded beside the one actively selected in the
Expand Down
14 changes: 6 additions & 8 deletions src/vorta/borg/info_archive.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from vorta.store.models import ArchiveModel, RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand All @@ -19,13 +20,11 @@ def prepare(cls, profile, archive_name):
return ret

ret['ok'] = True
ret['cmd'] = [
'borg',
'info',
'--log-json',
'--json',
f'{profile.repo.url}::{archive_name}',
]
ret['cmd'] = ['borg', 'info', '--log-json', '--json']
if borg_compat.check('V2'):
ret['cmd'].extend(["-r", profile.repo.url, '-a', archive_name])
else:
ret['cmd'].append(f'{profile.repo.url}::{archive_name}')
ret['archive_name'] = archive_name

return ret
Expand All @@ -52,7 +51,6 @@ def process_result(self, result):
stats = result['data']['cache']['stats']
repo = RepoModel.get(id=result['params']['repo_id'])
repo.total_size = stats['total_size']
repo.unique_csize = stats['unique_csize']
repo.unique_size = stats['unique_size']
repo.total_unique_chunks = stats['total_unique_chunks']
repo.save()
6 changes: 5 additions & 1 deletion src/vorta/borg/info_repo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from vorta.i18n import trans_late
from vorta.store.models import RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob, FakeProfile, FakeRepo


Expand Down Expand Up @@ -27,7 +28,10 @@ def prepare(cls, params):
else:
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ["borg", "info", "--info", "--json", "--log-json"]
if borg_compat.check('V2'):
cmd = ["borg", "rinfo", "--info", "--json", "--log-json", "-r"]
else:
cmd = ["borg", "info", "--info", "--json", "--log-json"]
cmd.append(profile.repo.url)

ret['additional_env'] = {
Expand Down
18 changes: 15 additions & 3 deletions src/vorta/borg/init.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from vorta.store.models import RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob, FakeProfile, FakeRepo


Expand Down Expand Up @@ -28,9 +29,20 @@ def prepare(cls, params):
else:
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ["borg", "init", "--info", "--log-json"]
cmd.append(f"--encryption={params['encryption']}")
cmd.append(params['repo_url'])
if borg_compat.check('V2'):
cmd = [
"borg",
"rcreate",
"--info",
"--log-json",
f"--encryption={params['encryption']}",
"-r",
params['repo_url'],
]
else:
cmd = ["borg", "init", "--info", "--log-json"]
cmd.append(f"--encryption={params['encryption']}")
cmd.append(params['repo_url'])

ret['additional_env'] = {'BORG_RSH': 'ssh -oStrictHostKeyChecking=accept-new'}

Expand Down
7 changes: 6 additions & 1 deletion src/vorta/borg/list_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ def prepare(cls, profile, archive_name):
"{mode}{user}{group}{size}{"
+ ('isomtime' if borg_compat.check('V122') else 'mtime')
+ "}{path}{source}{health}{NL}",
f'{profile.repo.url}::{archive_name}',
]

if borg_compat.check('V2'):
ret['cmd'].extend(["-r", profile.repo.url, archive_name])
else:
ret['cmd'].append(f'{profile.repo.url}::{archive_name}')

ret['ok'] = True

return ret
6 changes: 5 additions & 1 deletion src/vorta/borg/list_repo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime as dt
from vorta.store.models import ArchiveModel, RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand All @@ -21,7 +22,10 @@ def prepare(cls, profile):
else:
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ['borg', 'list', '--info', '--log-json', '--json']
if borg_compat.check('V2'):
cmd = ['borg', 'rlist', '--info', '--log-json', '--json', '-r']
else:
cmd = ['borg', 'list', '--info', '--log-json', '--json']
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/mount.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from vorta.store.models import SettingsModel
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand All @@ -23,7 +24,10 @@ def prepare(cls, profile):
if override_mount_permissions:
cmd += ['-o', f"umask=0277,uid={os.getuid()}"]

cmd += [f"{profile.repo.url}"]
if borg_compat.check('V2'):
cmd.extend(["-r", profile.repo.url])
else:
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
ret['cmd'] = cmd
Expand Down
5 changes: 4 additions & 1 deletion src/vorta/borg/prune.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ def prepare(cls, profile):
if profile.prune_keep_within:
pruning_opts += ['--keep-within', profile.prune_keep_within]
cmd += pruning_opts
cmd.append(f'{profile.repo.url}')
if borg_compat.check('V2'):
cmd.extend(["-r", profile.repo.url])
else:
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
ret['cmd'] = cmd
Expand Down
6 changes: 5 additions & 1 deletion src/vorta/borg/rename.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from vorta.store.models import ArchiveModel, RepoModel
from vorta.utils import borg_compat
from .borg_job import BorgJob


Expand All @@ -15,7 +16,10 @@ def prepare(cls, profile):
ret['ok'] = False # Set back to false, so we can do our own checks here.

cmd = ['borg', 'rename', '--info', '--log-json']
cmd.append(f'{profile.repo.url}')
if borg_compat.check('V2'):
cmd.extend(["-r", profile.repo.url])
else:
cmd.append(f'{profile.repo.url}')

ret['ok'] = True
ret['cmd'] = cmd
Expand Down
35 changes: 22 additions & 13 deletions src/vorta/views/repo_add_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,28 @@ def run_result(self, result):
self._set_status(self.tr('Unable to add your repository.'))

def init_encryption(self):
encryption_algos = [
[
self.tr('Repokey-Blake2 (Recommended, key stored in repository)'),
'repokey-blake2',
],
[self.tr('Repokey'), 'repokey'],
[
self.tr('Keyfile-Blake2 (Key stored in home directory)'),
'keyfile-blake2',
],
[self.tr('Keyfile'), 'keyfile'],
[self.tr('None (not recommended)'), 'none'],
]
if borg_compat.check('V2'):
encryption_algos = [
[
self.tr('Repokey-ChaCha20-Poly1305 (Recommended, key stored in repository)'),
'repokey-blake2-chacha20-poly1305',
],
[
self.tr('Keyfile-ChaCha20-Poly1305 (Key stored in home directory)'),
'keyfile-blake2-chacha20-poly1305',
],
[self.tr('Repokey-AES256-OCB'), 'repokey-blake2-aes-ocb'],
[self.tr('Keyfile-AES256-OCB'), 'keyfile-blake2-aes-ocb'],
[self.tr('None (not recommended)'), 'none'],
]
else:
encryption_algos = [
[self.tr('Repokey-Blake2 (Recommended, key stored in repository)'), 'repokey-blake2'],
[self.tr('Repokey'), 'repokey'],
[self.tr('Keyfile-Blake2 (Key stored in home directory)'), 'keyfile-blake2'],
[self.tr('Keyfile'), 'keyfile'],
[self.tr('None (not recommended)'), 'none'],
]

for desc, name in encryption_algos:
self.encryptionComboBox.addItem(desc, name)
Expand Down

0 comments on commit 2b2d61b

Please sign in to comment.