Exemple #1
0
 def handler(line):
     if line:
         if prefix:
             output.info("{prefix}{line}".format(prefix=prefix,
                                                 line=line))
         else:
             output.info("{}".format(line))
Exemple #2
0
    def stop_backup(self, backup_info):
        """
        Manage the stop of an pg_basebackup backup

        The method retrieves the information necessary for the
        backup.info file reading the backup_label file.

        Due of the nature of the pg_basebackup, information that are gathered
        during the start of a backup performed using rsync, are retrieved
        here

        :param barman.infofile.LocalBackupInfo backup_info: backup information
        """
        self._read_backup_label(backup_info)
        self._backup_info_from_backup_label(backup_info)

        # Set data in backup_info from current_xlog_info
        self.current_action = "stopping postgres backup_method"
        output.info("Finalising the backup.")

        # Get the current xlog position
        current_xlog_info = self.postgres.current_xlog_info
        if current_xlog_info:
            self._backup_info_from_stop_location(backup_info,
                                                 current_xlog_info)

        # Ask PostgreSQL to switch to another WAL file. This is needed
        # to archive the transaction log file containing the backup
        # end position, which is required to recover from the backup.
        try:
            self.postgres.switch_wal()
        except PostgresIsInRecovery:
            # Skip switching XLOG if a standby server
            pass
Exemple #3
0
def get_wal(args):
    """
    Retrieve WAL_NAME file from SERVER_NAME archive.
    The content will be streamed on standard output unless
    the --output-directory option is specified.
    """
    server = get_server(args, inactive_is_error=True)

    if getattr(args, 'test', None):
        output.info("Ready to retrieve WAL files from the server %s",
                    server.config.name)
        return

    # Retrieve optional arguments. If an argument is not specified,
    # the namespace doesn't contain it due to SUPPRESS default.
    # In that case we pick 'None' using getattr third argument.
    compression = getattr(args, 'compression', None)
    output_directory = getattr(args, 'output_directory', None)
    peek = getattr(args, 'peek', None)

    with closing(server):
        server.get_wal(args.wal_name,
                       compression=compression,
                       output_directory=output_directory,
                       peek=peek,
                       partial=args.partial)
    output.close_and_exit()
Exemple #4
0
def exec_diagnose(servers, errors_list):
    """
    Diagnostic command: gathers information from backup server
    and from all the configured servers.

    Gathered information should be used for support and problems detection

    :param dict(str,frabit.server.Server) servers: list of configured servers
    :param list errors_list: list of global errors
    """
    # global section. info about frabit server
    diagnosis = {'global': {}, 'servers': {}}
    # frabit global config
    diagnosis['global']['config'] = dict(frabit.__config__._global_config)
    diagnosis['global']['config']['errors_list'] = errors_list
    try:
        command = filesystem.UnixLocalCommand()
        # basic system info
        diagnosis['global']['system_info'] = command.get_system_info()
    except CommandFailedException as e:
        diagnosis['global']['system_info'] = {'error': repr(e)}
    diagnosis['global']['system_info']['frabit_ver'] = frabit.__version__
    diagnosis['global']['system_info']['timestamp'] = datetime.datetime.now()
    # per server section
    for name in sorted(servers):
        server = servers[name]
        if server is None:
            output.error("Unknown server '{}'".format(name))
            continue
        # server configuration
        diagnosis['servers'][name] = {}
        diagnosis['servers'][name]['config'] = vars(server.config)
        del diagnosis['servers'][name]['config']['config']
        # server system info
        if server.config.ssh_command:
            try:
                command = filesystem.UnixRemoteCommand( ssh_command=server.config.ssh_command, path=server.path)
                diagnosis['servers'][name]['system_info'] = (command.get_system_info())
            except FsOperationFailed:
                pass
        # frabit status information for the server
        diagnosis['servers'][name]['status'] = server.get_remote_status()
        # backup list
        backups = server.get_available_backups(BackupInfo.STATUS_ALL)
        diagnosis['servers'][name]['backups'] = backups
        # wal status
        diagnosis['servers'][name]['wals'] = {
            'last_archived_wal_per_timeline':
                server.backup_manager.get_latest_archived_wals_info(),
        }
        # Release any PostgreSQL resource
        server.close()
    output.info(json.dumps(diagnosis, cls=FrabitEncoder, indent=4,
                           sort_keys=True))
