Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Exit with error if the backup id doesn't exist.
:param Server server: server object to search for the required backup
:param args: command lien arguments namespace
:rtype: barman.infofile.LocalBackupInfo
"""
if args.backup_id in ('latest', 'last'):
backup_id = server.get_last_backup_id()
elif args.backup_id in ('oldest', 'first'):
backup_id = server.get_first_backup_id()
else:
backup_id = args.backup_id
backup_info = server.get_backup(backup_id)
if backup_info is None:
output.error(
"Unknown backup '%s' for server '%s'",
args.backup_id, server.config.name)
output.close_and_exit()
return backup_info
# Handle remote recovery options
if remote_command:
recovery_info['recovery_dest'] = 'remote'
recovery_info['rsync'] = RsyncPgData(
path=self.server.path,
ssh=remote_command,
bwlimit=self.config.bandwidth_limit,
network_compression=self.config.network_compression)
try:
# create a UnixRemoteCommand obj if is a remote recovery
recovery_info['cmd'] = UnixRemoteCommand(remote_command,
path=self.server.path)
except FsOperationFailed:
output.error(
"Unable to connect to the target host using the command "
"'%s'", remote_command)
output.close_and_exit()
else:
# if is a local recovery create a UnixLocalCommand
recovery_info['cmd'] = UnixLocalCommand()
return recovery_info
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 = barman.__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'"
show_server,
replication_status,
status,
switch_wal,
switch_xlog,
sync_info,
sync_backup,
sync_wals,
]
)
# noinspection PyBroadException
try:
p.dispatch(pre_call=global_config)
except KeyboardInterrupt:
msg = "Process interrupted by user (KeyboardInterrupt)"
output.error(msg)
except Exception as e:
msg = "%s\nSee log file for more details." % e
output.exception(msg)
# cleanup output API and exit honoring output.error_occurred and
# output.error_exit_code
output.close_and_exit()
# barman global config
diagnosis['global']['config'] = dict(barman.__config__._global_config)
diagnosis['global']['config']['errors_list'] = errors_list
try:
command = fs.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']['barman_ver'] = barman.__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 '%s'" % 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 = fs.UnixRemoteCommand(
ssh_command=server.config.ssh_command,
path=server.path
)
diagnosis['servers'][name]['system_info'] = (
command.get_system_info())
except FsOperationFailed:
pass
"slot_name configuration option required")
return
output.info(
"Dropping physical replication slot '%s' on server '%s'",
self.config.slot_name,
self.config.name)
try:
self.streaming.drop_repslot(self.config.slot_name)
output.info("Replication slot '%s' dropped", self.config.slot_name)
except PostgresInvalidReplicationSlot:
output.error("Replication slot '%s' does not exist",
self.config.slot_name)
except PostgresReplicationSlotInUse as exc:
output.error(
"Cannot drop replication slot '%s' on server '%s' "
"because it is in use.",
self.config.slot_name,
self.config.name)
except PostgresException as exc:
output.error(
"Cannot drop replication slot '%s' on server '%s': %s",
self.config.slot_name,
self.config.name,
str(exc).strip())
self._purge_unused_wal_files(backup_info)
# Start the copy
self.current_action = "copying files"
self._start_backup_copy_message(backup_info)
self.backup_copy(backup_info)
self._stop_backup_copy_message(backup_info)
# Try again to purge eventually unused WAL files. At this point
# the begin_wal value is surely known. Doing it twice is safe
# because this function is useful only during the first backup.
self._purge_unused_wal_files(backup_info)
except BaseException:
# we do not need to do anything here besides re-raising the
# exception. It will be handled in the external try block.
output.error("The backup has failed %s", self.current_action)
raise
else:
self.current_action = "issuing stop of the backup"
finally:
output.info("Asking PostgreSQL server to finalize the backup.")
try:
self.strategy.stop_backup(backup_info)
except BaseException:
self._update_action_from_strategy()
raise
if wal_file:
if os.path.exists(self.get_wal_full_path(wal_file)):
break
else:
# Check if any new file has been archived, on any timeline
wals = self.backup_manager.get_latest_archived_wals_info()
current_wals = dict([(tli, wals[tli].name) for tli in wals])
if current_wals != initial_wals:
break
# sleep a bit before retrying
time.sleep(.1)
else:
if wal_file:
output.error("The WAL file %s has not been received "
"in %s seconds",
wal_file, archive_timeout)
else:
output.info(
"A WAL file has not been received in %s seconds",
archive_timeout)
def check_backup(self, backup_info):
"""
Make sure that we have all the WAL files required
by a physical backup for consistencty (from the
first to the last WAL file)
:param backup_info: the target backup
"""
output.debug("Checking backup %s of server %s",
backup_info.backup_id, self.config.name)
try:
# No need to check a backup which is not waiting for WALs.
# Doing that we could also mark as DONE backups which
# were previously FAILED due to copy errors
if backup_info.status == BackupInfo.FAILED:
output.error(
"The validity of a failed backup cannot be checked")
return
# Take care of the backup lock.
# Only one process can modify a backup a a time
with ServerBackupIdLock(self.config.barman_lock_directory,
self.config.name,
backup_info.backup_id):
orig_status = backup_info.status
self.backup_manager.check_backup(backup_info)
if orig_status == backup_info.status:
output.debug(
"Check finished: the status of backup %s of server %s "
"remains %s",
backup_info.backup_id,
self.config.name,
output.error("Unknown server '%s'" % name)
return False
if not server.config.active:
# Report inactive server as error
if inactive_is_error:
output.error('Inactive server: %s' % server.config.name)
if skip_inactive:
return False
# Report disabled server as error
if server.config.disabled:
# Output all the messages as errors, and exit terminating the run.
if disabled_is_error:
for message in server.config.msg_list:
output.error(message)
if skip_disabled:
return False
# All ok, execute the command
return True