예제 #1
0
    def start_restore(self):
        '''
            Start restoring the files and directories.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> restore_task = RestoreTask(os.path.join(gettempdir(), 'bitcoin/data/testnet3/backups/level1'))
            >>> restore_task.manager = BitcoinManager(restore_task.log_name)
            >>> restore_process = restore_task.start_restore()
            >>> restore_process is not None
            True
            >>> test_utils.stop_restore()
        '''

        # do NOT use the --delete flag -- the backups dir itself would be deleted
        args = []
        # restore program is a link to safecopy
        bin_dir = os.path.join(virtualenv_dir(), 'bin')
        args.append(os.path.join(bin_dir, constants.RESTORE_PROGRAM))
        args.append('--exclude')
        args.append(bitcoin_utils.get_excluded_files())
        args.append('--verbose')
        args.append('--quick')
        args.append(f'{self.restore_dir}/*')
        args.append(self.manager.data_dir)

        restore_process = Popen(args, stdout=PIPE, universal_newlines=True)

        return restore_process
예제 #2
0
def stop_bitcoin_qt():
    '''
        Stop bitcoin_qt and determine if it ended properly.

        >>> init_database()
        >>> stop_bitcoin_qt()
    '''
    seconds = 0
    while (bitcoin_utils.is_bitcoin_qt_running() and seconds < 60):
        try:
            send_bitcoin_cli_cmd('stop')
            sleep(5)
            seconds += 5
        except:
            pass

    # use brute force if necessary
    if bitcoin_utils.is_bitcoin_qt_running():
        bin_dir = os.path.join(virtualenv_dir(), 'bin')
        args = [os.path.join(bin_dir, 'killmatch'), bitcoin_utils.bitcoin_qt()]
        command.run(*args).stdout

    # give it a little more time to settle down
    sleep(5)

    log(f'bitcoin-qt running: {bitcoin_utils.is_bitcoin_qt_running()}')
예제 #3
0
    def interrupt_backup(self):
        '''
            End user interrupts the backup.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> backup_task = BackupTask()
            >>> backup_task.manager = BitcoinManager(backup_task.log_name)
            >>> backup_task.to_backup_dir, backup_task.backup_formatted_time, __ = backup_utils.prep_backup(backup_task.manager.data_dir)
            >>> backup_process, backup_pid = backup_utils.start_backup(backup_task.manager.data_dir,
            ...                                                        backup_task.to_backup_dir)
            >>> test_utils.start_fake_backup()
            >>> backup_task.interrupt_backup()
            True
        '''

        MAX_SECS = 3

        seconds = 0

        self.log('interrupting backup')
        if self.to_backup_dir is not None:
            # remove all files that suggest this backup is complete
            backup_utils.delete_last_updated_files(self.to_backup_dir)
            # add a flag that we started to use this dir to backup
            backup_utils.add_backup_flag(self.to_backup_dir,
                                         self.backup_formatted_time)

        try:
            bin_dir = os.path.join(virtualenv_dir(), 'bin')
            args = [
                os.path.join(bin_dir, 'killmatch'), constants.BACKUP_PROGRAM
            ]

            attempts = 0
            while backup_utils.is_backup_running() and attempts < 3:
                result = command.run(*args).stdout
                self.log(f'result of stopping backup: {result}')
                if backup_utils.is_backup_running():
                    sleep(3)
                    attempts += 1
        except CalledProcessError as cpe:
            self.log(cpe)
            self.log(format_exc())

        while seconds < MAX_SECS:
            self.manager.update_header(backup_utils.STOPPED_BACKUP_HEADER)
            self.manager.update_progress(backup_utils.STOPPED_BACKUP_PROGRESS)
            self.manager.notify_close_window()

            sleep(1)
            seconds += 1

        # return value is for testing purposes only
        return not backup_utils.is_backup_running()
