1
0
Fork 0
mirror of https://github.com/borgbase/vorta synced 2024-12-21 23:33:13 +00:00

Add compaction scheduling. By @shivansh02 (#1981)

This commit is contained in:
Shivansh Singh 2024-06-29 15:08:02 +05:30 committed by GitHub
parent 7ab769e117
commit 449b95e1b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 167 additions and 1 deletions

View file

@ -443,6 +443,116 @@
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="compaction_label">
<property name="text">
<string>Compaction:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="compactionCheckBox">
<property name="text">
<string>Compact repository</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frameCompaction">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="layoutCompaction">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="interval_label">
<property name="text">
<string>Interval:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_interval">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>4</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="compactionWeeksCount">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>52</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="compaction_weeks_label">
<property name="text">
<string>weeks</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">

View file

@ -5,18 +5,21 @@
from datetime import timedelta
from typing import Dict, NamedTuple, Optional, Tuple, Union
from packaging import version
from PyQt6 import QtCore, QtDBus
from PyQt6.QtCore import QTimer
from PyQt6.QtWidgets import QApplication
from vorta import application
from vorta.borg.check import BorgCheckJob
from vorta.borg.compact import BorgCompactJob
from vorta.borg.create import BorgCreateJob
from vorta.borg.list_repo import BorgListRepoJob
from vorta.borg.prune import BorgPruneJob
from vorta.i18n import translate
from vorta.notifications import VortaNotifications
from vorta.store.models import BackupProfileModel, EventLogModel
from vorta.utils import borg_compat
logger = logging.getLogger(__name__)
@ -489,6 +492,27 @@ def post_backup_tasks(self, profile_id):
job = BorgCheckJob(msg['cmd'], msg, profile.repo.id)
self.app.jobs_manager.add_job(job)
compaction_cutoff = dt.now() - timedelta(days=7 * profile.compaction_weeks)
recent_compactions = (
EventLogModel.select()
.where(
(EventLogModel.subcommand == '--info')
& (EventLogModel.start_time > compaction_cutoff)
& (EventLogModel.repo_url == profile.repo.url)
)
.count()
)
if (
profile.compaction_on
and recent_compactions == 0
and version.parse(borg_compat.version) >= version.parse("1.2")
):
msg = BorgCompactJob.prepare(profile)
if msg['ok']:
job = BorgCompactJob(msg['cmd'], msg, profile.repo.id)
self.app.jobs_manager.add_job(job)
logger.info('Finished background task for profile %s', profile.name)
notifier.deliver(
self.tr('Vorta Backup'),

View file

@ -24,7 +24,7 @@
)
from .settings import get_misc_settings
SCHEMA_VERSION = 22
SCHEMA_VERSION = 23
@signals.post_save(sender=SettingsModel)

View file

@ -250,6 +250,22 @@ def run_migrations(current_schema, db_connection):
),
)
if current_schema.version < 23:
_apply_schema_update(
current_schema,
23,
migrator.add_column(
BackupProfileModel._meta.table_name,
'compaction_on',
pw.BooleanField(default=True),
),
migrator.add_column(
BackupProfileModel._meta.table_name,
'compaction_weeks',
pw.IntegerField(default=3),
),
)
def _apply_schema_update(current_schema, version_after, *operations):
with DB.atomic():

View file

@ -90,6 +90,8 @@ class BackupProfileModel(BaseModel):
schedule_make_up_missed = pw.BooleanField(default=True)
validation_on = pw.BooleanField(default=True)
validation_weeks = pw.IntegerField(default=3)
compaction_on = pw.BooleanField(default=False)
compaction_weeks = pw.IntegerField(default=3)
prune_on = pw.BooleanField(default=False)
prune_hour = pw.IntegerField(default=2)
prune_day = pw.IntegerField(default=7)

View file

@ -63,10 +63,12 @@ def __init__(self, parent=None):
self.framePeriodic.setEnabled(False)
self.frameDaily.setEnabled(False)
self.frameValidation.setEnabled(False)
self.frameCompaction.setEnabled(False)
self.scheduleIntervalRadio.toggled.connect(self.framePeriodic.setEnabled)
self.scheduleFixedRadio.toggled.connect(self.frameDaily.setEnabled)
self.validationCheckBox.toggled.connect(self.frameValidation.setEnabled)
self.compactionCheckBox.toggled.connect(self.frameCompaction.setEnabled)
# POPULATE with data
self.populate_from_profile()
@ -105,6 +107,12 @@ def __init__(self, parent=None):
self.validationWeeksCount.valueChanged.connect(
lambda new_val, attr='validation_weeks': self.save_profile_attr(attr, new_val)
)
self.compactionCheckBox.stateChanged.connect(
lambda new_val, attr='compaction_on': self.save_profile_attr(attr, new_val)
)
self.compactionWeeksCount.valueChanged.connect(
lambda new_val, attr='compaction_weeks': self.save_profile_attr(attr, new_val)
)
# Connect to schedule update
self.app.scheduler.schedule_changed.connect(lambda pid: self.draw_next_scheduled_backup())
@ -154,6 +162,12 @@ def populate_from_profile(self):
)
self.validationWeeksCount.setValue(profile.validation_weeks)
# set borg compact options
self.compactionCheckBox.setCheckState(
QtCore.Qt.CheckState.Checked if profile.compaction_on else QtCore.Qt.CheckState.Unchecked
)
self.compactionWeeksCount.setValue(profile.compaction_weeks)
# Other checkbox options
self.pruneCheckBox.setCheckState(
QtCore.Qt.CheckState.Checked if profile.prune_on else QtCore.Qt.CheckState.Unchecked