Exemple #1
0
    def restore_files_and_dirs(self):
        '''
            Restore files and directories to
            a previous state of the blockchain.

            >>> 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)
            >>> restore_task.restore_files_and_dirs()
            True
            >>> test_utils.stop_restore()
            >>> test_utils.start_fake_restore()
            >>> restore_task = RestoreTask(restore_dir)
            >>> restore_task.manager = BitcoinManager(restore_task.log_name)
            >>> restore_task.restore_files_and_dirs()
            True
            >>> test_utils.stop_restore()
        '''

        ok = True
        try:
            if bitcoin_utils.is_restore_running():
                restore_pid = get_pid(constants.RESTORE_PROGRAM)
                restore_process = None
                self.log('{} is already running using pid: {}'.format(
                    constants.RESTORE_PROGRAM, restore_pid))
            else:
                self.log('starting restore')
                restore_process = self.start_restore()
                restore_pid = None

            if restore_process is not None or restore_pid is not None:
                self.wait_for_restore(restore_process)

                self.stop_restore(restore_process, restore_pid)
            else:
                self.manager.update_progress(self.RESTORE_UNABLE_TO_START)
                ok = False
        except:  # 'bare except' because it catches more than "except Exception"
            ok = False
            self.log(format_exc())

        if not ok:
            self.manager.update_progress(self.RESTORE_ERROR)

        return ok
Exemple #2
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
    def start_bitcoind(self):
        '''
            Start bitcoind as a daemon.

            >>> from blockchain_backup.bitcoin.tests import utils as test_utils
            >>> need_backup = False
            >>> test_utils.init_database()
            >>> update_task = UpdateTask()
            >>> update_task.manager = BitcoinManager(update_task.log_name)
            >>> bitcoind_process, bitcoind_pid = update_task.start_bitcoind()
            >>> update_task.stop_bitcoind(bitcoind_process, bitcoind_pid, need_backup)
            (False, ' Error opening block database.\\n')
        '''
        if is_bitcoind_running():
            bitcoind_process = None
            bitcoind_pid = get_pid(bitcoind())
            if bitcoind_pid is None:
                sleep(5)
                bitcoind_pid = get_pid(bitcoind())
            self.log(f'bitcoind is already running using pid: {bitcoind_pid}')
        else:
            bitcoind_pid = None
            command_args = []

            if self.manager.bin_dir is None:
                command_args.append(bitcoind())
                ok = True
            else:
                cmd = os.path.join(self.manager.bin_dir, bitcoind())
                command_args.append(cmd)
                ok = os.path.exists(cmd)

            if ok:
                extra_args = preferences.get_extra_args()
                use_test_net = '-testnet' in extra_args

                if self.manager.data_dir is not None:
                    data_dir = self.manager.data_dir
                    if use_test_net and data_dir.endswith(
                            constants.TEST_NET_SUBDIR):
                        data_dir = data_dir[:data_dir.rfind(constants.
                                                            TEST_NET_SUBDIR)]
                    command_args.append(f'-datadir={data_dir}')

                # don't allow any interaction with the user's wallet
                command_args.append('-disablewallet')

                if extra_args:
                    for extra_arg in extra_args:
                        command_args.append(extra_arg)

                command_args.append('-daemon')

                try:
                    bitcoind_process = Popen(command_args)
                    self.log(
                        f'bitcoind started: {bitcoind_process is not None}')
                except FileNotFoundError as fnfe:
                    raise BitcoinException(str(fnfe))

            else:
                bitcoind_process = None
                self.log(
                    f'{bitcoind()} does not exist in {self.manager.bin_dir}')

        state.set_start_access_time(now())

        return bitcoind_process, bitcoind_pid
Exemple #4
0
    def run_qt(self):
        '''
            Run bitcon-qt.
        '''
        ok = False
        error_message = None

        self.manager.update_menu(constants.DISABLE_ITEM)

        try:
            command_args = self.get_launch_args()
            if command_args is None:
                ok = False
            else:
                self.manager.rename_logs()

                state.set_start_access_time(now())

                self.log(f'starting bitcoin-qt: {command_args}')
                os.putenv('DISPLAY', ':0.0')

                if bitcoin_utils.is_bitcoin_qt_running():
                    bitcoin_pid = get_pid(bitcoin_utils.bitcoin_qt())
                    bitcoin_process = None
                else:
                    bitcoin_pid = None
                    bitcoin_process = Popen(command_args)

                if bitcoin_process is not None or bitcoin_pid is not None:
                    self.wait_for_close(bitcoin_process)
                    state.set_last_access_time(now())
                    ok = True
                else:
                    self.manager.update_progress(self.BITCOIN_QT_OTHER_APP_RUNNING)
                    ok = False

        except CalledProcessError as cpe:
            ok = False
            stdout = cpe.stdout
            if stdout and not isinstance(stdout, str):
                stdout = stdout.decode()
            stderr = cpe.stderr
            if stderr and not isinstance(stderr, str):
                stderr = stderr.decode()
            __, error_message, log_message = self.manager.process_bitcoin_cli_error(
              'getblockchaininfo', cpe.returncode, stdout, stderr)
            if error_message is None:
                error_message = log_message
            self.log(error_message)

        except BitcoinException as be:
            ok = False
            error_message = str(be)
            self.log(error_message)

        except FileNotFoundError as fnfe:
            ok = False
            error_message = str(fnfe)
            self.log(error_message)

        except Exception:
            self.log(format_exc())

        if ok:
            # check the logs to make sure everything was ok
            ok, error_message = self.manager.bitcoin_finished_ok(
              bitcoin_utils.is_bitcoin_qt_running)

        if ok:
            if self.current_block > 0:
                state.set_last_block_updated(self.current_block)

        else:
            if error_message is None:
                error_message = ''

            self.manager.update_subnotice('{} {}'.format(
               self.BITCOIN_QT_ERROR_LABEL, error_message))

        self.manager.update_progress(' ')

        return ok, error_message