Support new `borg compact` command (#1205)

This commit is contained in:
Manu 2022-02-21 21:23:56 +04:00 committed by GitHub
parent 4bbd091c59
commit c4cd054033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 11 deletions

View File

@ -24,7 +24,6 @@
<widget class="QToolBox" name="toolBox">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
@ -130,9 +129,9 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="diffButton">
<widget class="QToolButton" name="pruneButton">
<property name="text">
<string>Diff</string>
<string>Prune</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@ -140,9 +139,19 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="pruneButton">
<widget class="QToolButton" name="compactButton">
<property name="text">
<string>Prune</string>
<string>Compact</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="diffButton">
<property name="text">
<string>Diff</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@ -175,7 +184,6 @@
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
@ -194,8 +202,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>541</width>
<height>299</height>
<width>757</width>
<height>374</height>
</rect>
</property>
<attribute name="label">
@ -410,7 +418,6 @@
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
@ -447,7 +454,6 @@
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="#000000" d="M93.13 257.7C71.25 275.1 53 313.5 38.63 355.1L99 333.1c5.75-2.125 10.62 4.749 6.625 9.499L11 454.7C3.75 486.1 0 510.2 0 510.2s206.6 13.62 266.6-34.12c60-47.87 76.63-150.1 76.63-150.1L256.5 216.7C256.5 216.7 153.1 209.1 93.13 257.7zM633.2 12.34c-10.84-13.91-30.91-16.45-44.91-5.624l-225.7 175.6l-34.99-44.06C322.5 131.9 312.5 133.1 309 140.5L283.8 194.1l86.75 109.2l58.75-12.5c8-1.625 11.38-11.12 6.375-17.5l-33.19-41.79l225.2-175.2C641.6 46.38 644.1 26.27 633.2 12.34z"/></svg>

After

Width:  |  Height:  |  Size: 731 B

View File

@ -4,7 +4,8 @@ MIN_BORG_FOR_FEATURE = {
'BLAKE2': parse_version('1.1.4'),
'ZSTD': parse_version('1.1.4'),
'JSON_LOG': parse_version('1.1.0'),
'DIFF_JSON_LINES': parse_version('1.1.16')
'DIFF_JSON_LINES': parse_version('1.1.16'),
'COMPACT_SUBCOMMAND': parse_version('1.2.0a1')
# add new version-checks here.
}

48
src/vorta/borg/compact.py Normal file
View File

@ -0,0 +1,48 @@
from typing import Any, Dict
from vorta.i18n import trans_late
from vorta.utils import borg_compat
from .borg_job import BorgJob
class BorgCompactJob(BorgJob):
def started_event(self):
self.app.backup_started_event.emit()
self.app.backup_progress_event.emit(self.tr('Starting repository compaction...'))
def finished_event(self, result: Dict[str, Any]):
"""
Process that the job terminated with the given results.
Parameters
----------
result : Dict[str, Any]
The (json-like) dictionary containing the job results.
"""
self.app.backup_finished_event.emit(result)
self.result.emit(result)
if result['returncode'] != 0:
self.app.backup_progress_event.emit(self.tr('Errors during compaction. See logs for details.'))
else:
self.app.backup_progress_event.emit(self.tr('Compaction completed.'))
@classmethod
def prepare(cls, profile):
ret = super().prepare(profile)
if not ret['ok']:
return ret
else:
ret['ok'] = False # Set back to false, so we can do our own checks here.
if not borg_compat.check('COMPACT_SUBCOMMAND'):
ret['ok'] = False
ret['message'] = trans_late('messages', 'This feature needs Borg 1.2.0 or higher.')
return ret
cmd = ['borg', '--info', '--log-json', 'compact', '--cleanup-commits']
cmd.append(f'{profile.repo.url}')
ret['ok'] = True
ret['cmd'] = cmd
return ret

View File

@ -9,6 +9,7 @@ from PyQt5.QtWidgets import (QHeaderView, QMessageBox, QTableView,
QToolButton)
from vorta.borg.check import BorgCheckJob
from vorta.borg.compact import BorgCompactJob
from vorta.borg.delete import BorgDeleteJob
from vorta.borg.diff import BorgDiffJob
from vorta.borg.extract import BorgExtractJob
@ -68,6 +69,7 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
self.listButton.clicked.connect(self.list_action)
self.pruneButton.clicked.connect(self.prune_action)
self.checkButton.clicked.connect(self.check_action)
self.compactButton.clicked.connect(self.compact_action)
self.diffButton.clicked.connect(self.diff_action)
self.archiveActionMenu = QMenu(parent=self)
@ -87,6 +89,7 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
def set_icons(self):
"Used when changing between light- and dark mode"
self.checkButton.setIcon(get_colored_icon('check-circle'))
self.compactButton.setIcon(get_colored_icon('broom-solid'))
self.diffButton.setIcon(get_colored_icon('stream-solid'))
self.pruneButton.setIcon(get_colored_icon('cut'))
self.listButton.setIcon(get_colored_icon('refresh'))
@ -226,6 +229,20 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
if result['returncode'] == 0:
self._toggle_all_buttons(True)
def compact_action(self):
params = BorgCompactJob.prepare(self.profile())
if params['ok']:
job = BorgCompactJob(params['cmd'], params, self.profile().repo.id)
job.updated.connect(self._set_status)
job.result.connect(self.compact_result)
self._toggle_all_buttons(False)
self.app.jobs_manager.add_job(job)
else:
self._set_status(params['message'])
def compact_result(self, result):
self._toggle_all_buttons(True)
def prune_action(self):
params = BorgPruneJob.prepare(self.profile())
if params['ok']:

View File

@ -0,0 +1 @@
{"type": "log_message", "time": 1645335268.9396632, "message": "compaction freed about 56.00 kB repository space.", "levelname": "INFO", "name": "borg.repository"}

View File

@ -63,6 +63,25 @@ def test_repo_prune(qapp, qtbot, mocker, borg_json_output):
qtbot.waitUntil(lambda: main.progressText.text().startswith('Refreshing archives done.'), **pytest._wait_defaults)
def test_repo_compact(qapp, qtbot, mocker, borg_json_output):
main = qapp.main_window
tab = main.archiveTab
vorta.utils.borg_compat.version = '1.2.0'
main.tabWidget.setCurrentIndex(3)
tab.populate_from_profile()
stdout, stderr = borg_json_output('compact')
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
qtbot.mouseClick(tab.compactButton, QtCore.Qt.LeftButton)
qtbot.waitUntil(
lambda: 'compaction freed about 56.00 kB repository space' in main.logText.text(),
**pytest._wait_defaults
)
vorta.utils.borg_compat.version = '1.1.0'
def test_check(qapp, mocker, borg_json_output, qtbot):
main = qapp.main_window
tab = main.archiveTab