def handler(line): if line: if prefix: output.info("{prefix}{line}".format(prefix=prefix, line=line)) else: output.info("{}".format(line))
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
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()
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))
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()
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()
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()
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