def init_db(qapp): vorta.models.db.drop_tables(models) vorta.models.init_db() new_repo = RepoModel(url='[email protected]:repo') new_repo.save() profile = BackupProfileModel.get(id=1) profile.repo = new_repo.id profile.save() test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive.save() test_archive1 = ArchiveModel(snapshot_id='99998', name='test-archive1', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive1.save() source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo) source_dir.save() qapp.open_main_window_action()
def app(tmpdir, qtbot): tmp_db = tmpdir.join('settings.sqlite') mock_db = peewee.SqliteDatabase(str(tmp_db)) vorta.models.init_db(mock_db) new_repo = RepoModel(url='[email protected]:repo') new_repo.save() profile = BackupProfileModel.get(id=1) profile.repo = new_repo.id profile.save() test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive.save() source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo) source_dir.save() app = VortaApp([]) app.main_window.show() qtbot.addWidget(app.main_window) return app
def app(tmpdir, qtbot, mocker): tmp_db = tmpdir.join('settings.sqlite') mock_db = peewee.SqliteDatabase(str(tmp_db)) vorta.models.init_db(mock_db) mocker.patch.object(vorta.application.VortaApp, 'set_borg_details_action', return_value=None) new_repo = RepoModel(url='[email protected]:repo') new_repo.save() profile = BackupProfileModel.get(id=1) profile.repo = new_repo.id profile.save() test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive.save() source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo) source_dir.save() app = VortaApp([]) app.open_main_window_action() qtbot.addWidget(app.main_window) app.main_window.tests_running = True return app
def create_backup(self, profile_id): notifier = VortaNotifications.pick() profile = BackupProfileModel.get(id=profile_id) logger.info('Starting background backup for %s', profile.name) notifier.deliver(self.tr('Vorta Backup'), self.tr('Starting background backup for %s.') % profile.name, level='info') msg = BorgCreateThread.prepare(profile) if msg['ok']: logger.info('Preparation for backup successful.') thread = BorgCreateThread(msg['cmd'], msg) thread.start() thread.wait() if thread.process.returncode in [0, 1]: notifier.deliver(self.tr('Vorta Backup'), self.tr('Backup successful for %s.') % profile.name, level='info') logger.info('Backup creation successful.') self.post_backup_tasks(profile_id) else: notifier.deliver(self.tr('Vorta Backup'), self.tr('Error during backup creation.'), level='error') logger.error('Error during backup creation.') else: logger.error('Conditions for backup not met. Aborting.') logger.error(msg['message']) notifier.deliver(self.tr('Vorta Backup'), translate('messages', msg['message']), level='error')
def profile_delete_action(self): if self.profileSelector.count() > 1: to_delete = BackupProfileModel.get( id=self.profileSelector.currentData()) # Remove pending background jobs to_delete_id = str(to_delete.id) msg = self.tr( "Are you sure you want to delete profile '{}'?".format( to_delete.name)) reply = QMessageBox.question(self, self.tr("Confirm deletion"), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if self.app.scheduler.get_job(to_delete_id): self.app.scheduler.remove_job(to_delete_id) to_delete.delete_instance(recursive=True) self.profileSelector.removeItem( self.profileSelector.currentIndex()) self.profile_select_action(0) else: warn = self.tr("Can't delete the last profile.") point = QPoint(0, self.profileDeleteButton.size().height() / 2) QToolTip.showText(self.profileDeleteButton.mapToGlobal(point), warn)
def profile_select_action(self, index): self.current_profile = BackupProfileModel.get( id=self.profileSelector.currentData()) self.archiveTab.populate_from_profile() self.repoTab.populate_from_profile() self.sourceTab.populate_from_profile() self.scheduleTab.populate_from_profile()
def init_db(qapp): vorta.models.db.drop_tables(models) vorta.models.init_db() new_repo = RepoModel(url='[email protected]:repo') new_repo.encryption = 'none' new_repo.save() profile = BackupProfileModel.get(id=1) profile.repo = new_repo.id profile.dont_run_on_metered_networks = False profile.save() test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive.save() test_archive1 = ArchiveModel(snapshot_id='99998', name='test-archive1', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive1.save() source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo, dir_size=100, dir_files_count=18, path_isdir=True) source_dir.save() qapp.main_window = MainWindow( qapp) # Re-open main window to apply mock data in UI
def delete_current_profile(qapp): ''' Delete current profile for cleanup ''' main = qapp.main_window target = BackupProfileModel.get(id=main.profileSelector.currentData()) if qapp.scheduler.get_job(target.id): qapp.scheduler.remove_job(target.id) target.delete_instance(recursive=True) main.profileSelector.removeItem(main.profileSelector.currentIndex()) main.profile_select_action(0)
def profile_select_action(self, index): self.current_profile = BackupProfileModel.get(id=self.profileSelector.currentData()) self.archiveTab.populate_from_profile() self.repoTab.populate_from_profile() self.sourceTab.populate_from_profile() self.scheduleTab.populate_from_profile() SettingsModel.update({SettingsModel.str_value: self.current_profile.id})\ .where(SettingsModel.key == 'previous_profile_id')\ .execute()
def test_prune_intervals(qapp, qtbot): prune_intervals = ['hour', 'day', 'week', 'month', 'year'] main = qapp.main_window tab = main.archiveTab profile = BackupProfileModel.get(id=1) for i in prune_intervals: getattr(tab, f'prune_{i}').setValue(9) tab.save_prune_setting(None) profile = profile.refresh() assert getattr(profile, f'prune_{i}') == 9
def profile_delete_action(self): if self.profileSelector.count() > 1: to_delete = BackupProfileModel.get(id=self.profileSelector.currentData()) # Remove pending background jobs to_delete_id = str(to_delete.id) if self.app.scheduler.get_job(to_delete_id): self.app.scheduler.remove_job(to_delete_id) to_delete.delete_instance(recursive=True) self.profileSelector.removeItem(self.profileSelector.currentIndex()) self.profile_select_action(0)
def next_job(self): self.wakeup() self._process_jobs() jobs = [] for job in self.get_jobs(): jobs.append((job.next_run_time, job.id)) if jobs: jobs.sort(key=lambda job: job[0]) profile = BackupProfileModel.get(id=int(jobs[0][1])) return f"{jobs[0][0].strftime('%H:%M')} ({profile.name})" else: return self.tr('None scheduled')
def create_backup_action(self, profile_id=None): if not profile_id: profile_id = self.main_window.current_profile.id profile = BackupProfileModel.get(id=profile_id) msg = BorgCreateThread.prepare(profile) if msg['ok']: thread = BorgCreateThread(msg['cmd'], msg, parent=self) thread.start() else: notifier = VortaNotifications.pick() notifier.deliver(self.tr('Vorta Backup'), translate('messages', msg['message']), level='error') self.backup_log_event.emit(translate('messages', msg['message']))
def profile_delete_action(self): if self.profileSelector.count() > 1: to_delete = BackupProfileModel.get(id=self.profileSelector.currentData()) # Remove pending background jobs to_delete_id = str(to_delete.id) msg = self.tr("Are you sure you want to delete profile '{}'?".format(to_delete.name)) reply = QMessageBox.question(self, self.tr("Confirm deletion"), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if self.app.scheduler.get_job(to_delete_id): self.app.scheduler.remove_job(to_delete_id) to_delete.delete_instance(recursive=True) self.profileSelector.removeItem(self.profileSelector.currentIndex()) self.profile_select_action(0)
def init_db(qapp, qtbot, tmpdir_factory): tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') mock_db = peewee.SqliteDatabase(str(tmp_db), pragmas={ 'journal_mode': 'wal', }) vorta.models.init_db(mock_db) new_repo = RepoModel(url='[email protected]:repo') new_repo.encryption = 'none' new_repo.save() profile = BackupProfileModel.get(id=1) profile.repo = new_repo.id profile.dont_run_on_metered_networks = False profile.save() test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive.save() test_archive1 = ArchiveModel(snapshot_id='99998', name='test-archive1', time=dt(2000, 1, 1, 0, 0), repo=1) test_archive1.save() source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo, dir_size=100, dir_files_count=18, path_isdir=True) source_dir.save() qapp.main_window.deleteLater() del qapp.main_window qapp.main_window = MainWindow( qapp) # Re-open main window to apply mock data in UI yield qapp.backup_cancelled_event.emit() qtbot.waitUntil(lambda: not vorta.borg.borg_thread.BorgThread.is_running()) mock_db.close()
def post_backup_tasks(self, profile_id): """ Pruning and checking after successful backup. """ profile = BackupProfileModel.get(id=profile_id) logger.info('Doing post-backup jobs for %s', profile.name) if profile.prune_on: msg = BorgPruneThread.prepare(profile) if msg['ok']: prune_thread = BorgPruneThread(msg['cmd'], msg) prune_thread.start() prune_thread.wait() # Refresh archives msg = BorgListRepoThread.prepare(profile) if msg['ok']: list_thread = BorgListRepoThread(msg['cmd'], msg) list_thread.start() list_thread.wait() validation_cutoff = date.today() - timedelta(days=7 * profile.validation_weeks) recent_validations = EventLogModel.select().where( ( EventLogModel.subcommand == 'check' ) & ( EventLogModel.start_time > validation_cutoff ) & ( EventLogModel.repo_url == profile.repo.url ) ).count() if profile.validation_on and recent_validations == 0: msg = BorgCheckThread.prepare(profile) if msg['ok']: check_thread = BorgCheckThread(msg['cmd'], msg) check_thread.start() check_thread.wait() logger.info('Finished background task for profile %s', profile.name)
def react_to_log(self, mgs, context): """ Trigger Vorta actions based on Borg logs. E.g. repo lock. """ msgid = context.get('msgid') if msgid == 'LockTimeout': profile = BackupProfileModel.get(name=context['profile_name']) repo_url = context.get('repo_url') msg = QMessageBox() msg.setWindowTitle(self.tr("Repository In Use")) msg.setIcon(QMessageBox.Critical) abortButton = msg.addButton(self.tr("Abort"), QMessageBox.RejectRole) msg.addButton(self.tr("Continue"), QMessageBox.AcceptRole) msg.setDefaultButton(abortButton) msg.setText( self. tr(f"The repository at {repo_url} might be in use elsewhere.")) msg.setInformativeText( self. tr("Only break the lock if you are certain no other Borg process " "on any machine is accessing the repository. Abort or break the lock?" )) msg.accepted.connect(lambda: self.break_lock(profile)) self._msg = msg msg.show() elif msgid == 'LockFailed': repo_url = context.get('repo_url') msg = QMessageBox() msg.setText( self. tr(f"You do not have permission to access the repository at {repo_url}. Gain access and try again." )) # noqa: E501 msg.setWindowTitle(self.tr("No Repository Permissions")) self._msg = msg msg.show()