1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-12-13 23:25:51 +02:00
Files
pgbackrest/lib/pgBackRest/Config/Define.pm

572 lines
21 KiB
Perl

####################################################################################################################################
# Configuration Definition Interface
####################################################################################################################################
package pgBackRest::Config::Define;
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use Exporter qw(import);
our @EXPORT = qw();
use Storable qw(dclone);
use pgBackRest::Common::Exception;
use pgBackRest::Common::Log;
use pgBackRest::Config::Data;
####################################################################################################################################
# Generate indexed defines
####################################################################################################################################
my $rhConfigDefineIndex = cfgDefine();
foreach my $strKey (sort(keys(%{$rhConfigDefineIndex})))
{
# Build options for all possible db configurations
if (defined($rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX}) &&
$rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX} eq CFGDEF_PREFIX_DB)
{
my $strPrefix = $rhConfigDefineIndex->{$strKey}{&CFGDEF_PREFIX};
for (my $iIndex = 1; $iIndex <= CFGDEF_INDEX_DB; $iIndex++)
{
my $strKeyNew = "${strPrefix}${iIndex}" . substr($strKey, length($strPrefix));
$rhConfigDefineIndex->{$strKeyNew} = dclone($rhConfigDefineIndex->{$strKey});
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX_TOTAL} = CFGDEF_INDEX_DB;
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_INDEX} = $iIndex - 1;
# Create the alternate name for option index 1
if ($iIndex == 1)
{
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_ALT_NAME} = $strKey;
}
else
{
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_REQUIRED} = false;
}
if (defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}) &&
defined($rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION}))
{
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION} =
"${strPrefix}${iIndex}" .
substr(
$rhConfigDefineIndex->{$strKeyNew}{&CFGDEF_DEPEND}{&CFGDEF_DEPEND_OPTION},
length($strPrefix));
}
}
delete($rhConfigDefineIndex->{$strKey});
}
else
{
$rhConfigDefineIndex->{$strKey}{&CFGDEF_INDEX} = 0;
}
}
my $iOptionTotal = scalar(keys(%{$rhConfigDefineIndex}));
sub cfgDefineIndex
{
return dclone($rhConfigDefineIndex);
}
push @EXPORT, qw(cfgDefineIndex);
####################################################################################################################################
# Create maps to convert option ids to names and vice versa
####################################################################################################################################
my $rhOptionNameId;
my $rhOptionIdName;
my $rhOptionNameAlt;
{
my $iIndex = 0;
foreach my $strOption (sort(keys(%{$rhConfigDefineIndex})))
{
$rhOptionNameId->{$strOption} = $iIndex;
$rhOptionNameAlt->{$strOption} = $strOption;
$rhOptionIdName->{$iIndex} = $strOption;
if (defined(cfgDefOptionNameAlt($strOption)))
{
$rhOptionNameId->{cfgDefOptionNameAlt($strOption)} = $iIndex;
$rhOptionNameAlt->{cfgDefOptionNameAlt($strOption)} = $strOption;
}
$iIndex++;
}
}
####################################################################################################################################
# Get a define for the option from a command or default
####################################################################################################################################
sub cfgOptionDefine
{
my $strCommand = shift;
my $strOption = shift;
my $strDefine = shift;
return
defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}) &&
defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{$strDefine}) ?
$rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{$strDefine} :
$rhConfigDefineIndex->{$strOption}{$strDefine};
}
####################################################################################################################################
# Functions that are noops in the Perl code since commands/options are always treated as strings
####################################################################################################################################
sub cfgCommandId {return shift()}
sub cfgCommandName {return shift()}
sub cfgOptionId
{
my $strOptionName = shift;
if (!defined($rhOptionNameId->{$strOptionName}))
{
return -1;
}
return $rhOptionNameAlt->{$strOptionName};
}
sub cfgOptionName
{
my $strOptionId = shift;
if (defined($rhOptionIdName->{$strOptionId}))
{
return $rhOptionIdName->{$strOptionId};
}
return $rhOptionNameAlt->{$strOptionId};
}
push @EXPORT, qw(cfgCommandId cfgCommandName cfgOptionId cfgOptionName);
####################################################################################################################################
# cfgOptionTotal - total number of options
####################################################################################################################################
sub cfgOptionTotal
{
return $iOptionTotal;
}
push @EXPORT, qw(cfgOptionTotal);
####################################################################################################################################
# cfgDefOptionAllowList - does the option have a specific list of allowed values?
####################################################################################################################################
sub cfgDefOptionAllowList
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $bError = shift;
my $rhAllowList = cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST);
if (!defined($rhAllowList) && defined($bError) && $bError)
{
confess &log(ASSERT, "allow list not set for ${strCommand}, ${strOption}");
}
# The allow list must have values
if (defined($rhAllowList) && @{$rhAllowList} == 0)
{
confess &log(ASSERT, "allow list must have values for ${strCommand}, ${strOption}");
}
return defined($rhAllowList) ? true : false;
}
push @EXPORT, qw(cfgDefOptionAllowList);
####################################################################################################################################
# cfgDefOptionAllowListValue - get an allow list value
####################################################################################################################################
sub cfgDefOptionAllowListValue
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $iValueIdx = shift;
# Index shouldn't be greater than the total number of values
if ($iValueIdx >= cfgDefOptionAllowListValueTotal($strCommand, $strOption, $iValueIdx))
{
confess &log(ASSERT, "invalid allow list value index ${iValueIdx} for ${strCommand}, ${strOption}");
}
# Return value
return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)->[$iValueIdx];
}
push @EXPORT, qw(cfgDefOptionAllowListValue);
####################################################################################################################################
# cfgDefOptionAllowListValueTotal - how many values are allowed for the option?
####################################################################################################################################
sub cfgDefOptionAllowListValueTotal
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
# Make sure the allow list exists
cfgDefOptionAllowList($strCommand, $strOption, true);
# Return total elements in the list
return scalar(@{cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)});
}
push @EXPORT, qw(cfgDefOptionAllowListValueTotal);
####################################################################################################################################
# cfgDefOptionAllowListValueValid - is the value valid for this option?
####################################################################################################################################
sub cfgDefOptionAllowListValueValid
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $strValue = shift;
# Make sure the allow list exists
cfgDefOptionAllowList($strCommand, $strOption, true);
# Check if the value is valid
foreach my $strValueMatch (@{cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_LIST)})
{
if ($strValue eq $strValueMatch)
{
return true;
}
}
return false;
}
push @EXPORT, qw(cfgDefOptionAllowListValueValid);
####################################################################################################################################
# cfgDefOptionAllowRange - does the option have min/max values?
####################################################################################################################################
sub cfgDefOptionAllowRange
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $bError = shift;
my $rhAllowRange = cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE);
if (!defined($rhAllowRange) && defined($bError) && $bError)
{
confess &log(ASSERT, "allow range not set for ${strCommand}, ${strOption}");
}
# The allow range must have two values
if (defined($rhAllowRange) && @{$rhAllowRange} != 2)
{
confess &log(ASSERT, "allow range must have two values for ${strCommand}, ${strOption}");
}
return defined($rhAllowRange) ? true : false;
}
push @EXPORT, qw(cfgDefOptionAllowRange);
####################################################################################################################################
# cfgDefOptionAllowRangeMax - get max value in allowed range
####################################################################################################################################
sub cfgDefOptionAllowRangeMax
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
# Make sure the allow range exists
cfgDefOptionAllowRange($strCommand, $strOption);
# Return value
return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE)->[1];
}
push @EXPORT, qw(cfgDefOptionAllowRangeMax);
####################################################################################################################################
# cfgDefOptionAllowRangeMin - get min value in allowed range
####################################################################################################################################
sub cfgDefOptionAllowRangeMin
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
# Make sure the allow range exists
cfgDefOptionAllowRange($strCommand, $strOption);
# Return value
return cfgOptionDefine($strCommand, $strOption, CFGDEF_ALLOW_RANGE)->[0];
}
push @EXPORT, qw(cfgDefOptionAllowRangeMin);
####################################################################################################################################
# cfgDefOptionDefault - option default, if any
####################################################################################################################################
sub cfgDefOptionDefault
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
return cfgOptionDefine($strCommand, $strOption, CFGDEF_DEFAULT);
}
push @EXPORT, qw(cfgDefOptionDefault);
####################################################################################################################################
# cfgDefOptionDepend - does the option depend on another option being set or having a certain value?
####################################################################################################################################
sub cfgDefOptionDepend
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $bError = shift;
my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND);
if (!defined($rhDepend) && defined($bError) && $bError)
{
confess &log(ASSERT, "depend define not set for ${strCommand}, ${strOption}");
}
return defined($rhDepend) ? true : false;
}
push @EXPORT, qw(cfgDefOptionDepend);
####################################################################################################################################
# cfgDefOptionDependOption - name of the option that this option depends on
####################################################################################################################################
sub cfgDefOptionDependOption
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
# Make sure the depend define exists
cfgDefOptionDepend($strCommand, $strOption, true);
# Error if the depend option does not exist
my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND);
if (!defined($rhDepend->{&CFGDEF_DEPEND_OPTION}))
{
confess &log(ASSERT, "depend define option not set for ${strCommand}, ${strOption}");
}
return $rhDepend->{&CFGDEF_DEPEND_OPTION};
}
push @EXPORT, qw(cfgDefOptionDependOption);
####################################################################################################################################
# cfgDefOptionDependValue - get a depend option value
####################################################################################################################################
sub cfgDefOptionDependValue
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $iValueIdx = shift;
# Index shouldn't be greater than the total number of values
if ($iValueIdx >= cfgDefOptionDependValueTotal($strCommand, $strOption, $iValueIdx))
{
confess &log(ASSERT, "invalid depend value index ${iValueIdx} for ${strCommand}, ${strOption}");
}
# Return value
return cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND)->{&CFGDEF_DEPEND_LIST}->[$iValueIdx];
}
push @EXPORT, qw(cfgDefOptionDependValue);
####################################################################################################################################
# cfgDefOptionDependValueTotal - how many values are allowed for the depend option?
#
# 0 indicates that the value of the depend option doesn't matter, only that is is set.
####################################################################################################################################
sub cfgDefOptionDependValueTotal
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
# Make sure the depend define exists
cfgDefOptionDepend($strCommand, $strOption, true);
# It's OK for the list not to be defined
my $rhDepend = cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND);
if (!defined($rhDepend->{&CFGDEF_DEPEND_LIST}))
{
return 0;
}
# Return total elements in the list
return scalar(@{$rhDepend->{&CFGDEF_DEPEND_LIST}});
}
push @EXPORT, qw(cfgDefOptionDependValueTotal);
####################################################################################################################################
# cfgDefOptionDependValueValid - is the depend valid valid?
####################################################################################################################################
sub cfgDefOptionDependValueValid
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $strValue = shift;
# Make sure the depend define exists
cfgDefOptionDepend($strCommand, $strOption, true);
# Check if the value is valid
foreach my $strValueMatch (@{cfgOptionDefine($strCommand, $strOption, CFGDEF_DEPEND)->{&CFGDEF_DEPEND_LIST}})
{
if ($strValue eq $strValueMatch)
{
return true;
}
}
return false;
}
push @EXPORT, qw(cfgDefOptionDependValueValid);
####################################################################################################################################
# cfgOptionIndex - index for option
####################################################################################################################################
sub cfgOptionIndex
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_INDEX};
}
push @EXPORT, qw(cfgOptionIndex);
####################################################################################################################################
# cfgOptionIndexTotal - max index for options that are indexed (e.g., db)
####################################################################################################################################
sub cfgOptionIndexTotal
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_INDEX_TOTAL};
}
push @EXPORT, qw(cfgOptionIndexTotal);
####################################################################################################################################
# cfgDefOptionNameAlt - alternative or deprecated option name
####################################################################################################################################
sub cfgDefOptionNameAlt
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_ALT_NAME};
}
push @EXPORT, qw(cfgDefOptionNameAlt);
####################################################################################################################################
# cfgDefOptionNegate - is the boolean option negatable?
####################################################################################################################################
sub cfgDefOptionNegate
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_NEGATE};
}
push @EXPORT, qw(cfgDefOptionNegate);
####################################################################################################################################
# cfgDefOptionPrefix - fixed prefix for indexed options
####################################################################################################################################
sub cfgDefOptionPrefix
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_PREFIX};
}
push @EXPORT, qw(cfgDefOptionPrefix);
####################################################################################################################################
# cfgDefOptionRequired - is the option required?
####################################################################################################################################
sub cfgDefOptionRequired
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
my $rxDefine = cfgOptionDefine($strCommand, $strOption, CFGDEF_REQUIRED);
return defined($rxDefine) ? $rxDefine : true;
}
push @EXPORT, qw(cfgDefOptionRequired);
####################################################################################################################################
# cfgDefOptionSection - section to contain optio (global or stanza), all others are command-line only
####################################################################################################################################
sub cfgDefOptionSection
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_SECTION};
}
push @EXPORT, qw(cfgDefOptionSection);
####################################################################################################################################
# cfgDefOptionSecure - can the option be passed on the command-line?
####################################################################################################################################
sub cfgDefOptionSecure
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_SECURE};
}
push @EXPORT, qw(cfgDefOptionSecure);
####################################################################################################################################
# cfgDefOptionType - data type of the option (e.g. boolean, string)
####################################################################################################################################
sub cfgDefOptionType
{
my $strOption = cfgOptionName(shift);
return $rhConfigDefineIndex->{$strOption}{&CFGDEF_TYPE};
}
push @EXPORT, qw(cfgDefOptionType);
####################################################################################################################################
# cfgDefOptionValid - is the option valid for the command?
####################################################################################################################################
sub cfgDefOptionValid
{
my $strCommand = shift;
my $strOption = cfgOptionName(shift);
return
defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}) &&
defined($rhConfigDefineIndex->{$strOption}{&CFGDEF_COMMAND}{$strCommand}) ? true : false;
}
push @EXPORT, qw(cfgDefOptionValid);
1;