mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Config parsing no longer implemented in Perl.
Options are passed to Perl as JSON from the C process.
This commit is contained in:
parent
f0ef1dee05
commit
a91a648019
@ -62,7 +62,7 @@
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Config parsing implemented in C.</p>
|
||||
<p>Config parsing implemented in C and passed to Perl as JSON.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
|
@ -39,7 +39,18 @@ sub process
|
||||
my $self = shift;
|
||||
|
||||
# Assign function parameters, defaults, and log debug info
|
||||
my ($strOperation) = logDebugParam(__PACKAGE__ . '->process');
|
||||
my
|
||||
(
|
||||
$strOperation,
|
||||
$strSourceArchive,
|
||||
$strDestinationFile
|
||||
) =
|
||||
logDebugParam
|
||||
(
|
||||
__PACKAGE__ . '->process', \@_,
|
||||
{name => 'strSourceArchive'},
|
||||
{name => 'strDestinationFile'}
|
||||
);
|
||||
|
||||
# Make sure the command happens on the db side
|
||||
if (!isDbLocal())
|
||||
@ -48,25 +59,25 @@ sub process
|
||||
}
|
||||
|
||||
# Make sure the archive file is defined
|
||||
if (!defined($ARGV[1]))
|
||||
if (!defined($strSourceArchive))
|
||||
{
|
||||
confess &log(ERROR, 'WAL segment not provided', ERROR_PARAM_REQUIRED);
|
||||
}
|
||||
|
||||
# Make sure the destination file is defined
|
||||
if (!defined($ARGV[2]))
|
||||
if (!defined($strDestinationFile))
|
||||
{
|
||||
confess &log(ERROR, 'WAL segment destination not provided', ERROR_PARAM_REQUIRED);
|
||||
}
|
||||
|
||||
# Info for the Postgres log
|
||||
&log(INFO, 'get WAL segment ' . $ARGV[1]);
|
||||
&log(INFO, 'get WAL segment ' . $strSourceArchive);
|
||||
|
||||
# Return from function and log return values if any
|
||||
return logDebugReturn
|
||||
(
|
||||
$strOperation,
|
||||
{name => 'iResult', value => $self->get($ARGV[1], $ARGV[2]), trace => true}
|
||||
{name => 'iResult', value => $self->get($strSourceArchive, $strDestinationFile), trace => true}
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,11 @@ package pgBackRest::Config::Config;
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
use Cwd qw(abs_path);
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw();
|
||||
use File::Basename qw(dirname basename);
|
||||
use Getopt::Long qw(GetOptions);
|
||||
use Storable qw(dclone);
|
||||
use JSON::PP;
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Ini;
|
||||
@ -83,63 +81,79 @@ push @EXPORT, qw(configLogging);
|
||||
sub configLoad
|
||||
{
|
||||
my $bInitLogging = shift;
|
||||
my $strBackRestBin = shift;
|
||||
my $strCommandName = shift;
|
||||
my $strConfigJson = shift;
|
||||
|
||||
# Clear option in case it was loaded before
|
||||
%oOption = ();
|
||||
|
||||
# Build hash with all valid command-line options
|
||||
my @stryOptionAllow;
|
||||
# Set backrest bin
|
||||
backrestBinSet($strBackRestBin);
|
||||
|
||||
# Set command
|
||||
$strCommand = $strCommandName;
|
||||
|
||||
# Convert options from JSON to a hash
|
||||
my $rhOption;
|
||||
|
||||
eval
|
||||
{
|
||||
$rhOption = (JSON::PP->new()->allow_nonref())->decode($strConfigJson);
|
||||
return true;
|
||||
}
|
||||
or do
|
||||
{
|
||||
confess &log(ASSERT, "$EVAL_ERROR" . (defined($strConfigJson) ? ":\n${strConfigJson}" : "<undef>"));
|
||||
};
|
||||
|
||||
# Load options into final option hash
|
||||
for (my $iOptionId = 0; $iOptionId < cfgOptionTotal(); $iOptionId++)
|
||||
{
|
||||
my $strKey = cfgOptionName($iOptionId);
|
||||
my $strOptionName = cfgOptionName($iOptionId);
|
||||
|
||||
foreach my $bAltName (false, true)
|
||||
# If option is not defined then it is not valid
|
||||
if (!defined($rhOption->{$strOptionName}))
|
||||
{
|
||||
my $strOptionName = $strKey;
|
||||
$oOption{$strOptionName}{valid} = false;
|
||||
}
|
||||
# Else set option
|
||||
else
|
||||
{
|
||||
$oOption{$strOptionName}{valid} = true;
|
||||
$oOption{$strOptionName}{source} =
|
||||
defined($rhOption->{$strOptionName}{source}) ? $rhOption->{$strOptionName}{source} : CFGDEF_SOURCE_DEFAULT;
|
||||
|
||||
if ($bAltName)
|
||||
# If option is negated only boolean will have a value
|
||||
if ($rhOption->{$strOptionName}{negate})
|
||||
{
|
||||
if (!defined(cfgDefOptionNameAlt($iOptionId)))
|
||||
$oOption{$strOptionName}{negate} = true;
|
||||
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
next;
|
||||
$oOption{$strOptionName}{value} = false;
|
||||
}
|
||||
|
||||
$strOptionName = cfgDefOptionNameAlt($iOptionId);
|
||||
}
|
||||
|
||||
my $strOption = $strOptionName;
|
||||
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH || cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_LIST)
|
||||
# Else set the value
|
||||
else
|
||||
{
|
||||
$strOption .= '=s@';
|
||||
}
|
||||
elsif (cfgDefOptionType($iOptionId) ne CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strOption .= '=s';
|
||||
}
|
||||
$oOption{$strOptionName}{negate} = false;
|
||||
|
||||
push(@stryOptionAllow, $strOption);
|
||||
|
||||
# Check if the option can be negated
|
||||
if (cfgDefOptionNegate($iOptionId))
|
||||
{
|
||||
push(@stryOptionAllow, 'no-' . $strOptionName);
|
||||
if (defined($rhOption->{$strOptionName}{value}))
|
||||
{
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$oOption{$strOptionName}{value} = $rhOption->{$strOptionName}{value} eq INI_TRUE ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oOption{$strOptionName}{value} = $rhOption->{$strOptionName}{value};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Get command-line options
|
||||
my %oOptionTest;
|
||||
|
||||
# Parse command line options
|
||||
if (!GetOptions(\%oOptionTest, @stryOptionAllow))
|
||||
{
|
||||
confess &log(ASSERT, "error parsing command line");
|
||||
}
|
||||
|
||||
optionValidate(\%oOptionTest);
|
||||
|
||||
# If this is not the remote and logging is allowed (to not overwrite log levels for tests) then set the log level so that
|
||||
# INFO/WARN messages can be displayed (the user may still disable them). This should be run before any WARN logging is
|
||||
# generated.
|
||||
@ -275,594 +289,6 @@ sub configLoad
|
||||
|
||||
push @EXPORT, qw(configLoad);
|
||||
|
||||
####################################################################################################################################
|
||||
# optionValueGet
|
||||
#
|
||||
# Find the value of an option using both the regular and alt values. Error if both are defined.
|
||||
####################################################################################################################################
|
||||
sub optionValueGet
|
||||
{
|
||||
my $strOption = shift;
|
||||
my $hOption = shift;
|
||||
|
||||
my $strValue = $hOption->{$strOption};
|
||||
|
||||
# Some options have an alternate name so check for that as well
|
||||
my $iOptionId = cfgOptionId($strOption);
|
||||
|
||||
if (defined(cfgDefOptionNameAlt($iOptionId)))
|
||||
{
|
||||
my $strOptionAlt = cfgDefOptionNameAlt($iOptionId);
|
||||
my $strValueAlt = $hOption->{$strOptionAlt};
|
||||
|
||||
if (defined($strValueAlt))
|
||||
{
|
||||
if (!defined($strValue))
|
||||
{
|
||||
$strValue = $strValueAlt;
|
||||
|
||||
delete($hOption->{$strOptionAlt});
|
||||
$hOption->{$strOption} = $strValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
confess &log(ERROR, "'${strOption}' and '${strOptionAlt}' cannot both be defined", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $strValue;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionValidate
|
||||
#
|
||||
# Make sure the command-line options are valid based on the command.
|
||||
####################################################################################################################################
|
||||
sub optionValidate
|
||||
{
|
||||
my $oOptionTest = shift;
|
||||
|
||||
# Check that the command is present and valid
|
||||
$strCommand = $ARGV[0];
|
||||
|
||||
if (!defined($strCommand))
|
||||
{
|
||||
confess &log(ERROR, "command must be specified", ERROR_COMMAND_REQUIRED);
|
||||
}
|
||||
|
||||
my $iCommandId = cfgCommandId($strCommand);
|
||||
|
||||
if ($iCommandId eq "-1")
|
||||
{
|
||||
confess &log(ERROR, "invalid command ${strCommand}", ERROR_COMMAND_INVALID);
|
||||
}
|
||||
|
||||
# Hash to store contents of the config file. The file will be loaded once the config dependency is resolved unless all options
|
||||
# are set on the command line or --no-config is specified.
|
||||
my $oConfig;
|
||||
my $bConfigExists = true;
|
||||
|
||||
# Keep track of unresolved dependencies
|
||||
my $bDependUnresolved = true;
|
||||
my %oOptionResolved;
|
||||
|
||||
# Loop through all possible options
|
||||
while ($bDependUnresolved)
|
||||
{
|
||||
# Assume that all dependencies will be resolved in this loop
|
||||
$bDependUnresolved = false;
|
||||
|
||||
for (my $iOptionId = 0; $iOptionId < cfgOptionTotal(); $iOptionId++)
|
||||
{
|
||||
my $strOption = cfgOptionName($iOptionId);
|
||||
|
||||
# Skip the option if it has been resolved in a prior loop
|
||||
if (defined($oOptionResolved{$strOption}))
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Determine if an option is valid for a command
|
||||
$oOption{$strOption}{valid} = cfgDefOptionValid($iCommandId, $iOptionId);
|
||||
|
||||
if (!$oOption{$strOption}{valid})
|
||||
{
|
||||
$oOptionResolved{$strOption} = true;
|
||||
next;
|
||||
}
|
||||
|
||||
# Store the option value
|
||||
my $strValue = optionValueGet($strOption, $oOptionTest);
|
||||
|
||||
# Check to see if an option can be negated. Make sure that it is not set and negated at the same time.
|
||||
$oOption{$strOption}{negate} = false;
|
||||
|
||||
if (cfgDefOptionNegate($iOptionId))
|
||||
{
|
||||
$oOption{$strOption}{negate} = defined($$oOptionTest{'no-' . $strOption});
|
||||
|
||||
if ($oOption{$strOption}{negate} && defined($strValue))
|
||||
{
|
||||
confess &log(ERROR, "option '${strOption}' cannot be both set and negated", ERROR_OPTION_NEGATE);
|
||||
}
|
||||
|
||||
if ($oOption{$strOption}{negate} && cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
# Check dependency for the command then for the option
|
||||
my $bDependResolved = true;
|
||||
my $strDependOption;
|
||||
my $strDependValue;
|
||||
my $strDependType;
|
||||
|
||||
if (cfgDefOptionDepend($iCommandId, $iOptionId))
|
||||
{
|
||||
# Check if the depend option has a value
|
||||
my $iDependOptionId = cfgDefOptionDependOption($iCommandId, $iOptionId);
|
||||
$strDependOption = cfgOptionName($iDependOptionId);
|
||||
$strDependValue = $oOption{$strDependOption}{value};
|
||||
|
||||
# Make sure the depend option has been resolved, otherwise skip this option for now
|
||||
if (!defined($oOptionResolved{$strDependOption}))
|
||||
{
|
||||
$bDependUnresolved = true;
|
||||
next;
|
||||
}
|
||||
|
||||
if (!defined($strDependValue))
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'source';
|
||||
}
|
||||
|
||||
# If a depend value exists, make sure the option value matches
|
||||
if ($bDependResolved && cfgDefOptionDependValueTotal($iCommandId, $iOptionId) == 1 &&
|
||||
cfgDefOptionDependValue($iCommandId, $iOptionId, 0) ne $strDependValue)
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'value';
|
||||
}
|
||||
|
||||
# If a depend list exists, make sure the value is in the list
|
||||
if ($bDependResolved && cfgDefOptionDependValueTotal($iCommandId, $iOptionId) > 1 &&
|
||||
!cfgDefOptionDependValueValid($iCommandId, $iOptionId, $strDependValue))
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'list';
|
||||
}
|
||||
}
|
||||
|
||||
# If the option value is undefined and not negated, see if it can be loaded from the config file
|
||||
if (!defined($strValue) && !$oOption{$strOption}{negate} && $strOption ne cfgOptionName(CFGOPT_CONFIG) &&
|
||||
defined(cfgDefOptionSection($iOptionId)) && $bDependResolved)
|
||||
{
|
||||
# If the config option has not been resolved yet then continue processing
|
||||
if (!defined($oOptionResolved{cfgOptionName(CFGOPT_CONFIG)}) ||
|
||||
!defined($oOptionResolved{cfgOptionName(CFGOPT_STANZA)}))
|
||||
{
|
||||
$bDependUnresolved = true;
|
||||
next;
|
||||
}
|
||||
|
||||
# If the config option is defined try to get the option from the config file
|
||||
if ($bConfigExists && defined($oOption{cfgOptionName(CFGOPT_CONFIG)}{value}))
|
||||
{
|
||||
# Attempt to load the config file if it has not been loaded
|
||||
if (!defined($oConfig))
|
||||
{
|
||||
my $strConfigFile = $oOption{cfgOptionName(CFGOPT_CONFIG)}{value};
|
||||
$bConfigExists = -e $strConfigFile;
|
||||
|
||||
if ($bConfigExists)
|
||||
{
|
||||
if (!-f $strConfigFile)
|
||||
{
|
||||
confess &log(ERROR, "'${strConfigFile}' is not a file", ERROR_FILE_INVALID);
|
||||
}
|
||||
|
||||
# Load Storage::Helper module
|
||||
require pgBackRest::Storage::Helper;
|
||||
pgBackRest::Storage::Helper->import();
|
||||
|
||||
$oConfig = iniParse(${storageLocal->('/')->get($strConfigFile)}, {bRelaxed => true});
|
||||
}
|
||||
}
|
||||
|
||||
# Get the section that the value should be in
|
||||
my $strSection = cfgDefOptionSection($iOptionId);
|
||||
|
||||
# Always check for the option in the stanza section first
|
||||
if (cfgOptionTest(CFGOPT_STANZA))
|
||||
{
|
||||
$strValue = optionValueGet($strOption, $$oConfig{cfgOption(CFGOPT_STANZA)});
|
||||
}
|
||||
|
||||
# Only continue searching when strSection != CFGDEF_SECTION_STANZA. Some options (e.g. db-path) can only be
|
||||
# configured in the stanza section.
|
||||
if (!defined($strValue) && $strSection ne CFGDEF_SECTION_STANZA)
|
||||
{
|
||||
# Check the stanza command section
|
||||
if (cfgOptionTest(CFGOPT_STANZA))
|
||||
{
|
||||
$strValue = optionValueGet($strOption, $$oConfig{cfgOption(CFGOPT_STANZA) . ":${strCommand}"});
|
||||
}
|
||||
|
||||
# Check the global command section
|
||||
if (!defined($strValue))
|
||||
{
|
||||
$strValue = optionValueGet($strOption, $$oConfig{&CFGDEF_SECTION_GLOBAL . ":${strCommand}"});
|
||||
}
|
||||
|
||||
# Finally check the global section
|
||||
if (!defined($strValue))
|
||||
{
|
||||
$strValue = optionValueGet($strOption, $$oConfig{&CFGDEF_SECTION_GLOBAL});
|
||||
}
|
||||
}
|
||||
|
||||
# Fix up data types
|
||||
if (defined($strValue))
|
||||
{
|
||||
# The empty string is undefined
|
||||
if ($strValue eq '')
|
||||
{
|
||||
$strValue = undef;
|
||||
}
|
||||
# Convert Y or N to boolean
|
||||
elsif (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
if ($strValue eq 'y')
|
||||
{
|
||||
$strValue = true;
|
||||
}
|
||||
elsif ($strValue eq 'n')
|
||||
{
|
||||
$strValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option",
|
||||
ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
# Convert a list of key/value pairs to a hash
|
||||
elsif (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH ||
|
||||
cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_LIST)
|
||||
{
|
||||
my @oValue = ();
|
||||
|
||||
# If there is only one key/value
|
||||
if (ref(\$strValue) eq 'SCALAR')
|
||||
{
|
||||
push(@oValue, $strValue);
|
||||
}
|
||||
# Else if there is an array of values
|
||||
else
|
||||
{
|
||||
@oValue = @{$strValue};
|
||||
}
|
||||
|
||||
# Reset the value hash
|
||||
$strValue = {};
|
||||
|
||||
# Iterate and parse each key/value pair
|
||||
foreach my $strHash (@oValue)
|
||||
{
|
||||
my $iEqualIdx = index($strHash, '=');
|
||||
|
||||
if ($iEqualIdx < 1 || $iEqualIdx == length($strHash) - 1)
|
||||
{
|
||||
confess &log(ERROR, "'${strHash}' is not valid for '${strOption}' option",
|
||||
ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
my $strHashKey = substr($strHash, 0, $iEqualIdx);
|
||||
my $strHashValue = substr($strHash, length($strHashKey) + 1);
|
||||
|
||||
$$strValue{$strHashKey} = $strHashValue;
|
||||
}
|
||||
}
|
||||
# In all other cases the value should be scalar
|
||||
elsif (ref(\$strValue) ne 'SCALAR')
|
||||
{
|
||||
confess &log(
|
||||
ERROR, "option '${strOption}' cannot be specified multiple times", ERROR_OPTION_MULTIPLE_VALUE);
|
||||
}
|
||||
|
||||
$oOption{$strOption}{source} = CFGDEF_SOURCE_CONFIG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cfgDefOptionDepend($iCommandId, $iOptionId) && !$bDependResolved && defined($strValue))
|
||||
{
|
||||
my $strError = "option '${strOption}' not valid without option ";
|
||||
my $iDependOptionId = cfgOptionId($strDependOption);
|
||||
|
||||
if ($strDependType eq 'source')
|
||||
{
|
||||
confess &log(ERROR, "${strError}'${strDependOption}'", ERROR_OPTION_INVALID);
|
||||
}
|
||||
|
||||
# If a depend value exists, make sure the option value matches
|
||||
if ($strDependType eq 'value')
|
||||
{
|
||||
if (cfgDefOptionType($iDependOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strError .=
|
||||
"'" . (cfgDefOptionDependValue($iCommandId, $iOptionId, 0) ? '' : 'no-') . "${strDependOption}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$strError .= "'${strDependOption}' = '" . cfgDefOptionDependValue($iCommandId, $iOptionId, 0) . "'";
|
||||
}
|
||||
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
|
||||
$strError .= "'${strDependOption}'";
|
||||
|
||||
# If a depend list exists, make sure the value is in the list
|
||||
if ($strDependType eq 'list')
|
||||
{
|
||||
my @oyValue;
|
||||
|
||||
for (my $iValueId = 0; $iValueId < cfgDefOptionDependValueTotal($iCommandId, $iOptionId); $iValueId++)
|
||||
{
|
||||
push(@oyValue, "'" . cfgDefOptionDependValue($iCommandId, $iOptionId, $iValueId) . "'");
|
||||
}
|
||||
|
||||
$strError .= @oyValue == 1 ? " = $oyValue[0]" : " in (" . join(", ", @oyValue) . ")";
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
# Is the option defined?
|
||||
if (defined($strValue))
|
||||
{
|
||||
# Check that floats and integers are valid
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_INTEGER ||
|
||||
cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_FLOAT)
|
||||
{
|
||||
# Test that the string is a valid float or integer by adding 1 to it. It's pretty hokey but it works and it
|
||||
# beats requiring Scalar::Util::Numeric to do it properly.
|
||||
my $bError = false;
|
||||
|
||||
eval
|
||||
{
|
||||
my $strTest = $strValue + 1;
|
||||
return true;
|
||||
}
|
||||
or do
|
||||
{
|
||||
$bError = true;
|
||||
};
|
||||
|
||||
# Check that integers are really integers
|
||||
if (!$bError && cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_INTEGER &&
|
||||
(int($strValue) . 'S') ne ($strValue . 'S'))
|
||||
{
|
||||
$bError = true;
|
||||
}
|
||||
|
||||
# Error if the value did not pass tests
|
||||
!$bError
|
||||
or confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Process an allow list for the command then for the option
|
||||
if (cfgDefOptionAllowList($iCommandId, $iOptionId) &&
|
||||
!cfgDefOptionAllowListValueValid($iCommandId, $iOptionId, $strValue))
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Process an allow range for the command then for the option
|
||||
if (cfgDefOptionAllowRange($iCommandId, $iOptionId) &&
|
||||
($strValue < cfgDefOptionAllowRangeMin($iCommandId, $iOptionId) ||
|
||||
$strValue > cfgDefOptionAllowRangeMax($iCommandId, $iOptionId)))
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_RANGE);
|
||||
}
|
||||
|
||||
# Set option value
|
||||
if (ref($strValue) eq 'ARRAY' &&
|
||||
(cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH || cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_LIST))
|
||||
{
|
||||
foreach my $strItem (@{$strValue})
|
||||
{
|
||||
my $strKey;
|
||||
my $strValue;
|
||||
|
||||
# If the keys are expected to have values
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH)
|
||||
{
|
||||
# Check for = and make sure there is a least one character on each side
|
||||
my $iEqualPos = index($strItem, '=');
|
||||
|
||||
if ($iEqualPos < 1 || length($strItem) <= $iEqualPos + 1)
|
||||
{
|
||||
confess &log(ERROR, "'${strItem}' not valid key/value for '${strOption}' option",
|
||||
ERROR_OPTION_INVALID_PAIR);
|
||||
}
|
||||
|
||||
$strKey = substr($strItem, 0, $iEqualPos);
|
||||
$strValue = substr($strItem, $iEqualPos + 1);
|
||||
}
|
||||
# Else no values are expected so set value to true
|
||||
else
|
||||
{
|
||||
$strKey = $strItem;
|
||||
$strValue = true;
|
||||
}
|
||||
|
||||
# Check that the key has not already been set
|
||||
if (defined($oOption{$strOption}{$strKey}{value}))
|
||||
{
|
||||
confess &log(ERROR, "'${$strItem}' already defined for '${strOption}' option",
|
||||
ERROR_OPTION_DUPLICATE_KEY);
|
||||
}
|
||||
|
||||
# Set key/value
|
||||
$oOption{$strOption}{value}{$strKey} = $strValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oOption{$strOption}{value} = $strValue;
|
||||
}
|
||||
|
||||
# If not config sourced then it must be a param
|
||||
if (!defined($oOption{$strOption}{source}))
|
||||
{
|
||||
$oOption{$strOption}{source} = CFGDEF_SOURCE_PARAM;
|
||||
}
|
||||
}
|
||||
# Else try to set a default
|
||||
elsif ($bDependResolved)
|
||||
{
|
||||
# Source is default for this option
|
||||
$oOption{$strOption}{source} = CFGDEF_SOURCE_DEFAULT;
|
||||
|
||||
# Check for default in command then option
|
||||
my $strDefault = cfgDefOptionDefault($iCommandId, $iOptionId);
|
||||
|
||||
# If default is defined
|
||||
if (defined($strDefault))
|
||||
{
|
||||
# Only set default if dependency is resolved
|
||||
$oOption{$strOption}{value} = $strDefault if !$oOption{$strOption}{negate};
|
||||
}
|
||||
# Else check required
|
||||
elsif (cfgDefOptionRequired($iCommandId, $iOptionId))
|
||||
{
|
||||
confess &log(ERROR,
|
||||
"${strCommand} command requires option: ${strOption}" .
|
||||
(defined(cfgDefOptionSection($iOptionId)) &&
|
||||
cfgDefOptionSection($iOptionId) eq CFGDEF_SECTION_STANZA ? "\nHINT: does this stanza exist?" : ''),
|
||||
ERROR_OPTION_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
$oOptionResolved{$strOption} = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Make sure all options specified on the command line are valid
|
||||
foreach my $strOption (sort(keys(%{$oOptionTest})))
|
||||
{
|
||||
# Strip "no-" off the option
|
||||
$strOption = $strOption =~ /^no\-/ ? substr($strOption, 3) : $strOption;
|
||||
|
||||
if (!$oOption{$strOption}{valid})
|
||||
{
|
||||
confess &log(ERROR, "option '${strOption}' not valid for command '${strCommand}'", ERROR_OPTION_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
# If a config file was loaded then determine if all options are valid in the config file
|
||||
if (defined($oConfig))
|
||||
{
|
||||
configFileValidate($oConfig);
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# configFileValidate
|
||||
#
|
||||
# Determine if the configuration file contains any invalid options or placements. Not valid on remote.
|
||||
####################################################################################################################################
|
||||
sub configFileValidate
|
||||
{
|
||||
my $oConfig = shift;
|
||||
|
||||
my $bFileValid = true;
|
||||
|
||||
if (!cfgCommandTest(CFGCMD_REMOTE) && !cfgCommandTest(CFGCMD_LOCAL))
|
||||
{
|
||||
foreach my $strSectionKey (keys(%$oConfig))
|
||||
{
|
||||
my ($strSection, $strCommand) = ($strSectionKey =~ m/([^:]*):*(\w*-*\w*)/);
|
||||
|
||||
foreach my $strOption (keys(%{$$oConfig{$strSectionKey}}))
|
||||
{
|
||||
my $strOptionDisplay = $strOption;
|
||||
my $strValue = $$oConfig{$strSectionKey}{$strOption};
|
||||
|
||||
# Is the option listed as an alternate name for another option? If so, replace it with the recognized option.
|
||||
my $strOptionAltName = optionAltName($strOption);
|
||||
|
||||
if (defined($strOptionAltName))
|
||||
{
|
||||
$strOption = $strOptionAltName;
|
||||
}
|
||||
|
||||
# Is the option a valid pgbackrest option?
|
||||
if (!(cfgOptionId($strOption) ne '-1' || defined($strOptionAltName)))
|
||||
{
|
||||
&log(WARN, cfgOption(CFGOPT_CONFIG) . " file contains invalid option '${strOptionDisplay}'");
|
||||
$bFileValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
# Is the option valid for the command section in which it is located?
|
||||
if (defined($strCommand) && $strCommand ne '')
|
||||
{
|
||||
if (!cfgDefOptionValid(cfgCommandId($strCommand), cfgOptionId($strOption)))
|
||||
{
|
||||
&log(WARN, cfgOption(CFGOPT_CONFIG) . " valid option '${strOptionDisplay}' is not valid for command " .
|
||||
"'${strCommand}'");
|
||||
$bFileValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
# Is the valid option a stanza-only option and not located in a global section?
|
||||
if (cfgDefOptionSection(cfgOptionId($strOption)) eq CFGDEF_SECTION_STANZA &&
|
||||
$strSection eq CFGDEF_SECTION_GLOBAL)
|
||||
{
|
||||
&log(WARN,
|
||||
cfgOption(CFGOPT_CONFIG) . " valid option '${strOptionDisplay}' is a stanza section option and is" .
|
||||
" not valid in section ${strSection}\n" .
|
||||
"HINT: global options can be specified in global or stanza sections but not visa-versa");
|
||||
$bFileValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bFileValid;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# optionAltName
|
||||
#
|
||||
# Returns the ALT_NAME for the option if one exists.
|
||||
####################################################################################################################################
|
||||
sub optionAltName
|
||||
{
|
||||
my $strOption = shift;
|
||||
|
||||
my $strOptionAltName = undef;
|
||||
|
||||
# Check if the options exists as an alternate name (e.g. db-host has altname db1-host)
|
||||
for (my $iOptionId = 0; $iOptionId < cfgOptionTotal(); $iOptionId++)
|
||||
{
|
||||
my $strKey = cfgOptionName($iOptionId);
|
||||
|
||||
if (defined(cfgDefOptionNameAlt($iOptionId)) && cfgDefOptionNameAlt($iOptionId) eq $strOption)
|
||||
{
|
||||
$strOptionAltName = $strKey;
|
||||
}
|
||||
}
|
||||
|
||||
return $strOptionAltName;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# cfgOptionIdFromIndex - return name for options that can be indexed (e.g. db1-host, db2-host).
|
||||
####################################################################################################################################
|
||||
|
@ -30,7 +30,9 @@ use pgBackRest::Version;
|
||||
sub main
|
||||
{
|
||||
my $strBackRestBin = shift;
|
||||
@ARGV = @_;
|
||||
my $strCommand = shift;
|
||||
my $strConfigJson = shift;
|
||||
my @stryCommandArg = @_;
|
||||
|
||||
################################################################################################################################
|
||||
# Run in eval block to catch errors
|
||||
@ -40,8 +42,7 @@ sub main
|
||||
############################################################################################################################
|
||||
# Load command line parameters and config
|
||||
############################################################################################################################
|
||||
backrestBinSet($strBackRestBin);
|
||||
configLoad();
|
||||
configLoad(undef, $strBackRestBin, $strCommand, $strConfigJson);
|
||||
|
||||
# Set test options
|
||||
if (cfgOptionTest(CFGOPT_TEST) && cfgOption(CFGOPT_TEST))
|
||||
@ -58,7 +59,7 @@ sub main
|
||||
require pgBackRest::Archive::Push::Push;
|
||||
pgBackRest::Archive::Push::Push->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Push::Push()->process($ARGV[1]));
|
||||
exitSafe(new pgBackRest::Archive::Push::Push()->process($stryCommandArg[0]));
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
@ -70,7 +71,7 @@ sub main
|
||||
require pgBackRest::Archive::Get::Get;
|
||||
pgBackRest::Archive::Get::Get->import();
|
||||
|
||||
exitSafe(new pgBackRest::Archive::Get::Get()->process());
|
||||
exitSafe(new pgBackRest::Archive::Get::Get()->process($stryCommandArg[0], $stryCommandArg[1]));
|
||||
}
|
||||
|
||||
############################################################################################################################
|
||||
|
@ -16,7 +16,7 @@ Module variables
|
||||
***********************************************************************************************************************************/
|
||||
// Log levels
|
||||
LogLevel logLevelStdOut = logLevelOff;
|
||||
LogLevel logLevelStdErr = logLevelWarn;
|
||||
LogLevel logLevelStdErr = logLevelOff;
|
||||
|
||||
// Log file handles
|
||||
int logHandleStdOut = STDOUT_FILENO;
|
||||
|
@ -20,20 +20,23 @@ cfgLoad(int argListSize, const char *argList[])
|
||||
configParse(argListSize, argList);
|
||||
|
||||
// Initialize logging
|
||||
LogLevel logLevelConsole = logLevelOff;
|
||||
LogLevel logLevelStdErr = logLevelOff;
|
||||
bool logTimestamp = true;
|
||||
if (cfgCommand() != cfgCmdLocal && cfgCommand() != cfgCmdRemote)
|
||||
{
|
||||
LogLevel logLevelConsole = logLevelOff;
|
||||
LogLevel logLevelStdErr = logLevelOff;
|
||||
bool logTimestamp = true;
|
||||
|
||||
if (cfgOptionValid(cfgOptLogLevelConsole))
|
||||
logLevelConsole = logLevelEnum(strPtr(cfgOptionStr(cfgOptLogLevelConsole)));
|
||||
if (cfgOptionValid(cfgOptLogLevelConsole))
|
||||
logLevelConsole = logLevelEnum(strPtr(cfgOptionStr(cfgOptLogLevelConsole)));
|
||||
|
||||
if (cfgOptionValid(cfgOptLogLevelStderr))
|
||||
logLevelStdErr = logLevelEnum(strPtr(cfgOptionStr(cfgOptLogLevelStderr)));
|
||||
if (cfgOptionValid(cfgOptLogLevelStderr))
|
||||
logLevelStdErr = logLevelEnum(strPtr(cfgOptionStr(cfgOptLogLevelStderr)));
|
||||
|
||||
if (cfgOptionValid(cfgOptLogTimestamp))
|
||||
logTimestamp = cfgOptionBool(cfgOptLogTimestamp);
|
||||
if (cfgOptionValid(cfgOptLogTimestamp))
|
||||
logTimestamp = cfgOptionBool(cfgOptLogTimestamp);
|
||||
|
||||
logInit(logLevelConsole, logLevelStdErr, logTimestamp);
|
||||
logInit(logLevelConsole, logLevelStdErr, logTimestamp);
|
||||
}
|
||||
|
||||
// Set default for backup-cmd
|
||||
if (cfgOptionValid(cfgOptBackupHost) && cfgOption(cfgOptBackupHost) != NULL &&
|
||||
|
@ -8,6 +8,7 @@ Command and Option Parse
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/ini.h"
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "config/parse.h"
|
||||
#include "storage/helper.h"
|
||||
@ -190,7 +191,12 @@ configParse(int argListSize, const char *argList[])
|
||||
if (commandParamList != NULL)
|
||||
cfgCommandParamSet(commandParamList);
|
||||
|
||||
// Parse options from config file unless --no-config passed
|
||||
// Enable logging except for local and remote commands
|
||||
if (cfgCommand() != cfgCmdLocal && cfgCommand() != cfgCmdRemote)
|
||||
logInit(logLevelOff, logLevelWarn, false);
|
||||
|
||||
// Phase 2: parse config file unless --no-config passed
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
if (cfgCommand() != cfgCmdNone &&
|
||||
cfgCommand() != cfgCmdVersion &&
|
||||
cfgCommand() != cfgCmdHelp)
|
||||
@ -198,8 +204,6 @@ configParse(int argListSize, const char *argList[])
|
||||
// Get the command definition id
|
||||
ConfigDefineCommand commandDefId = cfgCommandDefIdFromId(cfgCommand());
|
||||
|
||||
// Phase 2: parse config file
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
if (!parseOptionList[cfgOptConfig].negate)
|
||||
{
|
||||
// Get the config file name from the command-line if it exists else default
|
||||
@ -263,13 +267,13 @@ configParse(int argListSize, const char *argList[])
|
||||
// Warn if the option not found
|
||||
if (optionList[optionIdx].name == NULL)
|
||||
{
|
||||
/// ??? Put warning here once there is a logging system
|
||||
LOG_WARN("'%s' contains invalid option '%s'", strPtr(configFile), strPtr(key));
|
||||
continue;
|
||||
}
|
||||
// Warn if negate option found in config
|
||||
else if (optionList[optionIdx].val & PARSE_NEGATE_FLAG)
|
||||
{
|
||||
/// ??? Put warning here once there is a logging system
|
||||
LOG_WARN("'%s' contains negate option '%s'", strPtr(configFile), strPtr(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -279,7 +283,7 @@ configParse(int argListSize, const char *argList[])
|
||||
/// Warn if this option should be command-line only
|
||||
if (cfgDefOptionSection(optionDefId) == cfgDefSectionCommandLine)
|
||||
{
|
||||
/// ??? Put warning here once there is a logging system
|
||||
LOG_WARN("'%s' contains command-line only option '%s'", strPtr(configFile), strPtr(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -293,7 +297,9 @@ configParse(int argListSize, const char *argList[])
|
||||
// Warn if it is in a command section
|
||||
if (sectionIdx % 2 == 0)
|
||||
{
|
||||
// ??? Put warning here once there is a logging system (and remove continue and braces)
|
||||
LOG_WARN(
|
||||
"'%s' contains option '%s' invalid for section '%s'", strPtr(configFile), strPtr(key),
|
||||
strPtr(section));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -43,33 +43,57 @@ StringList *perlCommand()
|
||||
}
|
||||
|
||||
// Construct option list to pass to main
|
||||
String *mainCallParam = strNew("");
|
||||
String *configJson = strNew("{");
|
||||
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
{
|
||||
// Skip the option if it is not valid or not a command line option
|
||||
if (!cfgOptionValid(optionId) || cfgOptionSource(optionId) != cfgSourceParam)
|
||||
// Skip the option if it is not valid
|
||||
if (!cfgOptionValid(optionId))
|
||||
continue;
|
||||
|
||||
// Output option
|
||||
if (strSize(configJson) != 1)
|
||||
strCat(configJson, ",");
|
||||
|
||||
strCatFmt(configJson, "\"%s\":{", cfgOptionName(optionId));
|
||||
|
||||
// Output source unless it is default
|
||||
if (cfgOptionSource(optionId) != cfgSourceDefault)
|
||||
{
|
||||
strCat(configJson, "\"source\":\"");
|
||||
|
||||
if (cfgOptionSource(optionId) == cfgSourceParam)
|
||||
strCat(configJson, "param");
|
||||
else
|
||||
strCat(configJson, "config");
|
||||
|
||||
strCat(configJson, "\"");
|
||||
}
|
||||
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
strCatFmt(mainCallParam, ", '--no-%s'", cfgOptionName(optionId));
|
||||
// Else not negated
|
||||
else
|
||||
strCatFmt(configJson, ",\"negate\":%s", strPtr(varStrForce(varNewBool(true))));
|
||||
// Else not negated and has a value
|
||||
else if (cfgOption(optionId) != NULL)
|
||||
{
|
||||
if (cfgOptionSource(optionId) != cfgSourceDefault)
|
||||
strCat(configJson, ",");
|
||||
|
||||
strCat(configJson, "\"value\":");
|
||||
|
||||
switch (cfgDefOptionType(cfgOptionDefIdFromId(optionId)))
|
||||
{
|
||||
case cfgDefOptTypeBoolean:
|
||||
case cfgDefOptTypeFloat:
|
||||
case cfgDefOptTypeInteger:
|
||||
{
|
||||
strCatFmt(mainCallParam, ", '--%s'", cfgOptionName(optionId));
|
||||
strCat(configJson, strPtr(varStrForce(cfgOption(optionId))));
|
||||
break;
|
||||
}
|
||||
|
||||
case cfgDefOptTypeFloat:
|
||||
case cfgDefOptTypeInteger:
|
||||
case cfgDefOptTypeString:
|
||||
{
|
||||
strCatFmt(mainCallParam, ", '--%s', '%s'", cfgOptionName(optionId), strPtr(varStrForce(cfgOption(optionId))));
|
||||
strCatFmt(configJson, "\"%s\"", strPtr(cfgOptionStr(optionId)));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -78,14 +102,20 @@ StringList *perlCommand()
|
||||
const KeyValue *valueKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(valueKv);
|
||||
|
||||
strCat(configJson, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < varLstSize(keyList); listIdx++)
|
||||
{
|
||||
strCatFmt(mainCallParam, ", '--%s'", cfgOptionName(optionId));
|
||||
if (listIdx != 0)
|
||||
strCat(configJson, ",");
|
||||
|
||||
strCatFmt(
|
||||
mainCallParam, ", '%s=%s'", strPtr(varStr(varLstGet(keyList, listIdx))),
|
||||
configJson, "\"%s\":\"%s\"", strPtr(varStr(varLstGet(keyList, listIdx))),
|
||||
strPtr(varStr(kvGet(valueKv, varLstGet(keyList, listIdx)))));
|
||||
}
|
||||
|
||||
strCat(configJson, "}");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -93,29 +123,33 @@ StringList *perlCommand()
|
||||
{
|
||||
StringList *valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
|
||||
strCat(configJson, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < strLstSize(valueList); listIdx++)
|
||||
{
|
||||
strCatFmt(mainCallParam, ", '--%s'", cfgOptionName(optionId));
|
||||
strCatFmt(mainCallParam, ", '%s'", strPtr(strLstGet(valueList, listIdx)));
|
||||
if (listIdx != 0)
|
||||
strCat(configJson, ",");
|
||||
|
||||
strCatFmt(configJson, "\"%s\":true", strPtr(strLstGet(valueList, listIdx)));
|
||||
}
|
||||
|
||||
strCat(configJson, "}");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strCat(configJson, "}");
|
||||
}
|
||||
|
||||
// Add help command if it was set
|
||||
if (cfgCommandHelp())
|
||||
strCatFmt(mainCallParam, ", '%s'", cfgCommandName(cfgCmdHelp));
|
||||
|
||||
// Add command to pass to main
|
||||
if (cfgCommand() != cfgCmdNone && cfgCommand() != cfgCmdHelp)
|
||||
strCatFmt(mainCallParam, ", '%s'", cfgCommandName(cfgCommand()));
|
||||
strCat(configJson, "}");
|
||||
|
||||
// Add command arguments to pass to main
|
||||
String *commandParam = strNew("");
|
||||
|
||||
for (unsigned int paramIdx = 0; paramIdx < strLstSize(cfgCommandParam()); paramIdx++)
|
||||
strCatFmt(mainCallParam, ", '%s'", strPtr(strLstGet(cfgCommandParam(), paramIdx)));
|
||||
strCatFmt(commandParam, ",'%s'", strPtr(strLstGet(cfgCommandParam(), paramIdx)));
|
||||
|
||||
// Add Perl options
|
||||
StringList *perlOptionList = strLstNewVarLst(cfgOptionLst(cfgOptPerlOption));
|
||||
@ -125,7 +159,9 @@ StringList *perlCommand()
|
||||
strLstAdd(perlArgList, strLstGet(perlOptionList, argIdx));
|
||||
|
||||
// Construct Perl main call
|
||||
String *mainCall = strNewFmt(PGBACKREST_MAIN "('%s'%s)", strPtr(cfgExe()), strPtr(mainCallParam));
|
||||
String *mainCall = strNewFmt(
|
||||
PGBACKREST_MAIN "('%s','%s','%s'%s)", strPtr(cfgExe()), cfgCommandName(cfgCommand()), strPtr(configJson),
|
||||
strPtr(commandParam));
|
||||
|
||||
// End arg list for perl exec
|
||||
strLstAdd(perlArgList, strNew("-M" PGBACKREST_MODULE));
|
||||
|
@ -80,6 +80,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -449,6 +451,8 @@ stop all stanzas (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --repo-path=[TEST_PATH]/db-master/repo
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 INFO: sent term signal to process [PROCESS-ID]
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
@ -471,6 +475,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -563,6 +569,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --repo-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
|
||||
@ -575,6 +583,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --repo-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 WARN: stop file already exists for stanza db
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
@ -651,6 +661,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -1009,6 +1021,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = restore
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -1645,6 +1659,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -1964,6 +1980,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -4611,7 +4629,7 @@ info bogus stanza - bogus stanza (db-master host)
|
||||
diff backup - config file warning on local (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --no-online --log-level-console=info 2>&1 --type=diff --stanza=db backup
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
WARN: [TEST_PATH]/db-master/pgbackrest.conf file contains invalid option 'bogus'
|
||||
WARN: '[TEST_PATH]/db-master/pgbackrest.conf' contains invalid option 'bogus'
|
||||
P00 INFO: backup command begin [BACKREST-VERSION]: --compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base-2/base --db-timeout=45 --hardlink --lock-path=[TEST_PATH]/db-master/lock --log-level-console=info --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db --start-fast --type=diff
|
||||
P00 WARN: option retention-full is not set, the repository may run out of space
|
||||
HINT: to retain full backups indefinitely (without warning), set option 'retention-full' to the maximum.
|
||||
|
@ -80,6 +80,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 16384, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -470,6 +472,8 @@ stop all stanzas (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --force stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-2] --config=[TEST_PATH]/db-master/pgbackrest.conf --force --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 INFO: sent term signal to process [PROCESS-ID]
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
@ -492,6 +496,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -598,6 +604,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -645,6 +653,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-2] --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
|
||||
@ -657,6 +667,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-2] --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 WARN: stop file already exists for stanza db
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
@ -679,6 +691,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -760,6 +774,8 @@ stop all stanzas (backup host)
|
||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --force stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --force --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --repo-path=[TEST_PATH]/backup/repo
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 INFO: sent term signal to process [PROCESS-ID]
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
@ -782,6 +798,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -918,6 +936,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -1295,6 +1315,8 @@ P00 INFO: restore command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = restore
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/db-master/log
|
||||
@ -1721,6 +1743,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
@ -2070,6 +2094,8 @@ P00 DEBUG: Storage::Local->pathExists=>: bExists = true
|
||||
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = <true>, bRemote = <false>, strLockType = backup
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
P00 DEBUG: Common::Lock::lockStopTest=>: bStopExists = false
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Lock::lockAcquire=>: bResult = true
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 0770, strPathExp = [TEST_PATH]/backup/log
|
||||
|
@ -79,6 +79,8 @@ P00 DEBUG: Archive::Common::walInfo(): strWalFile = [TEST_PATH]/db-master/d
|
||||
P00 DEBUG: Archive::Common::walInfo=>: strDbVersion = 9.4, ullDbSysId = 1000000000000000094
|
||||
P00 DEBUG: Archive::Push::File::archivePushCheck(): strArchiveFile = 000000010000000100000001, strDbVersion = 9.4, strWalFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001, ullDbSysId = 1000000000000000094
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, strArchiveClusterPath = [TEST_PATH]/db-master/repo/archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = true
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = true
|
||||
@ -114,6 +116,7 @@ P00 DEBUG: Common::Exit::exitSafe=>: iExitCode = 0
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: --no-compress --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --repo-cipher-pass=<redacted> --repo-cipher-type=aes-256-cbc --repo-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||
P00 DEBUG: Archive::Get::Get->process(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
|
||||
P00 INFO: get WAL segment 000000010000000100000001
|
||||
P00 DEBUG: Archive::Get::Get->get(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
@ -127,6 +130,8 @@ P00 DEBUG: Db::dbObjectGet=>: iDbMasterIdx = 1, iDbStandbyIdx = [undef], oD
|
||||
P00 DEBUG: Db->info(): strDbPath = <[TEST_PATH]/db-master/db/base>
|
||||
P00 DEBUG: Db->info=>: iDbCatalogVersion = 201409291, iDbControlVersion = 942, strDbVersion = 9.4, ullDbSysId = 1000000000000000094
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = true, strArchiveClusterPath = [TEST_PATH]/db-master/repo/archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = true
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = true
|
||||
|
@ -100,6 +100,7 @@ P00 DEBUG: Common::Exit::exitSafe=>: iExitCode = 0
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get --log-level-console=debug 000000010000000100000001 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-1] --no-compress --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --stanza=db
|
||||
P00 DEBUG: Archive::Get::Get->process(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
|
||||
P00 INFO: get WAL segment 000000010000000100000001
|
||||
P00 DEBUG: Archive::Get::Get->get(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000001
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
|
@ -189,6 +189,8 @@ P00 DEBUG: Archive::Common::walInfo(): strWalFile = [TEST_PATH]/db-master/d
|
||||
P00 DEBUG: Archive::Common::walInfo=>: strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Push::File::archivePushCheck(): strArchiveFile = 000000010000000100000001, strDbVersion = 9.3, strWalFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, strArchiveClusterPath = [TEST_PATH]/db-master/repo/archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -476,6 +478,8 @@ P00 DEBUG: Archive::Common::walInfo(): strWalFile = [TEST_PATH]/db-master/d
|
||||
P00 DEBUG: Archive::Common::walInfo=>: strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Push::File::archivePushCheck(): strArchiveFile = 000000010000000100000002, strDbVersion = 9.3, strWalFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, strArchiveClusterPath = [TEST_PATH]/db-master/repo/archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -557,6 +561,7 @@ db-version="9.4"
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||
P00 DEBUG: Archive::Get::Get->process(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 INFO: get WAL segment 000000010000000100000002
|
||||
P00 DEBUG: Archive::Get::Get->get(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
@ -570,6 +575,8 @@ P00 DEBUG: Db::dbObjectGet=>: iDbMasterIdx = 1, iDbStandbyIdx = [undef], oD
|
||||
P00 DEBUG: Db->info(): strDbPath = <[TEST_PATH]/db-master/db/base>
|
||||
P00 DEBUG: Db->info=>: iDbCatalogVersion = 201306121, iDbControlVersion = 937, strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = true, strArchiveClusterPath = [TEST_PATH]/db-master/repo/archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = [TEST_PATH]/db-master/repo/archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -996,6 +1003,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --repo-path=[TEST_PATH]/db-master/repo --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
|
||||
|
@ -414,6 +414,7 @@ db-version="9.4"
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-2] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --stanza=db
|
||||
P00 DEBUG: Archive::Get::Get->process(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 INFO: get WAL segment 000000010000000100000002
|
||||
P00 DEBUG: Archive::Get::Get->get(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
@ -821,6 +822,8 @@ stop db stanza (backup host)
|
||||
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/backup/pgbackrest.conf --db1-cmd=[BACKREST-BIN] --db1-config=[TEST_PATH]/db-master/pgbackrest.conf --db1-host=db-master --lock-path=[TEST_PATH]/backup/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/backup/log --repo-cipher-pass=<redacted> --repo-cipher-type=aes-256-cbc --repo-path=[TEST_PATH]/backup/repo --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/backup/lock
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
|
||||
|
@ -189,6 +189,8 @@ P00 DEBUG: Archive::Common::walInfo(): strWalFile = [TEST_PATH]/db-master/d
|
||||
P00 DEBUG: Archive::Common::walInfo=>: strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Push::File::archivePushCheck(): strArchiveFile = 000000010000000100000001, strDbVersion = 9.3, strWalFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000001, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, strArchiveClusterPath = /archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = /archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -451,6 +453,8 @@ P00 DEBUG: Archive::Common::walInfo(): strWalFile = [TEST_PATH]/db-master/d
|
||||
P00 DEBUG: Archive::Common::walInfo=>: strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Push::File::archivePushCheck(): strArchiveFile = 000000010000000100000002, strDbVersion = 9.3, strWalFile = [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = <true>, strArchiveClusterPath = /archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = /archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -532,6 +536,7 @@ db-version="9.4"
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-get 000000010000000100000002 [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: archive-get command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --repo-path=/ --repo-s3-bucket=pgbackrest-dev --repo-s3-endpoint=s3.amazonaws.com --repo-s3-key=<redacted> --repo-s3-key-secret=<redacted> --repo-s3-region=us-east-1 --no-repo-s3-verify-ssl --repo-type=s3 --stanza=db
|
||||
P00 DEBUG: Archive::Get::Get->process(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 INFO: get WAL segment 000000010000000100000002
|
||||
P00 DEBUG: Archive::Get::Get->get(): strDestinationFile = [TEST_PATH]/db-master/db/base/pg_xlog/RECOVERYXLOG, strSourceArchive = 000000010000000100000002
|
||||
P00 DEBUG: Common::Lock::lockStopTest(): bStanzaStopRequired = <false>
|
||||
@ -545,6 +550,8 @@ P00 DEBUG: Db::dbObjectGet=>: iDbMasterIdx = 1, iDbStandbyIdx = [undef], oD
|
||||
P00 DEBUG: Db->info(): strDbPath = <[TEST_PATH]/db-master/db/base>
|
||||
P00 DEBUG: Db->info=>: iDbCatalogVersion = 201306121, iDbControlVersion = 937, strDbVersion = 9.3, ullDbSysId = 1000000000000000093
|
||||
P00 DEBUG: Archive::Info->new(): bIgnoreMissing = <false>, bLoad = <true>, bRequired = true, strArchiveClusterPath = /archive/db, strCipherPassSub = [undef]
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = 4194304, oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->encrypted(): bIgnoreMissing = true, strFileName = /archive/db/archive.info
|
||||
P00 DEBUG: Storage::Local->encrypted=>: bEncrypted = false
|
||||
P00 DEBUG: Storage::Local->encryptionValid(): bEncrypted = false
|
||||
@ -983,6 +990,8 @@ stop db stanza (db-master host)
|
||||
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db stop
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
P00 INFO: stop command begin [BACKREST-VERSION]: --config=[TEST_PATH]/db-master/pgbackrest.conf --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --repo-path=/ --repo-s3-bucket=pgbackrest-dev --repo-s3-endpoint=s3.amazonaws.com --repo-s3-key=<redacted> --repo-s3-key-secret=<redacted> --repo-s3-region=us-east-1 --no-repo-s3-verify-ssl --repo-type=s3 --stanza=db
|
||||
P00 DEBUG: Storage::Posix::Driver->new(): bFileSync = <true>, bPathSync = <true>
|
||||
P00 DEBUG: Storage::Local->new(): bAllowTemp = <true>, hRule = [undef], lBufferMax = [undef], oDriver = [object], strCipherPassUser = [undef], strCipherType = [undef], strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strPathBase = /, strTempExtension = pgbackrest.tmp
|
||||
P00 DEBUG: Storage::Local->pathCreate(): bCreateParent = true, bIgnoreExists = true, strMode = 770, strPathExp = [TEST_PATH]/db-master/lock
|
||||
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = 0, oException = [undef], strSignal = [undef]
|
||||
P00 DEBUG: Protocol::Helper::protocolDestroy(): bComplete = true, iRemoteIdx = [undef], strRemoteType = [undef]
|
||||
|
@ -470,18 +470,6 @@ my $oTestDef =
|
||||
'config/load' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'unit',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'option',
|
||||
&TESTDEF_TOTAL => 34,
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'config-perl',
|
||||
&TESTDEF_TOTAL => 25,
|
||||
}
|
||||
]
|
||||
},
|
||||
# Storage tests
|
||||
|
@ -153,7 +153,7 @@ sub run
|
||||
# Create gcov directory
|
||||
my $bGCovExists = true;
|
||||
|
||||
if (!$self->{oStorageTest}->pathExists($self->{strGCovPath}))
|
||||
if ($self->{oTest}->{&TEST_C} && !$self->{oStorageTest}->pathExists($self->{strGCovPath}))
|
||||
{
|
||||
$self->{oStorageTest}->pathCreate($self->{strGCovPath}, {strMode => '0770'});
|
||||
$bGCovExists = false;
|
||||
@ -165,7 +165,7 @@ sub run
|
||||
'docker run -itd -h ' . $self->{oTest}->{&TEST_VM} . "-test --name=${strImage}" .
|
||||
" -v $self->{strCoveragePath}:$self->{strCoveragePath} " .
|
||||
" -v ${strHostTestPath}:${strVmTestPath}" .
|
||||
" -v $self->{strGCovPath}:$self->{strGCovPath}" .
|
||||
($self->{oTest}->{&TEST_C} ? " -v $self->{strGCovPath}:$self->{strGCovPath}" : '') .
|
||||
" -v $self->{strBackRestBase}:$self->{strBackRestBase} " .
|
||||
containerRepo() . ':' . $self->{oTest}->{&TEST_VM} .
|
||||
"-test",
|
||||
|
@ -12,10 +12,12 @@ use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
use Getopt::Long qw(GetOptions);
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
use pgBackRestBuild::Config::Data;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use constant CONFIGENVTEST => 'ConfigEnvTest';
|
||||
|
||||
@ -101,13 +103,347 @@ sub commandTestWrite
|
||||
return @szyParam;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# testOptionValidate
|
||||
#
|
||||
# Make sure the command-line options are valid based on the command.
|
||||
####################################################################################################################################
|
||||
sub testOptionValidate
|
||||
{
|
||||
my $iCommandId = shift;
|
||||
|
||||
# Build hash with all valid command-line options
|
||||
my @stryOptionAllow;
|
||||
|
||||
for (my $iOptionId = 0; $iOptionId < cfgOptionTotal(); $iOptionId++)
|
||||
{
|
||||
my $strOption = cfgOptionName($iOptionId);
|
||||
|
||||
if (cfgDefOptionType($iOptionId) == CFGDEF_TYPE_HASH || cfgDefOptionType($iOptionId) == CFGDEF_TYPE_LIST)
|
||||
{
|
||||
$strOption .= '=s@';
|
||||
}
|
||||
elsif (cfgDefOptionType($iOptionId) != CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strOption .= '=s';
|
||||
}
|
||||
|
||||
push(@stryOptionAllow, $strOption);
|
||||
|
||||
# Check if the option can be negated
|
||||
if (cfgDefOptionNegate($iOptionId))
|
||||
{
|
||||
push(@stryOptionAllow, 'no-' . cfgOptionName($iOptionId));
|
||||
}
|
||||
}
|
||||
|
||||
# Get command-line options
|
||||
my $oOptionTest = {};
|
||||
|
||||
# Parse command line options
|
||||
if (!GetOptions($oOptionTest, @stryOptionAllow))
|
||||
{
|
||||
confess &log(ASSERT, "error parsing command line");
|
||||
}
|
||||
|
||||
# Store results of validation
|
||||
my $rhOption = {};
|
||||
|
||||
# Keep track of unresolved dependencies
|
||||
my $bDependUnresolved = true;
|
||||
my %oOptionResolved;
|
||||
|
||||
# Loop through all possible options
|
||||
while ($bDependUnresolved)
|
||||
{
|
||||
# Assume that all dependencies will be resolved in this loop
|
||||
$bDependUnresolved = false;
|
||||
|
||||
for (my $iOptionId = 0; $iOptionId < cfgOptionTotal(); $iOptionId++)
|
||||
{
|
||||
my $strOption = cfgOptionName($iOptionId);
|
||||
|
||||
# Skip the option if it has been resolved in a prior loop
|
||||
if (defined($oOptionResolved{$strOption}))
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Determine if an option is valid for a command
|
||||
$rhOption->{$strOption}{valid} = cfgDefOptionValid($iCommandId, $iOptionId);
|
||||
|
||||
if (!$rhOption->{$strOption}{valid})
|
||||
{
|
||||
$oOptionResolved{$strOption} = true;
|
||||
next;
|
||||
}
|
||||
|
||||
# Store the option value
|
||||
my $strValue = $oOptionTest->{$strOption};
|
||||
|
||||
# Check to see if an option can be negated. Make sure that it is not set and negated at the same time.
|
||||
$rhOption->{$strOption}{negate} = false;
|
||||
|
||||
if (cfgDefOptionNegate($iOptionId))
|
||||
{
|
||||
$rhOption->{$strOption}{negate} = defined($$oOptionTest{'no-' . $strOption});
|
||||
|
||||
if ($rhOption->{$strOption}{negate} && defined($strValue))
|
||||
{
|
||||
confess &log(ERROR, "option '${strOption}' cannot be both set and negated", ERROR_OPTION_NEGATE);
|
||||
}
|
||||
|
||||
if ($rhOption->{$strOption}{negate} && cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
# Check dependency for the command then for the option
|
||||
my $bDependResolved = true;
|
||||
my $strDependOption;
|
||||
my $strDependValue;
|
||||
my $strDependType;
|
||||
|
||||
if (cfgDefOptionDepend($iCommandId, $iOptionId))
|
||||
{
|
||||
# Check if the depend option has a value
|
||||
my $iDependOptionId = cfgDefOptionDependOption($iCommandId, $iOptionId);
|
||||
$strDependOption = cfgOptionName($iDependOptionId);
|
||||
$strDependValue = $rhOption->{$strDependOption}{value};
|
||||
|
||||
# Make sure the depend option has been resolved, otherwise skip this option for now
|
||||
if (!defined($oOptionResolved{$strDependOption}))
|
||||
{
|
||||
$bDependUnresolved = true;
|
||||
next;
|
||||
}
|
||||
|
||||
if (!defined($strDependValue))
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'source';
|
||||
}
|
||||
|
||||
# If a depend value exists, make sure the option value matches
|
||||
if ($bDependResolved && cfgDefOptionDependValueTotal($iCommandId, $iOptionId) == 1 &&
|
||||
cfgDefOptionDependValue($iCommandId, $iOptionId, 0) ne $strDependValue)
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'value';
|
||||
}
|
||||
|
||||
# If a depend list exists, make sure the value is in the list
|
||||
if ($bDependResolved && cfgDefOptionDependValueTotal($iCommandId, $iOptionId) > 1 &&
|
||||
!cfgDefOptionDependValueValid($iCommandId, $iOptionId, $strDependValue))
|
||||
{
|
||||
$bDependResolved = false;
|
||||
$strDependType = 'list';
|
||||
}
|
||||
}
|
||||
|
||||
if (cfgDefOptionDepend($iCommandId, $iOptionId) && !$bDependResolved && defined($strValue))
|
||||
{
|
||||
my $strError = "option '${strOption}' not valid without option ";
|
||||
my $iDependOptionId = cfgOptionId($strDependOption);
|
||||
|
||||
if ($strDependType eq 'source')
|
||||
{
|
||||
confess &log(ERROR, "${strError}'${strDependOption}'", ERROR_OPTION_INVALID);
|
||||
}
|
||||
|
||||
# If a depend value exists, make sure the option value matches
|
||||
if ($strDependType eq 'value')
|
||||
{
|
||||
if (cfgDefOptionType($iDependOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$strError .=
|
||||
"'" . (cfgDefOptionDependValue($iCommandId, $iOptionId, 0) ? '' : 'no-') . "${strDependOption}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$strError .= "'${strDependOption}' = '" . cfgDefOptionDependValue($iCommandId, $iOptionId, 0) . "'";
|
||||
}
|
||||
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
|
||||
$strError .= "'${strDependOption}'";
|
||||
|
||||
# If a depend list exists, make sure the value is in the list
|
||||
if ($strDependType eq 'list')
|
||||
{
|
||||
my @oyValue;
|
||||
|
||||
for (my $iValueId = 0; $iValueId < cfgDefOptionDependValueTotal($iCommandId, $iOptionId); $iValueId++)
|
||||
{
|
||||
push(@oyValue, "'" . cfgDefOptionDependValue($iCommandId, $iOptionId, $iValueId) . "'");
|
||||
}
|
||||
|
||||
$strError .= @oyValue == 1 ? " = $oyValue[0]" : " in (" . join(", ", @oyValue) . ")";
|
||||
confess &log(ERROR, $strError, ERROR_OPTION_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
# Is the option defined?
|
||||
if (defined($strValue))
|
||||
{
|
||||
# Check that floats and integers are valid
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_INTEGER ||
|
||||
cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_FLOAT)
|
||||
{
|
||||
# Test that the string is a valid float or integer by adding 1 to it. It's pretty hokey but it works and it
|
||||
# beats requiring Scalar::Util::Numeric to do it properly.
|
||||
my $bError = false;
|
||||
|
||||
eval
|
||||
{
|
||||
my $strTest = $strValue + 1;
|
||||
return true;
|
||||
}
|
||||
or do
|
||||
{
|
||||
$bError = true;
|
||||
};
|
||||
|
||||
# Check that integers are really integers
|
||||
if (!$bError && cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_INTEGER &&
|
||||
(int($strValue) . 'S') ne ($strValue . 'S'))
|
||||
{
|
||||
$bError = true;
|
||||
}
|
||||
|
||||
# Error if the value did not pass tests
|
||||
!$bError
|
||||
or confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Process an allow list for the command then for the option
|
||||
if (cfgDefOptionAllowList($iCommandId, $iOptionId) &&
|
||||
!cfgDefOptionAllowListValueValid($iCommandId, $iOptionId, $strValue))
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_VALUE);
|
||||
}
|
||||
|
||||
# Process an allow range for the command then for the option
|
||||
if (cfgDefOptionAllowRange($iCommandId, $iOptionId) &&
|
||||
($strValue < cfgDefOptionAllowRangeMin($iCommandId, $iOptionId) ||
|
||||
$strValue > cfgDefOptionAllowRangeMax($iCommandId, $iOptionId)))
|
||||
{
|
||||
confess &log(ERROR, "'${strValue}' is not valid for '${strOption}' option", ERROR_OPTION_INVALID_RANGE);
|
||||
}
|
||||
|
||||
# Set option value
|
||||
if (ref($strValue) eq 'ARRAY' &&
|
||||
(cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH || cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_LIST))
|
||||
{
|
||||
foreach my $strItem (@{$strValue})
|
||||
{
|
||||
my $strKey;
|
||||
my $strValue;
|
||||
|
||||
# If the keys are expected to have values
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_HASH)
|
||||
{
|
||||
# Check for = and make sure there is a least one character on each side
|
||||
my $iEqualPos = index($strItem, '=');
|
||||
|
||||
if ($iEqualPos < 1 || length($strItem) <= $iEqualPos + 1)
|
||||
{
|
||||
confess &log(ERROR, "'${strItem}' not valid key/value for '${strOption}' option",
|
||||
ERROR_OPTION_INVALID_PAIR);
|
||||
}
|
||||
|
||||
$strKey = substr($strItem, 0, $iEqualPos);
|
||||
$strValue = substr($strItem, $iEqualPos + 1);
|
||||
}
|
||||
# Else no values are expected so set value to true
|
||||
else
|
||||
{
|
||||
$strKey = $strItem;
|
||||
$strValue = true;
|
||||
}
|
||||
|
||||
# Check that the key has not already been set
|
||||
if (defined($rhOption->{$strOption}{$strKey}{value}))
|
||||
{
|
||||
confess &log(ERROR, "'${$strItem}' already defined for '${strOption}' option",
|
||||
ERROR_OPTION_DUPLICATE_KEY);
|
||||
}
|
||||
|
||||
# Set key/value
|
||||
$rhOption->{$strOption}{value}{$strKey} = $strValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$rhOption->{$strOption}{value} = $strValue;
|
||||
}
|
||||
|
||||
# If not config sourced then it must be a param
|
||||
if (!defined($rhOption->{$strOption}{source}))
|
||||
{
|
||||
$rhOption->{$strOption}{source} = CFGDEF_SOURCE_PARAM;
|
||||
}
|
||||
}
|
||||
# Else try to set a default
|
||||
elsif ($bDependResolved)
|
||||
{
|
||||
# Source is default for this option
|
||||
$rhOption->{$strOption}{source} = CFGDEF_SOURCE_DEFAULT;
|
||||
|
||||
# Check for default in command then option
|
||||
my $strDefault = cfgDefOptionDefault($iCommandId, $iOptionId);
|
||||
|
||||
# If default is defined
|
||||
if (defined($strDefault))
|
||||
{
|
||||
# Only set default if dependency is resolved
|
||||
$rhOption->{$strOption}{value} = $strDefault if !$rhOption->{$strOption}{negate};
|
||||
}
|
||||
# Else check required
|
||||
elsif (cfgDefOptionRequired($iCommandId, $iOptionId))
|
||||
{
|
||||
confess &log(ERROR,
|
||||
cfgCommandName($iCommandId) . " command requires option: ${strOption}" .
|
||||
ERROR_OPTION_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
$oOptionResolved{$strOption} = true;
|
||||
}
|
||||
}
|
||||
|
||||
# Make sure all options specified on the command line are valid
|
||||
foreach my $strOption (sort(keys(%{$oOptionTest})))
|
||||
{
|
||||
# Strip "no-" off the option
|
||||
$strOption = $strOption =~ /^no\-/ ? substr($strOption, 3) : $strOption;
|
||||
|
||||
if (!$rhOption->{$strOption}{valid})
|
||||
{
|
||||
confess &log(
|
||||
ERROR, "option '${strOption}' not valid for command '" . cfgCommandName($iCommandId) . "'", ERROR_OPTION_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
return $rhOption;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Load the configuration
|
||||
####################################################################################################################################
|
||||
sub configTestLoad
|
||||
{
|
||||
my $self = shift;
|
||||
my $iCommandId = shift;
|
||||
|
||||
@ARGV = $self->commandTestWrite(cfgCommandName($iCommandId), $self->{&CONFIGENVTEST});
|
||||
$self->testResult(sub {configLoad(false)}, true, 'config load: ' . join(" ", @ARGV));
|
||||
$self->testResult(
|
||||
sub {configLoad(
|
||||
false, backrestBin(), cfgCommandName($iCommandId),
|
||||
(JSON::PP->new()->allow_nonref())->encode(testOptionValidate($iCommandId)))},
|
||||
true, 'config load: ' . join(" ", @ARGV));
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
|
@ -1,362 +0,0 @@
|
||||
####################################################################################################################################
|
||||
# ConfigConfigTest.pm - Tests for mixed command line and config file options in Config.pm
|
||||
####################################################################################################################################
|
||||
package pgBackRestTest::Module::Config::ConfigConfigPerlTest;
|
||||
use parent 'pgBackRestTest::Env::ConfigEnvTest';
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
####################################################################################################################################
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Ini;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# run
|
||||
####################################################################################################################################
|
||||
sub run
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $oConfig = {};
|
||||
my $strConfigFile = $self->testPath() . '/pgbackrest.conf';
|
||||
|
||||
if ($self->begin('set and negate option ' . cfgOptionName(CFGOPT_CONFIG)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, '/dude/dude.conf');
|
||||
$self->optionTestSetBool(CFGOPT_CONFIG, false);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_NEGATE, cfgOptionName(CFGOPT_CONFIG));
|
||||
}
|
||||
|
||||
if ($self->begin('option ' . cfgOptionName(CFGOPT_CONFIG)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_CONFIG, false);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_CONFIG);
|
||||
}
|
||||
|
||||
if ($self->begin('default option ' . cfgOptionName(CFGOPT_CONFIG)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_CONFIG, cfgDefOptionDefault(CFGCMD_BACKUP, CFGOPT_CONFIG));
|
||||
}
|
||||
|
||||
if ($self->begin('config file is a path'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $self->testPath());
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_FILE_INVALID, $self->testPath());
|
||||
}
|
||||
|
||||
if ($self->begin('load from config stanza command section - option ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza() . ':' . cfgCommandName(CFGCMD_BACKUP)}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 2;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 2);
|
||||
}
|
||||
|
||||
if ($self->begin('load from config stanza section - option ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 3;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 3);
|
||||
}
|
||||
|
||||
if ($self->begin('load from config global command section - option thread-max'))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_BACKUP)}{'thread-max'} = 2;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 2);
|
||||
}
|
||||
|
||||
if ($self->begin('load from config global section - option ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 5;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 5);
|
||||
}
|
||||
|
||||
if ($self->begin('default - option ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$oConfig = {};
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 1);
|
||||
}
|
||||
|
||||
if ($self->begin('command-line override - option ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 9;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_PROCESS_MAX, 7);
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 7);
|
||||
}
|
||||
|
||||
if ($self->begin('invalid boolean - option ' . cfgOptionName(CFGOPT_HARDLINK)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_BACKUP)}{cfgOptionName(CFGOPT_HARDLINK)} = 'Y';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, 'Y', cfgOptionName(CFGOPT_HARDLINK));
|
||||
}
|
||||
|
||||
if ($self->begin('invalid value - option ' . cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE)} = BOGUS;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, BOGUS, cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE));
|
||||
}
|
||||
|
||||
if ($self->begin('valid value - option ' . cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE)} = lc(INFO);
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
}
|
||||
|
||||
if ($self->begin('archive-push - option ' . cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_ARCHIVE_PUSH));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_EXPIRE) . ' ' . cfgOptionName(CFGOPT_RETENTION_FULL)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza() . ':' . cfgCommandName(CFGCMD_EXPIRE)}{cfgOptionName(CFGOPT_RETENTION_FULL)} = 2;
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_EXPIRE));
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_FULL, 2);
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' option ' . cfgOptionName(CFGOPT_COMPRESS)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_BACKUP)}{cfgOptionName(CFGOPT_COMPRESS)} = 'n';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_COMPRESS, false);
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' global option ' . cfgOptionName(CFGOPT_RECOVERY_OPTION) . ' error'))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_RESTORE)}{cfgOptionName(CFGOPT_RECOVERY_OPTION)} = 'bogus=';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_VALUE, 'bogus=', cfgOptionName(CFGOPT_RECOVERY_OPTION));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' global option ' . cfgOptionName(CFGOPT_RECOVERY_OPTION) . ' error'))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_RESTORE)}{cfgOptionName(CFGOPT_RECOVERY_OPTION)} = '=bogus';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_VALUE, '=bogus', cfgOptionName(CFGOPT_RECOVERY_OPTION));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' global option ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_RESTORE)}{cfgOptionName(CFGOPT_RECOVERY_OPTION)} =
|
||||
'archive-command=/path/to/pgbackrest';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
$self->optionTestExpect(CFGOPT_RECOVERY_OPTION, '/path/to/pgbackrest', 'archive-command');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' stanza option ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_RECOVERY_OPTION)} = ['standby-mode=on', 'a=b'];
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
$self->optionTestExpect(CFGOPT_RECOVERY_OPTION, 'b', 'a');
|
||||
$self->optionTestExpect(CFGOPT_RECOVERY_OPTION, 'on', 'standby-mode');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' option ' . cfgOptionName(CFGOPT_DB_PATH)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_DB_PATH)} = '/path/to/db';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_DB_PATH, '/path/to/db');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' option ' . cfgOptionName(CFGOPT_ARCHIVE_CHECK)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_DB_PATH)} = '/path/to/db';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
$self->optionTestSetBool(CFGOPT_ARCHIVE_CHECK, false);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_ONLINE, true);
|
||||
$self->optionTestExpect(CFGOPT_ARCHIVE_CHECK, false);
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_ARCHIVE_PUSH) . ' option ' . cfgOptionName(CFGOPT_DB_PATH)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_DB_PATH)} = '/path/to/db';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_ARCHIVE_PUSH));
|
||||
$self->optionTestExpect(CFGOPT_DB_PATH, '/path/to/db');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' option ' . cfgOptionName(CFGOPT_REPO_PATH)))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_REPO_PATH)} = '/repo';
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_REPO_PATH, '/repo');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' option ' . cfgOptionName(CFGOPT_REPO_PATH) . ' multiple times'))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_REPO_PATH)} = ['/repo', '/repo2'];
|
||||
storageTest()->put($strConfigFile, iniRender($oConfig, true));
|
||||
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_CONFIG, $strConfigFile);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_MULTIPLE_VALUE, cfgOptionName(CFGOPT_REPO_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Getters
|
||||
####################################################################################################################################
|
||||
# Change this from the default so the same stanza is not used in all tests.
|
||||
sub stanza {return 'main'};
|
||||
|
||||
1;
|
@ -1,404 +0,0 @@
|
||||
####################################################################################################################################
|
||||
# ConfigOptionTest.pm - Tests for command line options in Config.pm
|
||||
####################################################################################################################################
|
||||
package pgBackRestTest::Module::Config::ConfigOptionTest;
|
||||
use parent 'pgBackRestTest::Env::ConfigEnvTest';
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
####################################################################################################################################
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
use English '-no_match_vars';
|
||||
|
||||
use Cwd qw(abs_path);
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
use pgBackRest::Version;
|
||||
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# run
|
||||
####################################################################################################################################
|
||||
sub run
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my @oyArray;
|
||||
|
||||
if ($self->begin('backup with no stanza'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_REQUIRED, cfgOptionName(CFGOPT_STANZA));
|
||||
}
|
||||
|
||||
if ($self->begin('backup with boolean stanza'))
|
||||
{
|
||||
$self->optionTestSetBool(CFGOPT_STANZA);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_COMMAND_REQUIRED);
|
||||
}
|
||||
|
||||
if ($self->begin('backup type defaults to ' . CFGOPTVAL_BACKUP_TYPE_INCR))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_TYPE, CFGOPTVAL_BACKUP_TYPE_INCR);
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' invalid option ' . cfgOptionName(CFGOPT_ARCHIVE_ASYNC)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_ARCHIVE_ASYNC);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_COMMAND, cfgOptionName(CFGOPT_ARCHIVE_ASYNC),
|
||||
cfgCommandName(CFGCMD_BACKUP));
|
||||
}
|
||||
|
||||
if ($self->begin('backup type set to ' . CFGOPTVAL_BACKUP_TYPE_FULL))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TYPE, CFGOPTVAL_BACKUP_TYPE_FULL);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_TYPE, CFGOPTVAL_BACKUP_TYPE_FULL);
|
||||
}
|
||||
|
||||
if ($self->begin('backup type invalid'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TYPE, BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, BOGUS, cfgOptionName(CFGOPT_TYPE));
|
||||
}
|
||||
|
||||
if ($self->begin('backup invalid force'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_FORCE);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID, cfgOptionName(CFGOPT_FORCE), 'no-' . cfgOptionName(CFGOPT_ONLINE));
|
||||
}
|
||||
|
||||
if ($self->begin('backup valid force'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_ONLINE, false);
|
||||
$self->optionTestSetBool(CFGOPT_FORCE);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_ONLINE, false);
|
||||
$self->optionTestExpect(CFGOPT_FORCE, true);
|
||||
}
|
||||
|
||||
if ($self->begin('backup invalid value for ' . cfgOptionName(CFGOPT_TEST_DELAY)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_TEST);
|
||||
$self->optionTestSet(CFGOPT_TEST_DELAY, BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, BOGUS, cfgOptionName(CFGOPT_TEST_DELAY));
|
||||
}
|
||||
|
||||
if ($self->begin('backup invalid ' . cfgOptionName(CFGOPT_TEST_DELAY)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TEST_DELAY, 5);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID, cfgOptionName(CFGOPT_TEST_DELAY), cfgOptionName(CFGOPT_TEST));
|
||||
}
|
||||
|
||||
if ($self->begin('backup check ' . cfgOptionName(CFGOPT_TEST_DELAY) . ' undef'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_TEST_DELAY);
|
||||
}
|
||||
|
||||
if ($self->begin('restore invalid ' . cfgOptionName(CFGOPT_TARGET)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TYPE, cfgDefOptionDefault(CFGCMD_RESTORE, CFGOPT_TYPE));
|
||||
$self->optionTestSet(CFGOPT_TARGET, BOGUS);
|
||||
|
||||
@oyArray = (CFGOPTVAL_RESTORE_TYPE_NAME, CFGOPTVAL_RESTORE_TYPE_TIME, CFGOPTVAL_RESTORE_TYPE_XID);
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID, cfgOptionName(CFGOPT_TARGET),
|
||||
cfgOptionName(CFGOPT_TYPE), \@oyArray);
|
||||
}
|
||||
|
||||
if ($self->begin('restore ' . cfgOptionName(CFGOPT_TARGET)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TYPE, CFGOPTVAL_RESTORE_TYPE_NAME);
|
||||
$self->optionTestSet(CFGOPT_TARGET, BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
$self->optionTestExpect(CFGOPT_TYPE, CFGOPTVAL_RESTORE_TYPE_NAME);
|
||||
$self->optionTestExpect(CFGOPT_TARGET, BOGUS);
|
||||
$self->optionTestExpect(CFGOPT_TARGET_TIMELINE);
|
||||
}
|
||||
|
||||
if ($self->begin('invalid string ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_PROCESS_MAX, BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, BOGUS, cfgOptionName(CFGOPT_PROCESS_MAX));
|
||||
}
|
||||
|
||||
if ($self->begin('invalid float ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_PROCESS_MAX, '0.0');
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, '0.0', cfgOptionName(CFGOPT_PROCESS_MAX));
|
||||
}
|
||||
|
||||
if ($self->begin('valid ' . cfgOptionName(CFGOPT_PROCESS_MAX)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_PROCESS_MAX, '2');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
}
|
||||
|
||||
if ($self->begin('valid thread-max'))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetByName('thread-max', '2');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROCESS_MAX, 2);
|
||||
}
|
||||
|
||||
if ($self->begin('valid float ' . cfgOptionName(CFGOPT_TEST_DELAY)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_TEST);
|
||||
$self->optionTestSet(CFGOPT_TEST_DELAY, '0.25');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
}
|
||||
|
||||
if ($self->begin('valid int ' . cfgOptionName(CFGOPT_TEST_DELAY)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSetBool(CFGOPT_TEST);
|
||||
$self->optionTestSet(CFGOPT_TEST_DELAY, 3);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
}
|
||||
|
||||
if ($self->begin('restore valid ' . cfgOptionName(CFGOPT_TARGET_TIMELINE)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_TARGET_TIMELINE, 2);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
}
|
||||
|
||||
if ($self->begin('invalid ' . cfgOptionName(CFGOPT_COMPRESS_LEVEL)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_COMPRESS_LEVEL, '12');
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_RANGE, '12', cfgOptionName(CFGOPT_COMPRESS_LEVEL));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' invalid value ' . cfgOptionName(CFGOPT_RETENTION_ARCHIVE_TYPE)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RETENTION_ARCHIVE_TYPE, BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, BOGUS, cfgOptionName(CFGOPT_RETENTION_ARCHIVE_TYPE));
|
||||
}
|
||||
|
||||
if ($self->begin(
|
||||
cfgCommandName(CFGCMD_BACKUP) . ' default value ' . cfgDefOptionDefault(CFGCMD_BACKUP, CFGOPT_RETENTION_ARCHIVE_TYPE) .
|
||||
' for ' . cfgOptionName(CFGOPT_RETENTION_ARCHIVE_TYPE) . ' with valid ' . cfgOptionName(CFGOPT_RETENTION_FULL)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RETENTION_FULL, 1);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE, 1);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_FULL, 1);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_DIFF, undef);
|
||||
# Default is FULL so this test will fail if the default is changed, alerting to the need to update configLoad.
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE_TYPE, CFGOPTVAL_BACKUP_TYPE_FULL);
|
||||
}
|
||||
|
||||
if ($self->begin(
|
||||
cfgCommandName(CFGCMD_BACKUP) . ' valid value ' . cfgOptionName(CFGOPT_RETENTION_ARCHIVE) . ' for ' .
|
||||
cfgOptionName(CFGOPT_RETENTION_ARCHIVE_TYPE) . ' ' . CFGOPTVAL_BACKUP_TYPE_DIFF))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RETENTION_DIFF, 1);
|
||||
$self->optionTestSet(CFGOPT_RETENTION_ARCHIVE_TYPE, CFGOPTVAL_BACKUP_TYPE_DIFF);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE, 1);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_DIFF, 1);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_FULL, undef);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE_TYPE, CFGOPTVAL_BACKUP_TYPE_DIFF);
|
||||
}
|
||||
|
||||
if ($self->begin(
|
||||
cfgCommandName(CFGCMD_BACKUP) . ' warn no valid value ' . cfgOptionName(CFGOPT_RETENTION_ARCHIVE) . ' for ' .
|
||||
cfgOptionName(CFGOPT_RETENTION_ARCHIVE_TYPE) . ' ' . CFGOPTVAL_BACKUP_TYPE_INCR))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RETENTION_FULL, 2);
|
||||
$self->optionTestSet(CFGOPT_RETENTION_DIFF, 1);
|
||||
$self->optionTestSet(CFGOPT_RETENTION_ARCHIVE_TYPE, CFGOPTVAL_BACKUP_TYPE_INCR);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE, undef);
|
||||
$self->optionTestExpect(CFGOPT_RETENTION_ARCHIVE_TYPE, CFGOPTVAL_BACKUP_TYPE_INCR);
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' invalid value ' . cfgOptionName(CFGOPT_PROTOCOL_TIMEOUT)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_DB_TIMEOUT, 5);
|
||||
$self->optionTestSet(CFGOPT_PROTOCOL_TIMEOUT, 4);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_INVALID_VALUE, 4, cfgOptionName(CFGOPT_PROTOCOL_TIMEOUT),
|
||||
"'protocol-timeout' option (4) should be greater than 'db-timeout' option (5)");
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' invalid value ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RECOVERY_OPTION, '=');
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_PAIR, '=', cfgOptionName(CFGOPT_RECOVERY_OPTION));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' invalid value ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RECOVERY_OPTION, '=' . BOGUS);
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_PAIR, '=' . BOGUS, cfgOptionName(CFGOPT_RECOVERY_OPTION));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' invalid value ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RECOVERY_OPTION, BOGUS . '=');
|
||||
|
||||
$self->configTestLoadExpect(
|
||||
cfgCommandName(CFGCMD_RESTORE), ERROR_OPTION_INVALID_PAIR, BOGUS . '=', cfgOptionName(CFGOPT_RECOVERY_OPTION));
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' valid value ' . cfgOptionName(CFGOPT_RECOVERY_OPTION)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_RECOVERY_OPTION, 'primary-conn-info=db.domain.net');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
$self->optionTestExpect(&CFGOPT_RECOVERY_OPTION, 'db.domain.net', 'primary-conn-info');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_RESTORE) . ' values passed to ' . cfgCommandName(CFGCMD_ARCHIVE_GET)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db path/main');
|
||||
$self->optionTestSet(CFGOPT_REPO_PATH, '/repo');
|
||||
$self->optionTestSet(CFGOPT_BACKUP_HOST, 'db.mydomain.com');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_RESTORE));
|
||||
|
||||
my $strCommand = cfgCommandWrite(CFGCMD_ARCHIVE_GET);
|
||||
my $strExpectedCommand =
|
||||
backrestBin() . " --backup-host=db.mydomain.com \"--db1-path=/db path/main\" --repo-path=/repo --stanza=app " .
|
||||
cfgCommandName(CFGCMD_ARCHIVE_GET);
|
||||
|
||||
if ($strCommand ne $strExpectedCommand)
|
||||
{
|
||||
confess "expected command '${strExpectedCommand}' but got '${strCommand}'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' default value ' . cfgOptionName(CFGOPT_DB_CMD)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_HOST, 'db');
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_DB_CMD, backrestBin());
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' missing option ' . cfgOptionName(CFGOPT_DB_PATH)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP), ERROR_OPTION_REQUIRED, 'db1-path', 'does this stanza exist?');
|
||||
}
|
||||
|
||||
if ($self->begin(cfgCommandName(CFGCMD_BACKUP) . ' automatically increase ' . cfgOptionName(CFGOPT_PROTOCOL_TIMEOUT)))
|
||||
{
|
||||
$self->optionTestSet(CFGOPT_STANZA, $self->stanza());
|
||||
$self->optionTestSet(CFGOPT_DB_PATH, '/db');
|
||||
$self->optionTestSet(CFGOPT_DB_TIMEOUT, cfgDefOptionDefault(CFGCMD_BACKUP, CFGOPT_PROTOCOL_TIMEOUT) + 30);
|
||||
|
||||
$self->configTestLoadExpect(cfgCommandName(CFGCMD_BACKUP));
|
||||
$self->optionTestExpect(CFGOPT_PROTOCOL_TIMEOUT, cfgDefOptionDefault(CFGCMD_BACKUP, CFGOPT_PROTOCOL_TIMEOUT) + 60);
|
||||
}
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# Getters
|
||||
####################################################################################################################################
|
||||
# Change this from the default so the same stanza is not used in all tests.
|
||||
sub stanza {return 'app'};
|
||||
|
||||
1;
|
@ -1,113 +0,0 @@
|
||||
####################################################################################################################################
|
||||
# ConfigUnitTest.pm - Tests code paths
|
||||
####################################################################################################################################
|
||||
package pgBackRestTest::Module::Config::ConfigUnitTest;
|
||||
use parent 'pgBackRestTest::Env::ConfigEnvTest';
|
||||
|
||||
####################################################################################################################################
|
||||
# Perl includes
|
||||
####################################################################################################################################
|
||||
use strict;
|
||||
use warnings FATAL => qw(all);
|
||||
use Carp qw(confess);
|
||||
|
||||
use pgBackRest::Common::Exception;
|
||||
use pgBackRest::Common::Ini;
|
||||
use pgBackRest::Common::Log;
|
||||
use pgBackRest::Config::Config;
|
||||
|
||||
use pgBackRestTest::Common::RunTest;
|
||||
|
||||
####################################################################################################################################
|
||||
# run
|
||||
####################################################################################################################################
|
||||
sub run
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $oConfig = {};
|
||||
my $strConfigFile = $self->testPath() . '/pgbackrest.conf';
|
||||
cfgCommandSet(CFGCMD_ARCHIVE_GET);
|
||||
cfgOptionSet(CFGOPT_CONFIG, $strConfigFile, true);
|
||||
|
||||
if ($self->begin('Config::configFileValidate()'))
|
||||
{
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_DB_PORT)} = 1234;
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, false,
|
||||
'valid option ' . cfgOptionName(CFGOPT_DB_PORT) . ' under invalid section',
|
||||
{strLogExpect =>
|
||||
"WARN: $strConfigFile valid option '" . cfgOptionName(CFGOPT_DB_PORT) . "' is a stanza section option and is not" .
|
||||
" valid in section " . CFGDEF_SECTION_GLOBAL . "\n" .
|
||||
"HINT: global options can be specified in global or stanza sections but not visa-versa"});
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_BACKUP)}{cfgOptionName(CFGOPT_DB_PORT)} = 1234;
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, false,
|
||||
'valid option ' . cfgOptionName(CFGOPT_DB_PORT) . ' for command ' . cfgCommandName(CFGCMD_BACKUP) .
|
||||
' under invalid global section',
|
||||
{strLogExpect =>
|
||||
"WARN: $strConfigFile valid option '" . cfgOptionName(CFGOPT_DB_PORT) . "' is a stanza section option and is not" .
|
||||
" valid in section " . CFGDEF_SECTION_GLOBAL . "\n" .
|
||||
"HINT: global options can be specified in global or stanza sections but not visa-versa"});
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{$self->stanza() . ':' . cfgCommandName(CFGCMD_ARCHIVE_PUSH)}{cfgOptionName(CFGOPT_DB_PORT)} = 1234;
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, false,
|
||||
'valid option ' . cfgOptionName(CFGOPT_DB_PORT) . ' under invalid stanza section command',
|
||||
{strLogExpect =>
|
||||
"WARN: $strConfigFile valid option '" . cfgOptionName(CFGOPT_DB_PORT) . "' is not valid for command '" .
|
||||
cfgCommandName(CFGCMD_ARCHIVE_PUSH) ."'"});
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{&BOGUS} = BOGUS;
|
||||
|
||||
$self->testResult(
|
||||
sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, false,
|
||||
'invalid option ' . $$oConfig{&CFGDEF_SECTION_GLOBAL}{&BOGUS},
|
||||
{strLogExpect => "WARN: $strConfigFile file contains invalid option '" . BOGUS . "'"});
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{'thread-max'} = 3;
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, true, 'valid alt name found');
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_LOG_LEVEL_STDERR)} =
|
||||
cfgDefOptionDefault(CFGCMD_ARCHIVE_PUSH, CFGOPT_LOG_LEVEL_STDERR);
|
||||
$$oConfig{$self->stanza()}{cfgOptionName(CFGOPT_DB_PATH)} = '/db';
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_ARCHIVE_PUSH)}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 2;
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, true, 'valid config file');
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{cfgOptionName(CFGOPT_LOG_LEVEL_STDERR)} =
|
||||
cfgDefOptionDefault(CFGCMD_ARCHIVE_PUSH, CFGOPT_LOG_LEVEL_STDERR);
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL . ':' . cfgCommandName(CFGCMD_ARCHIVE_PUSH)}{cfgOptionName(CFGOPT_PROCESS_MAX)} = 2;
|
||||
$$oConfig{'unusual-section^name!:' . cfgCommandName(CFGCMD_CHECK)}{cfgOptionName(CFGOPT_DB_PATH)} = '/db';
|
||||
|
||||
$self->testResult(sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, true, 'valid unusual section name');
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oConfig = {};
|
||||
$$oConfig{&CFGDEF_SECTION_GLOBAL}{&BOGUS} = BOGUS;
|
||||
|
||||
# Change command to indicate remote
|
||||
cfgCommandSet(CFGCMD_REMOTE);
|
||||
|
||||
$self->testResult(
|
||||
sub {pgBackRest::Config::Config::configFileValidate($oConfig)}, true,
|
||||
'invalid option but config file not validated on remote');
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
@ -14,6 +14,7 @@ Log Test Harness
|
||||
Name of file where logs are stored for testing
|
||||
***********************************************************************************************************************************/
|
||||
String *stdoutFile = NULL;
|
||||
String *stderrFile = NULL;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Initialize log for testing
|
||||
@ -25,6 +26,9 @@ testLogInit()
|
||||
|
||||
stdoutFile = strNewFmt("%s/stdout.log", testPath());
|
||||
logHandleStdOut = open(strPtr(stdoutFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
|
||||
|
||||
stderrFile = strNewFmt("%s/stderr.log", testPath());
|
||||
logHandleStdErr = open(strPtr(stderrFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -44,6 +48,23 @@ testLogResult(const char *expected)
|
||||
logHandleStdOut = open(strPtr(stdoutFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Compare error log to a static string
|
||||
|
||||
After the comparison the log is cleared so the next result can be compared.
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
testLogErrResult(const char *expected)
|
||||
{
|
||||
String *actual = strTrim(strNewBuf(storageGet(storageLocal(), stderrFile, false)));
|
||||
|
||||
if (!strEqZ(actual, expected))
|
||||
THROW(AssertError, "\n\nexpected error log:\n\n%s\n\nbut actual error log was:\n\n%s\n\n", expected, strPtr(actual));
|
||||
|
||||
close(logHandleStdErr);
|
||||
logHandleStdErr = open(strPtr(stderrFile), O_WRONLY | O_CREAT | O_TRUNC, 0640);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Make sure nothing is left in the log after all tests have completed
|
||||
***********************************************************************************************************************************/
|
||||
@ -54,4 +75,9 @@ testLogFinal()
|
||||
|
||||
if (!strEqZ(actual, ""))
|
||||
THROW(AssertError, "\n\nexpected log to be empty but actual log was:\n\n%s\n\n", strPtr(actual));
|
||||
|
||||
actual = strTrim(strNewBuf(storageGet(storageLocal(), stderrFile, false)));
|
||||
|
||||
if (!strEqZ(actual, ""))
|
||||
THROW(AssertError, "\n\nexpected error log to be empty but actual error log was:\n\n%s\n\n", strPtr(actual));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ Functions
|
||||
***********************************************************************************************************************************/
|
||||
void testLogInit();
|
||||
void testLogResult(const char *expected);
|
||||
void testLogErrResult(const char *expected);
|
||||
void testLogFinal();
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@ Test Archive Push Command
|
||||
***********************************************************************************************************************************/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config/parse.h"
|
||||
#include "config/load.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
@ -20,7 +20,8 @@ void testRun()
|
||||
strLstAddZ(argList, "--archive-timeout=1");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAddZ(argList, "archive-push");
|
||||
configParse(strLstSize(argList), strLstPtr(argList));
|
||||
cfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
logInit(logLevelInfo, logLevelOff, false);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
String *segment = strNew("000000010000000100000001");
|
||||
@ -90,13 +91,13 @@ void testRun()
|
||||
strLstAddZ(argList, "--archive-timeout=1");
|
||||
strLstAddZ(argList, "--stanza=db");
|
||||
strLstAddZ(argList, "archive-push");
|
||||
configParse(strLstSize(argList), strLstPtr(argList));
|
||||
cfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_ERROR(cmdArchivePush(), ParamRequiredError, "WAL segment to push required");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAddZ(argList, "000000010000000100000001");
|
||||
configParse(strLstSize(argList), strLstPtr(argList));
|
||||
cfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_ERROR(cmdArchivePush(), AssertError, "archive-push in C does not support synchronous mode");
|
||||
|
||||
@ -107,7 +108,8 @@ void testRun()
|
||||
strLstAdd(argList, strNewFmt("--perl-bin=%s", strPtr(perlBin)));
|
||||
strLstAdd(argList, strNewFmt("--spool-path=%s", testPath()));
|
||||
strLstAddZ(argList, "--archive-async");
|
||||
configParse(strLstSize(argList), strLstPtr(argList));
|
||||
cfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
logInit(logLevelInfo, logLevelOff, false);
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ void testRun()
|
||||
if (testBegin("logInit()"))
|
||||
{
|
||||
TEST_RESULT_INT(logLevelStdOut, logLevelOff, "console logging is off");
|
||||
TEST_RESULT_INT(logLevelStdErr, logLevelWarn, "stderr logging is warn");
|
||||
TEST_RESULT_INT(logLevelStdErr, logLevelOff, "stderr logging is off");
|
||||
TEST_RESULT_VOID(logInit(logLevelInfo, logLevelError, true), "init logging");
|
||||
TEST_RESULT_INT(logLevelStdOut, logLevelInfo, "console logging is info");
|
||||
TEST_RESULT_INT(logLevelStdErr, logLevelError, "stderr logging is error");
|
||||
|
@ -335,6 +335,15 @@ void testRun()
|
||||
)));
|
||||
|
||||
TEST_RESULT_VOID(configParse(strLstSize(argList), strLstPtr(argList)), TEST_COMMAND_BACKUP " command");
|
||||
logInit(logLevelInfo, logLevelOff, false);
|
||||
testLogErrResult(
|
||||
strPtr(
|
||||
strNewFmt(
|
||||
"WARN: '%s' contains option 'recovery-option' invalid for section 'db:backup'\n"
|
||||
"WARN: '%s' contains invalid option 'bogus'\n"
|
||||
"WARN: '%s' contains negate option 'no-compress'\n"
|
||||
"WARN: '%s' contains command-line only option 'online'",
|
||||
strPtr(configFile), strPtr(configFile), strPtr(configFile), strPtr(configFile))));
|
||||
|
||||
TEST_RESULT_STR(strPtr(cfgOptionStr(cfgOptDbPath)), "/path/to/db", " db-path is set");
|
||||
TEST_RESULT_INT(cfgOptionSource(cfgOptDbPath), cfgSourceConfig, " db-path is source config");
|
||||
|
@ -25,13 +25,13 @@ void testRun()
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(perlCommand(), "|")),
|
||||
"/usr/bin/perl|" TEST_PERL_MAIN "', 'info')|[NULL]", "custom command with no options");
|
||||
"/usr/bin/perl|" TEST_PERL_MAIN "','info','{}')|[NULL]", "custom command with no options");
|
||||
|
||||
cfgOptionSet(cfgOptPerlBin, cfgSourceParam, NULL);
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(perlCommand(), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "', 'info')|[NULL]", "command with no options");
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "','info','{}')|[NULL]", "command with no options");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cfgInit();
|
||||
@ -49,16 +49,21 @@ void testRun()
|
||||
cfgOptionSet(cfgOptProtocolTimeout, cfgSourceParam, varNewDbl(1.1));
|
||||
|
||||
cfgOptionValidSet(cfgOptCompressLevel, true);
|
||||
cfgOptionSet(cfgOptCompressLevel, cfgSourceParam, varNewInt(3));
|
||||
cfgOptionSet(cfgOptCompressLevel, cfgSourceConfig, varNewInt(3));
|
||||
|
||||
cfgOptionValidSet(cfgOptStanza, true);
|
||||
cfgOptionSet(cfgOptStanza, cfgSourceParam, varNewStr(strNew("db")));
|
||||
cfgOptionSet(cfgOptStanza, cfgSourceDefault, varNewStr(strNew("db")));
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(perlCommand(), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "'"
|
||||
", '--compress', '--compress-level', '3', '--no-online', '--protocol-timeout', '1.1', '--stanza', 'db'"
|
||||
", 'backup')|[NULL]", "simple options");
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|" TEST_PERL_MAIN "','backup','{"
|
||||
"\"compress\":{\"source\":\"param\",\"value\":true},"
|
||||
"\"compress-level\":{\"source\":\"config\",\"value\":3},"
|
||||
"\"online\":{\"source\":\"param\",\"negate\":true},"
|
||||
"\"protocol-timeout\":{\"source\":\"param\",\"value\":1.1},"
|
||||
"\"stanza\":{\"value\":\"db\"}"
|
||||
"}')|[NULL]",
|
||||
"simple options");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
cfgInit();
|
||||
@ -94,11 +99,11 @@ void testRun()
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(perlCommand(), "|")),
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|-MDevel::Cover=-silent,1|" TEST_PERL_MAIN "'"
|
||||
", '--db-include', 'db1', '--db-include', 'db2'"
|
||||
", '--perl-option', '-I.', '--perl-option', '-MDevel::Cover=-silent,1'"
|
||||
", '--recovery-option', 'standby_mode=on', '--recovery-option', 'primary_conn_info=blah'"
|
||||
", 'help', 'restore', 'param1', 'param2')|[NULL]", "complex options");
|
||||
TEST_ENV_EXE "|" TEST_PERL_EXE "|-I.|-MDevel::Cover=-silent,1|" TEST_PERL_MAIN "','restore','{"
|
||||
"\"db-include\":{\"source\":\"param\",\"value\":{\"db1\":true,\"db2\":true}},"
|
||||
"\"perl-option\":{\"source\":\"param\",\"value\":{\"-I.\":true,\"-MDevel::Cover=-silent,1\":true}},"
|
||||
"\"recovery-option\":{\"source\":\"param\",\"value\":{\"standby_mode\":\"on\",\"primary_conn_info\":\"blah\"}}"
|
||||
"}','param1','param2')|[NULL]", "complex options");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -86,7 +86,8 @@ void testRun()
|
||||
TEST_RESULT_PTR(storageList(storage, strNew(BOGUS_STR), NULL, true), NULL, "ignore missing dir");
|
||||
|
||||
TEST_RESULT_VOID(storagePut(storage, strNew("aaa.txt"), bufNewStr(strNew("aaa"))), "write aaa.text");
|
||||
TEST_RESULT_STR(strPtr(strLstJoin(storageList(storage, NULL, NULL, false), ", ")), "aaa.txt, stdout.log", "dir list");
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(storageList(storage, NULL, NULL, false), ", ")), "aaa.txt, stderr.log, stdout.log", "dir list");
|
||||
|
||||
TEST_RESULT_VOID(storagePut(storage, strNew("bbb.txt"), bufNewStr(strNew("bbb"))), "write bbb.text");
|
||||
TEST_RESULT_STR(strPtr(strLstJoin(storageList(storage, NULL, strNew("^bbb"), false), ", ")), "bbb.txt", "dir list");
|
||||
|
Loading…
x
Reference in New Issue
Block a user