Commit beafa831 authored by Marco Nenciarini's avatar Marco Nenciarini

Update upstream source from tag 'upstream/2.7'

Update to upstream version '2.7'
with Debian dir 606bf96d1daf7b7de6fc8ee0bb6808e4a9d59ffe
parents 109b95a5 da669815
2019-03-20 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Update the ChangeLog file
Update NEWS file for release 2.7
Version set to 2.7
Add utility script to set a new barman version
Remove obsolete rpp packagin files
2019-03-19 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Make `barman cron` resilient to unhandled exceptions
Before this patch, any unhandled exceptions raised during the handling
of a server, would have terminated the cron, preventing any other
maintenance operation required by subsequent servers.
Now the exception is logged and the cron continues with eventual other
servers.
Thanks to Martín Marqués for the analysis.
Closes: #202
Clarify cron error message on primary server connection failures
This patch also avoids to propagate and log the SyncError exception.
Fixes: #202
Update import sorting using latest isort
2019-03-01 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Fix error handling exceptions containing non-ascii error messages
Fixes #194
Fix broken unit test (s/asset_called/assert_called/)
2019-02-17 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Avoid failing if the output contains non ascii characters
Fixes #196
2019-02-22 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Fix backup validation in PostgreSQL older than 9.2
2019-02-05 tomascassidy <tomascassidy@users.noreply.github.com>
Fix typo in passive-server.conf-template
2019-02-14 Luc Didry <luc@didry.org>
Fix doc typo
2019-02-21 Giulio Calacoci <giulio.calacoci@2ndquadrant.it>
Set version to 2.7a1
2019-02-17 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Make CommandMaxRetryExceeded exception serializable
The CommandMaxRetryExceeded could be raised by one of the parallel
worker subprocesses, and if not serializable it causes a failure
reporting the error.
Fixes: #199
2019-02-17 Gabriele Bartolini <gabriele.bartolini@2ndQuadrant.it>
Ignore history/backup/partial files for first sync of geo-redundancy
Fixes #198
2019-02-06 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Manual: fix example of archiving with barman-wal-archive
2019-01-31 Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
Update the ChangeLog file
......
Barman News - History of user-visible changes
Copyright (C) 2011-2018 2ndQuadrant Limited
Copyright (C) 2011-2019 2ndQuadrant Limited
Version 2.7 - 21 Mar 2019
- Fix error handling during the parallel backup. Previously an
unrecoverable error during the copy could have corrupted the barman
internal state, requiring a manual kill of barman process with
SIGTERM and a manual cleanup of the running backup in PostgreSQL.
(GH#199)
- Fix support of UTF-8 characters in input and output (GH#194 and
GH#196)
- Ignore history/backup/partial files for first sync of geo-redundancy
(GH#198)
- Fix network failure with geo-redundancy causing cron to break
(GH#202)
- Fix backup validation in PostgreSQL older than 9.2
- Various documentation fixes
Version 2.6 - 4 Feb 2019
......
Metadata-Version: 1.1
Name: barman
Version: 2.6
Version: 2.7
Summary: Backup and Recovery Manager for PostgreSQL
Home-page: http://www.pgbarman.org/
Author: 2ndQuadrant Limited
......
Metadata-Version: 1.1
Name: barman
Version: 2.6
Version: 2.7
Summary: Backup and Recovery Manager for PostgreSQL
Home-page: http://www.pgbarman.org/
Author: 2ndQuadrant Limited
......
......@@ -191,14 +191,4 @@ doc/manual/66-about.en.md
doc/manual/70-feature-matrix.en.md
doc/manual/99-references.en.md
doc/manual/Makefile
rpm/barman.spec
rpm/rhel5/python-dateutil-1.4.1-remove-embedded-timezone-data.patch
rpm/rhel5/python26-argcomplete.spec
rpm/rhel5/python26-argh.spec
rpm/rhel5/python26-dateutil.spec
rpm/rhel5/python26-psycopg2.spec
rpm/rhel5/setup.cfg.patch
rpm/rhel6/python-argcomplete.spec
rpm/rhel6/python-argh.spec
rpm/rhel7/python-argh.spec
scripts/barman.bash_completion
\ No newline at end of file
......@@ -20,6 +20,7 @@ The main Barman module
"""
from __future__ import absolute_import
from .version import __version__
__config__ = None
......
......@@ -43,8 +43,8 @@ from barman.infofile import BackupInfo, WalFileInfo
from barman.lockfile import ServerBackupSyncLock
from barman.recovery_executor import RecoveryExecutor
from barman.remote_status import RemoteStatusMixin
from barman.utils import (fsync_dir, fsync_file, human_readable_timedelta,
pretty_size)
from barman.utils import (force_str, fsync_dir, fsync_file,
human_readable_timedelta, pretty_size)
_logger = logging.getLogger(__name__)
......@@ -73,7 +73,7 @@ class BackupManager(RemoteStatusMixin):
self.executor = RsyncBackupExecutor(self)
except SshCommandException as e:
self.config.disabled = True
self.config.msg_list.append(str(e).strip())
self.config.msg_list.append(force_str(e).strip())
@property
def mode(self):
......@@ -418,7 +418,7 @@ class BackupManager(RemoteStatusMixin):
# Use BaseException instead of Exception to catch events like
# KeyboardInterrupt (e.g.: CTRL-C)
except BaseException as e:
msg_lines = str(e).strip().splitlines()
msg_lines = force_str(e).strip().splitlines()
if backup_info:
# Use only the first line of exception message
# in backup_info error field
......@@ -1067,13 +1067,12 @@ class BackupManager(RemoteStatusMixin):
# Check the intersection between the required WALs and the archived
# ones. They should all exist
bound_end = min(last_archived_wal, end_wal)
segments = xlog.generate_segment_names(
begin_wal,
bound_end,
xlog_segment_size=backup_info.xlog_segment_size)
segments = backup_info.get_required_wal_segments()
missing_wal = None
for wal in segments:
# Stop checking if we reach the last archived wal
if wal > last_archived_wal:
break
wal_full_path = self.server.get_wal_full_path(wal)
if not os.path.exists(wal_full_path):
missing_wal = wal
......
......@@ -47,8 +47,8 @@ from barman.exceptions import (CommandFailedException, DataTransferFailure,
from barman.fs import UnixRemoteCommand
from barman.infofile import BackupInfo
from barman.remote_status import RemoteStatusMixin
from barman.utils import (human_readable_timedelta, mkpath, total_seconds,
with_metaclass)
from barman.utils import (force_str, human_readable_timedelta, mkpath,
total_seconds, with_metaclass)
_logger = logging.getLogger(__name__)
......@@ -780,7 +780,7 @@ class SshBackupExecutor(with_metaclass(ABCMeta, BackupExecutor)):
path=self.server.path)
minimal_ssh_output = ''.join(cmd.get_last_output())
except FsOperationFailed as e:
hint = str(e).strip()
hint = force_str(e).strip()
# Output the result
check_strategy.result(self.config.name, cmd is not None, hint=hint)
......@@ -941,7 +941,7 @@ class PassiveBackupExecutor(BackupExecutor):
path=self.server.path)
minimal_ssh_output = ''.join(cmd.get_last_output())
except FsOperationFailed as e:
hint = str(e).strip()
hint = force_str(e).strip()
# Output the result
check_strategy.result(self.config.name, cmd is not None, hint=hint)
......
......@@ -37,7 +37,7 @@ from barman.exceptions import BadXlogSegmentName, RecoveryException, SyncError
from barman.infofile import BackupInfo
from barman.server import Server
from barman.utils import (BarmanEncoder, configure_logging, drop_privileges,
parse_log_level)
force_str, parse_log_level)
_logger = logging.getLogger(__name__)
......@@ -141,7 +141,16 @@ def cron():
# server is None and to report inactive and disabled servers,
# but here we have only active and well configured servers.
server.cron()
try:
server.cron()
except Exception:
# A cron should never raise an exception, so this code
# should never be executed. However, it is here to protect
# unrelated servers in case of unexpected failures.
output.exception(
"Unable to run cron on server '%s', "
"please look in the barman log file for more details.",
name)
output.close_and_exit()
......@@ -521,7 +530,7 @@ def recover(args):
target_action=getattr(args, 'target_action', None),
standby_mode=getattr(args, 'standby_mode', None))
except RecoveryException as exc:
output.error(str(exc))
output.error(force_str(exc))
output.close_and_exit()
......@@ -784,7 +793,7 @@ def list_files(args):
"invalid xlog segment name %r\n"
"HINT: Please run \"barman rebuild-xlogdb %s\" "
"to solve this issue",
str(e), server.config.name)
force_str(e), server.config.name)
output.close_and_exit()
......
......@@ -298,7 +298,7 @@ class Command(object):
# there is still an error, exit raising
# a CommandMaxRetryExceeded exception and wrap the
# original one
raise CommandMaxRetryExceeded(exc)
raise CommandMaxRetryExceeded(*exc.args)
def _get_output_once(self, *args, **kwargs):
"""
......
......@@ -30,7 +30,7 @@ import barman.infofile
from barman.command_wrappers import Command
from barman.exceptions import (CommandFailedException,
CompressionIncompatibility)
from barman.utils import with_metaclass
from barman.utils import force_str, with_metaclass
_logger = logging.getLogger(__name__)
......@@ -217,7 +217,8 @@ class InternalCompressor(Compressor):
shutil.copyfileobj(istream, ostream)
except Exception as e:
# you won't get more information from the compressors anyway
raise CommandFailedException(dict(ret=None, err=str(e), out=None))
raise CommandFailedException(dict(
ret=None, err=force_str(e), out=None))
return 0
def decompress(self, src, dst):
......@@ -233,7 +234,8 @@ class InternalCompressor(Compressor):
shutil.copyfileobj(istream, ostream)
except Exception as e:
# you won't get more information from the compressors anyway
raise CommandFailedException(dict(ret=None, err=str(e), out=None))
raise CommandFailedException(dict(
ret=None, err=force_str(e), out=None))
return 0
@abstractmethod
......
......@@ -143,12 +143,6 @@ class CommandMaxRetryExceeded(CommandFailedException):
"""
A command with retry_times > 0 has exceeded the number of available retry
"""
def __init__(self, exc):
"""
:param Exception exc: the last exception raised by the command
"""
self.exc = exc
super(CommandMaxRetryExceeded, self).__init__(*exc.args)
class RsyncListFilesFailure(CommandException):
......@@ -182,7 +176,8 @@ class DataTransferFailure(CommandException):
return cls(details)
except (TypeError, NameError):
# If it is not a dictionary just convert it to a string
return cls(str(e.args))
from barman.utils import force_str
return cls(force_str(e.args))
class CompressionIncompatibility(CompressionException):
......
......@@ -26,6 +26,7 @@ import time
from barman import version
from barman.command_wrappers import Command
from barman.exceptions import AbortedRetryHookScript, UnknownBackupIdException
from barman.utils import force_str
_logger = logging.getLogger(__name__)
......@@ -64,7 +65,7 @@ class HookScriptRunner(object):
'BARMAN_RETRY': str(1 if self.retry else 0),
})
if self.error:
self.environment['BARMAN_ERROR'] = str(self.error)
self.environment['BARMAN_ERROR'] = force_str(self.error)
if self.phase:
self.environment['BARMAN_PHASE'] = self.phase
script_config_name = "%s_%s" % (self.phase, self.name)
......@@ -123,7 +124,7 @@ class HookScriptRunner(object):
'BARMAN_SIZE': str(wal_info.size),
'BARMAN_TIMESTAMP': str(wal_info.time),
'BARMAN_COMPRESSION': wal_info.compression or '',
'BARMAN_ERROR': str(error or '')
'BARMAN_ERROR': force_str(error or '')
})
def env_from_recover(self, backup_info, dest, tablespaces, remote_command,
......@@ -158,7 +159,7 @@ class HookScriptRunner(object):
'BARMAN_TABLESPACES': tablespaces_map,
'BARMAN_REMOTE_COMMAND': str(remote_command or ''),
'BARMAN_RECOVER_OPTIONS': recover_options,
'BARMAN_ERROR': str(error or '')
'BARMAN_ERROR': force_str(error or '')
})
def run(self):
......
......@@ -367,17 +367,36 @@ class ConsoleOutputWriter(object):
#: The server is active
self.active = True
def _print(self, message, args, stream):
"""
Print an encoded message on the given output stream
"""
# Make sure to add a newline at the end of the message
if message is None:
message = '\n'
else:
message += '\n'
# Format and encode the message
encoded_msg = _format_message(message, args).encode('utf-8')
try:
# Python 3.x
stream.buffer.write(encoded_msg)
except AttributeError:
# Python 2.x
stream.write(encoded_msg)
stream.flush()
def _out(self, message, args):
"""
Print a message on standard output
"""
print(_format_message(message, args), file=sys.stdout)
self._print(message, args, sys.stdout)
def _err(self, message, args):
"""
Print a message on standard error
"""
print(_format_message(message, args), file=sys.stderr)
self._print(message, args, sys.stderr)
def is_quiet(self):
"""
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ from barman.exceptions import (BadXlogSegmentName, CommandFailedException,
RecoveryTargetActionException)
from barman.fs import UnixLocalCommand, UnixRemoteCommand
from barman.infofile import BackupInfo
from barman.utils import mkpath
from barman.utils import force_str, mkpath
# generic logger for this module
_logger = logging.getLogger(__name__)
......@@ -226,7 +226,7 @@ class RecoveryExecutor(object):
"invalid xlog segment name %r\n"
"HINT: Please run \"barman rebuild-xlogdb %s\" "
"to solve this issue",
str(e), self.config.name)
force_str(e), self.config.name)
output.close_and_exit()
# If WAL files are put directly in the pg_xlog directory,
# avoid shipping of just recovered files
......
......@@ -61,9 +61,9 @@ from barman.postgres import PostgreSQLConnection, StreamingConnection
from barman.process import ProcessManager
from barman.remote_status import RemoteStatusMixin
from barman.retention_policies import RetentionPolicyFactory
from barman.utils import (BarmanEncoder, file_md5, fsync_dir, fsync_file,
human_readable_timedelta, is_power_of_two, mkpath,
pretty_size, timeout)
from barman.utils import (BarmanEncoder, file_md5, force_str, fsync_dir,
fsync_file, human_readable_timedelta,
is_power_of_two, mkpath, pretty_size, timeout)
from barman.wal_archiver import (FileWalArchiver, StreamingWalArchiver,
WalArchiver)
......@@ -235,7 +235,7 @@ class Server(RemoteStatusMixin):
except ConninfoException as e:
self.config.disabled = True
self.config.msg_list.append(
"PostgreSQL connection: " + str(e).strip())
"PostgreSQL connection: " + force_str(e).strip())
# ARCHIVER_OFF_BACKCOMPATIBILITY - START OF CODE
# IMPORTANT: This is a back-compatibility feature that has
......@@ -282,7 +282,7 @@ class Server(RemoteStatusMixin):
except ConninfoException as e:
self.config.disabled = True
self.config.msg_list.append(
"Streaming connection: " + str(e).strip())
"Streaming connection: " + force_str(e).strip())
# Initialize the StreamingWalArchiver
# WARNING: Order of items in self.archivers list is important!
......@@ -1127,7 +1127,7 @@ class Server(RemoteStatusMixin):
"invalid WAL segment name %r\n"
"HINT: Please run \"barman rebuild-xlogdb %s\" "
"to solve this issue",
str(e), self.config.name)
force_str(e), self.config.name)
if self.enforce_retention_policies and \
retention_status[backup.backup_id] != BackupInfo.VALID:
rstatus = retention_status[backup.backup_id]
......@@ -1859,7 +1859,7 @@ class Server(RemoteStatusMixin):
except PostgresException as exc:
msg = "Cannot connect to server '%s'" % self.config.name
output.error(msg, log=False)
_logger.error("%s: %s", msg, str(exc).strip())
_logger.error("%s: %s", msg, force_str(exc).strip())
return
if not self.config.slot_name:
......@@ -1888,7 +1888,7 @@ class Server(RemoteStatusMixin):
"Cannot create replication slot '%s' on server '%s': %s",
self.config.slot_name,
self.config.name,
str(exc).strip())
force_str(exc).strip())
def drop_repslot(self):
"""
......@@ -1910,7 +1910,7 @@ class Server(RemoteStatusMixin):
except PostgresException as exc:
msg = "Cannot connect to server '%s'" % self.config.name
output.error(msg, log=False)
_logger.error("%s: %s", msg, str(exc).strip())
_logger.error("%s: %s", msg, force_str(exc).strip())
return
if not self.config.slot_name:
......@@ -1940,7 +1940,7 @@ class Server(RemoteStatusMixin):
"Cannot drop replication slot '%s' on server '%s': %s",
self.config.slot_name,
self.config.name,
str(exc).strip())
force_str(exc).strip())
def receive_wal(self, reset=False):
"""
......@@ -2118,7 +2118,7 @@ class Server(RemoteStatusMixin):
"invalid xlog segment name %r\n"
"HINT: Please run \"barman rebuild-xlogdb %s\" "
"to solve this issue",
str(e), self.config.name)
force_str(e), self.config.name)
output.close_and_exit()
@staticmethod
......@@ -2483,8 +2483,13 @@ class Server(RemoteStatusMixin):
sync_wal_info = self.load_sync_wals_info()
# Use last_wal and last_position for the remote call to the
# master server
remote_info = self.primary_node_info(sync_wal_info.last_wal,
sync_wal_info.last_position)
try:
remote_info = self.primary_node_info(sync_wal_info.last_wal,
sync_wal_info.last_position)
except SyncError as exc:
output.error("Failed to retrieve the primary node status: %s"
% force_str(exc))
return
# Perform backup synchronisation
if remote_info['backups']:
......@@ -2724,10 +2729,12 @@ class Server(RemoteStatusMixin):
remote_command(cmd_str)
# All good, exit the retry loop with 'break'
break
except CommandFailedException as e:
except CommandFailedException as exc:
# In case we requested synchronisation with a last WAL info,
# we try again requesting the full current status
if last_wal is not None:
# we try again requesting the full current status, but only if
# exit code is 1. A different exit code means that
# the error is not from Barman (i.e. ssh failure)
if exc.args[0]['ret'] == 1 and last_wal is not None:
last_wal = None
last_position = None
output.warning(
......@@ -2740,7 +2747,7 @@ class Server(RemoteStatusMixin):
# for custom message and logging.
raise SyncError("sync-info execution on remote "
"primary server %s failed: %s" %
(self.config.name, e.args[0]['err']))
(self.config.name, exc.args[0]['err']))
# Save the result on disk
primary_info_file = os.path.join(self.config.backup_directory,
......@@ -2897,7 +2904,7 @@ class Server(RemoteStatusMixin):
return
# Catch KeyboardInterrupt (Ctrl+c) and all the exceptions
except BaseException as e:
msg_lines = str(e).strip().splitlines()
msg_lines = force_str(e).strip().splitlines()
if local_backup_info:
# Use only the first line of exception message
# in local_backup_info error field
......@@ -2983,7 +2990,14 @@ class Server(RemoteStatusMixin):
# Case 2: bw = 10, sw = 10 - SYNC
# Case 3: bw = 10, sw = 15 - SYNC
#
first_remote_wal = primary_info['wals'][0]['name']
# Search for the first WAL file (skip history,
# backup and partial files)
first_remote_wal = None
for wal in primary_info['wals']:
if xlog.is_wal_file(wal['name']):
first_remote_wal = wal['name']
break
first_backup_id = self.get_first_backup_id()
first_backup = self.get_backup(first_backup_id) \
if first_backup_id else None
......@@ -3055,7 +3069,7 @@ class Server(RemoteStatusMixin):
output.error(msg)
return
except BaseException as e:
msg_lines = str(e).strip().splitlines()
msg_lines = force_str(e).strip().splitlines()
# Use only the first line of exception message
# If the exception has no attached message
# use the raw type name
......
......@@ -31,6 +31,7 @@ import os
import pwd
import re
import signal
import sys
from contextlib import contextmanager
from distutils.version import Version
......@@ -40,6 +41,14 @@ from barman.exceptions import TimeoutError
_logger = logging.getLogger(__name__)
if sys.version_info[0] >= 3:
_text_type = str
_string_types = str
else:
_text_type = unicode
_string_types = basestring
def drop_privileges(user):
"""
Change the system user of the current python process.
......@@ -421,3 +430,40 @@ def file_md5(file_path, buffer_size=1024 * 16):
break
md5.update(buf)
return md5.hexdigest()
def force_str(obj, encoding='utf-8', errors='replace'):
"""
Force any object to an unicode string.
Code inspired by Django's force_text function
"""
# Handle the common case first for performance reasons.
if issubclass(type(obj), _text_type):
return obj
try:
if issubclass(type(obj), _string_types):
obj = obj.decode(encoding, errors)
else:
if sys.version_info[0] >= 3:
if isinstance(obj, bytes):
obj = _text_type(obj, encoding, errors)
else:
obj = _text_type(obj)
elif hasattr(obj, '__unicode__'):
obj = _text_type(obj)
else:
obj = _text_type(bytes(obj), encoding, errors)
except (UnicodeDecodeError, TypeError):
if isinstance(obj, Exception):
# If we get to here, the caller has passed in an Exception
# subclass populated with non-ASCII bytestring data without a
# working unicode method. Try to handle this without raising a
# further exception by individually forcing the exception args
# to unicode.
obj = ' '.join(force_str(arg, encoding, errors)
for arg in obj.args)
else:
# As last resort, use a repr call to avoid any exception
obj = repr(obj)
return obj
......@@ -19,4 +19,4 @@
This module contains the current Barman version.
'''
__version__ = '2.6'
__version__ = '2.7'
This diff is collapsed.
% BARMAN(1) Barman User manuals | Version 2.6
% BARMAN(1) Barman User manuals | Version 2.7
% 2ndQuadrant Limited <https://www.2ndQuadrant.com>
% February 4, 2019
% March 21, 2019
......@@ -2,5 +2,5 @@ sync-backup *SERVER_NAME* *BACKUP_ID*
: Command used for the synchronisation of a passive node with its primary.
Executes a copy of all the files of a `BACKUP_ID` that is present on
`SERVER_NAME` node. This command is available only for passive nodes,
and uses the `primary_ssh_command` option to enstablish a secure connection
and uses the `primary_ssh_command` option to establish a secure connection
with the primary node.
......@@ -2,5 +2,5 @@ sync-wals *SERVER_NAME*
: Command used for the synchronisation of a passive node with its primary.
Executes a copy of all the archived WAL files that are present on
`SERVER_NAME` node. This command is available only for passive nodes,
and uses the `primary_ssh_command` option to enstablish a secure connection
and uses the `primary_ssh_command` option to establish a secure connection
with the primary node.
.\" Automatically generated by Pandoc 2.5
.\" Automatically generated by Pandoc 2.7.1
.\"
.TH "BARMAN" "5" "February 4, 2019" "Barman User manuals" "Version 2.6"
.TH "BARMAN" "5" "March 21, 2019" "Barman User manuals" "Version 2.7"
.hy
.SH NAME
.PP
barman \- Backup and Recovery Manager for PostgreSQL
barman - Backup and Recovery Manager for PostgreSQL
.SH DESCRIPTION
.PP
Barman is an administration tool for disaster recovery of PostgreSQL
......@@ -13,7 +13,7 @@ Barman can perform remote backups of multiple servers in business
critical environments and helps DBAs during the recovery phase.
.SH CONFIGURATION FILE LOCATIONS
.PP
The system\-level Barman configuration file is located at
The system-level Barman configuration file is located at
.IP
.nf
\f[C]
......@@ -29,7 +29,7 @@ or
\f[R]
.fi
.PP
and is overridden on a per\-user level by
and is overridden on a per-user level by
.IP
.nf
\f[C]
......@@ -82,7 +82,7 @@ This option allows you to activate batch processing of WAL files for the
\f[C]archiver\f[R] process, by setting it to a value > 0.
Otherwise, the traditional unlimited processing of the WAL queue is
enabled.
When batch processing is activated, the \f[C]archive\-wal\f[R] process
When batch processing is activated, the \f[C]archive-wal\f[R] process
would limit itself to maximum \f[C]archiver_batch_size\f[R] WAL segments
per single run.
Integer.
......@@ -103,7 +103,7 @@ Global/Server.
.B backup_options
This option allows you to control the way Barman interacts with
PostgreSQL for backups.
It is a comma\-separated list of values that accepts the following
It is a comma-separated list of values that accepts the following
options:
.RS
.IP \[bu] 2
......@@ -416,15 +416,15 @@ Parameter that identifies a Barman server as \f[C]passive\f[R].
In a passive node, the source of a backup server is a Barman
installation rather than a PostgreSQL server.
If \f[C]primary_ssh_command\f[R] is specified, Barman uses it to
enstablish a connection with the primary server.
establish a connection with the primary server.
Empty by default, it can also be set globally.
.TP
.B recovery_options
Options for recovery operations.
Currently only supports \f[C]get\-wal\f[R].
\f[C]get\-wal\f[R] activates generation of a basic
Currently only supports \f[C]get-wal\f[R].
\f[C]get-wal\f[R] activates generation of a basic
\f[C]restore_command\f[R] in the resulting \f[C]recovery.conf\f[R] file
that uses the \f[C]barman get\-wal\f[R] command to fetch WAL files
that uses the \f[C]barman get-wal\f[R] command to fetch WAL files
directly from Barman\[aq]s archive of WALs.
Comma separated list of values, default empty.
Global/Server.
......@@ -464,7 +464,7 @@ Requires operating system and file system support for hard links.
.RE
.TP
.B slot_name
Physical replication slot to be used by the