Exemple #5
0
def list_files(args):
    """
    List all the files for a single backup
    """
    server = get_server(args)

    # Retrieves the backup
    backup_info = parse_backup_id(server, args)
    try:
        for line in backup_info.get_list_of_files(args.target):
            output.info(line, log=False)
    except BinlogHasPurged as e:
        output.error(
            "invalid xlog segment name %r\n"
            "HINT: Please run \"barman rebuild-xlogdb %s\" "
            "to solve this issue", force_str(e), server.config.name)
        output.close_and_exit()
Exemple #6
0
def put_wal(args):
    """
    Receive a WAL file from SERVER_NAME and securely store it in the incoming
    directory. The file will be read from standard input in tar format.
    """
    server = get_server(args, inactive_is_error=True)

    if getattr(args, 'test', None):
        output.info("Ready to accept WAL files for the server %s",
                    server.config.name)
        return

    try:
        # Python 3.x
        stream = sys.stdin.buffer
    except AttributeError:
        # Python 2.x
        stream = sys.stdin
    with closing(server):
        server.put_wal(stream)
    output.close_and_exit()
Exemple #7
0
def sync_info(args):
    """
    Output the internal synchronisation status.
    Used to sync_backup with a passive node
    """
    server = get_server(args)
    try:
        # if called with --primary option
        if getattr(args, 'primary', False):
            primary_info = server.primary_node_info(args.last_wal,
                                                    args.last_position)
            output.info(json.dumps(primary_info, cls=FrabitEncoder, indent=4),
                        log=False)
        else:
            server.sync_status(args.last_wal, args.last_position)
    except SyncError as e:
        # Catch SyncError exceptions and output only the error message,
        # preventing from logging the stack trace
        output.error(e)

    output.close_and_exit()
Exemple #8
0
def get_server_list(args=None,
                    skip_inactive=False,
                    skip_disabled=False,
                    skip_passive=False,
                    on_error_stop=True,
                    suppress_error=False):
    """
    Get the server list from the configuration

    If args the parameter is None or arg.server_name is ['all']
    returns all defined servers

    :param args: an argparse namespace containing a list server_name parameter
    :param bool skip_inactive: skip inactive servers when 'all' is required
    :param bool skip_disabled: skip disabled servers when 'all' is required
    :param bool skip_passive: skip passive servers when 'all' is required
    :param bool on_error_stop: stop if an error is found
    :param bool suppress_error: suppress display of errors (e.g. diagnose)
    :rtype: dict[str,Server]
    """
    server_dict = {}

    # This function must to be called with in a multiple-server context
    assert not args or isinstance(args.server_name, list)

    # Generate the list of servers (required for global errors)
    available_servers = frabit.__config__.server_names()

    # Get a list of configuration errors from all the servers
    global_error_list = frabit.__config__.servers_msg_list

    # Global errors have higher priority
    if global_error_list:
        # Output the list of global errors
        if not suppress_error:
            for error in global_error_list:
                output.error(error)

        # If requested, exit on first error
        if on_error_stop:
            output.close_and_exit()
            # The following return statement will never be reached
            # but it is here for clarity
            return {}

    # Handle special 'all' server cases
    # - args is None
    # - 'all' special name
    if not args or 'all' in args.server_name:
        # When 'all' is used, it must be the only specified argument
        if args and len(args.server_name) != 1:
            output.error("You cannot use 'all' with other server names")
        servers = available_servers
    else:
        # Put servers in a set, so multiple occurrences are counted only once
        servers = set(args.server_name)

    # Loop through all the requested servers
    for server in servers:
        conf = frabit.__config__.get_server(server)
        if conf is None:
            # Unknown server
            server_dict[server] = None
        else:
            server_object = Server(conf)
            # Skip inactive servers, if requested
            if skip_inactive and not server_object.config.active:
                output.info("Skipping inactive server '%s'" % conf.name)
                continue
            # Skip disabled servers, if requested
            if skip_disabled and server_object.config.disabled:
                output.info("Skipping temporarily disabled server '%s'" %
                            conf.name)
                continue
            # Skip passive nodes, if requested
            if skip_passive and server_object.replica_node:
                output.info("Skipping passive server '%s'", conf.name)
                continue
            server_dict[server] = server_object

    return server_dict