Exemplo n.º 1
0
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()
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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')
Exemplo n.º 5
0
    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)
Exemplo n.º 6
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()
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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)
Exemplo n.º 9
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()
Exemplo n.º 10
0
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
Exemplo n.º 11
0
    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)
Exemplo n.º 12
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')
Exemplo n.º 13
0
    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']))
Exemplo n.º 14
0
    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)
Exemplo n.º 15
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()
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
 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()