예제 #4
0
    def interrupt_restore(self):
        '''
            User wants the restoration interrupted.
            This is not recommended because it almost
            always leaves the blockchain in unusable shape.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> restore_dir = os.path.join(gettempdir(), 'bitcoin/data/testnet3/backups/level1')
            >>> restore_task = RestoreTask(restore_dir)
            >>> restore_task.manager = BitcoinManager(restore_task.log_name)
            >>> test_utils.start_fake_restore()
            >>> restore_task.interrupt_restore()
            True
        '''

        max_secs = 3
        seconds = 0

        try:
            bin_dir = os.path.join(virtualenv_dir(), 'bin')
            args = [
                os.path.join(bin_dir, 'killmatch'), constants.RESTORE_PROGRAM
            ]
            args = [
                os.path.join('/usr/local/bin', 'killmatch'),
                constants.RESTORE_PROGRAM
            ]
            self.log(f'args: {args}')

            attempts = 0
            while bitcoin_utils.is_restore_running() and attempts < 5:
                command.run(*args)
                if bitcoin_utils.is_restore_running():
                    sleep(3)
                    attempts += 1
        except CalledProcessError as cpe:
            self.log(cpe)
            self.log(format_exc())

        # a new page was displayed so give socketio time to connect
        while seconds < max_secs:
            self.manager.update_header(self.STOPPED_RESTORE)
            self.manager.update_subnotice(self.STOP_RESTORE_NOT_COMPLETE)
            self.manager.notify_done()

            sleep(1)
            seconds += 1

        # return value is for testing purposes only
        return not bitcoin_utils.is_restore_running()
예제 #5
0
    def stop_backup(self, backup_process, backup_pid):
        '''
            Stop backup.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> backup_task = BackupTask()
            >>> backup_task.manager = BitcoinManager(backup_task.log_name)
            >>> backup_task.prep_backup()
            >>> backup_process, backup_pid = backup_task.start_backup()
            >>> backup_process is not None
            True
            >>> backup_pid is None
            True
            >>> backup_task.stop_backup(backup_process, backup_pid)
            >>> test_utils.start_fake_backup()
            >>> backup_pid = get_pid(constants.BACKUP_PROGRAM)
            >>> backup_task.stop_backup(None, backup_pid)
        '''
        try:
            if backup_process is None and backup_pid is not None:
                if is_backup_running():
                    bin_dir = os.path.join(virtualenv_dir(), 'bin')
                    args = [
                        os.path.join(bin_dir, 'killmatch'),
                        '"{} --exclude {}"'.format(constants.BACKUP_PROGRAM,
                                                   get_excluded_files())
                    ]
                    result = command.run(*args).stdout
                    self.log(f'killing backup result: {result}')

                try:
                    pid, returncode = os.waitpid(backup_pid, os.P_WAIT)
                    self.log(f'waitpid {pid} return code: {returncode}')
                except ChildProcessError:
                    self.log('backup_pid already dead')
            else:
                # if bcb-backup hasn't stopped yet, then kill it
                if backup_process is None:
                    self.log('not back process active')
                else:
                    if backup_process.poll() is None:
                        self.log('killing backup')
                        backup_process.terminate()

                    # wait until backup terminates
                    backup_process.wait()
                    self.log(
                        f'backup return code: {backup_process.returncode}')
        except:  # 'bare except' because it catches more than "except Exception"
            self.log(f'error while stopping backup\n{format_exc()}')
예제 #6
0
def stop_bitcoin_core_apps():
    '''
        Stop all bitcoin core apps.

        >>> stop_bitcoin_core_apps()
    '''
    if bitcoin_utils.is_bitcoin_qt_running():
        stop_bitcoin_qt()

        # if it's still running, then kill it
        if bitcoin_utils.is_bitcoin_qt_running():
            bin_dir = os.path.join(virtualenv_dir(), 'bin')
            args = [os.path.join(bin_dir, 'killmatch'), bitcoin_utils.bitcoin_qt()]
            command.run(*args).stdout

    if bitcoin_utils.is_bitcoind_running():
        stop_bitcoind()

        # if it's still running, then kill it
        if bitcoin_utils.is_bitcoind_running():
            bin_dir = os.path.join(virtualenv_dir(), 'bin')
            args = [os.path.join(bin_dir, 'killmatch'), bitcoin_utils.bitcoind()]
            command.run(*args).stdout
예제 #7
0
def stop_restore():
    '''
        Stop the restore.

        >>> init_database()
        >>> stop_restore()
    '''
    while bitcoin_utils.is_restore_running():
        sleep(5)

        bin_dir = os.path.join(virtualenv_dir(), 'bin')
        excluded_files = bitcoin_utils.get_excluded_files()
        args = [os.path.join(bin_dir, 'killmatch'),
                f'"{constants.RESTORE_PROGRAM} --exclude {excluded_files}"']
        result = command.run(*args).stdout
        log(f'killing restore result: {result}')
예제 #8
0
    def stop_restore(self, restore_process, restore_pid):
        '''
            Stop restore.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> restore_task = RestoreTask(os.path.join(gettempdir(), 'bitcoin/data/testnet3/backups/level1'))
            >>> restore_task.manager = BitcoinManager(restore_task.log_name)
            >>> restore_process = restore_task.start_restore()
            >>> restore_process is not None
            True
            >>> restore_task.stop_restore(restore_process, None)
            >>> test_utils.start_fake_restore()
            >>> restore_pid = get_pid(constants.RESTORE_PROGRAM)
            >>> restore_task.stop_restore(None, restore_pid)
        '''
        try:
            if restore_process is None:
                if bitcoin_utils.is_restore_running():
                    bin_dir = os.path.join(virtualenv_dir(), 'bin')
                    args = [
                        os.path.join(bin_dir, 'killmatch'),
                        '"{} --exclude {}"'.format(
                            constants.RESTORE_PROGRAM,
                            bitcoin_utils.get_excluded_files())
                    ]
                    result = command.run(*args).stdout
                    self.log(f'killing restore result: {result}')

                try:
                    pid, returncode = os.waitpid(restore_pid, os.P_WAIT)
                    self.log(f'waitpid {pid} return code: {returncode}')
                except ChildProcessError:
                    self.log('restore_pid already dead')

            else:
                # if bcb-restore hasn't stopped yet, then kill it
                if restore_process.poll() is None:
                    self.log('killing restore')
                    restore_process.terminate()

                # wait until restore terminates
                restore_process.wait()
                self.log(f'restore return code: {restore_process.returncode}')
        except:  # 'bare except' because it catches more than "except Exception"
            self.log(f'error while stopping restore\n{format_exc()}')
            self.log(f'error while stopping restore\n{format_exc()}')
예제 #9
0
def start_fake_restore():
    '''
        Start a program which has the restore program's name,
        but just keeps itself running for a few minutes
        so we can test for the app to be running.

        >>> start_fake_restore()
        >>> bin_dir = os.path.join(virtualenv_dir(), 'bin')
        >>> sleep(15)
        >>> args = [os.path.join(bin_dir, 'killmatch'), constants.RESTORE_PROGRAM]
        >>> result = command.run(*args)
    '''

    bin_dir = os.path.join(virtualenv_dir(), 'bin')
    config_dir = os.path.join(PROJECT_PATH, 'config')
    args = [os.path.join(bin_dir, constants.RESTORE_PROGRAM), config_dir, '/tmp']
    command.background(*args)
예제 #10
0
    def start_backup(self):
        '''
            Start backup.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> test_utils.init_database()
            >>> backup_task = BackupTask()
            >>> backup_task.manager = BitcoinManager(backup_task.log_name)
            >>> backup_task.prep_backup()
            >>> backup_process, backup_pid = backup_task.start_backup()
            >>> backup_process is not None
            True
            >>> backup_pid is None
            True
            >>> test_utils.stop_backup()
        '''
        bin_dir = os.path.join(virtualenv_dir(), 'bin')
        data_dir = self.manager.data_dir
        if not data_dir.endswith(os.sep):
            data_dir += os.sep

        if is_backup_running():
            backup_process = None
            backup_pid = get_pid(constants.BACKUP_PROGRAM)
            self.log('{} is already running using pid: {}'.format(
                constants.BACKUP_PROGRAM, backup_pid))
        else:
            backup_pid = None

            args = []
            # "bcb-backup" is a link to safecopy so we can distinguish it when we kill it
            args.append(os.path.join(bin_dir, constants.BACKUP_PROGRAM))
            args.append('--exclude')
            args.append(get_excluded_files())
            args.append('--verbose')
            args.append('--quick')
            args.append('--delete')
            args.append(f'{data_dir}*')
            args.append(self.to_backup_dir)

            # Popen appears to report "'list' object has no attribute 'split'"
            # the docs state Popen should pass a sequence as the first arg
            backup_process = Popen(args, stdout=PIPE, universal_newlines=True)

        return backup_process, backup_pid