mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Move logic for setting Perl configuration defaults to C.
This commit is contained in:
parent
919635b6f4
commit
fbe4c40386
@ -52,7 +52,7 @@
|
||||
|
||||
<release-development-list>
|
||||
<release-item>
|
||||
<p>Set config before <code>Main::main()</code> call to avoid secrets being exposed in a stack trace.</p>
|
||||
<p>Improve Perl configuration. Set config before <code>Main::main()</code> call to avoid secrets being exposed in a stack trace. Move logic for setting defaults to C.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
|
@ -85,24 +85,18 @@ sub configLoad
|
||||
my $strCommandName = shift;
|
||||
my $rstrConfigJson = shift;
|
||||
|
||||
# Clear option in case it was loaded before
|
||||
%oOption = ();
|
||||
|
||||
# Set backrest bin
|
||||
backrestBinSet($strBackRestBin);
|
||||
|
||||
# Set command
|
||||
$strCommand = $strCommandName;
|
||||
|
||||
# Convert options from JSON to a hash
|
||||
my $rhOption;
|
||||
|
||||
eval
|
||||
{
|
||||
# Hacky fix for backslashes that need to be escaped
|
||||
$$rstrConfigJson =~ s/\\/\\\\/g;
|
||||
|
||||
$rhOption = (JSON::PP->new()->allow_nonref())->decode($$rstrConfigJson);
|
||||
%oOption = %{(JSON::PP->new()->allow_nonref())->decode($$rstrConfigJson)};
|
||||
return true;
|
||||
}
|
||||
or do
|
||||
@ -115,51 +109,19 @@ sub configLoad
|
||||
{
|
||||
my $strOptionName = cfgOptionName($iOptionId);
|
||||
|
||||
# If option is not defined then it is not valid
|
||||
if (!defined($rhOption->{$strOptionName}))
|
||||
# If option is defined it is valid
|
||||
if (defined($oOption{$strOptionName}))
|
||||
{
|
||||
$oOption{$strOptionName}{valid} = false;
|
||||
# Convert JSON bool to standard bool that Perl understands
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN && defined($oOption{$strOptionName}{value}))
|
||||
{
|
||||
$oOption{$strOptionName}{value} = $oOption{$strOptionName}{value} eq INI_TRUE ? true : false;
|
||||
}
|
||||
}
|
||||
# Else set option
|
||||
# Else it is not valid
|
||||
else
|
||||
{
|
||||
$oOption{$strOptionName}{valid} = true;
|
||||
$oOption{$strOptionName}{source} =
|
||||
defined($rhOption->{$strOptionName}{source}) ? $rhOption->{$strOptionName}{source} : CFGDEF_SOURCE_DEFAULT;
|
||||
$oOption{$strOptionName}{reset} = false;
|
||||
$oOption{$strOptionName}{negate} = false;
|
||||
|
||||
# If option is negated only boolean will have a value
|
||||
if ($rhOption->{$strOptionName}{negate})
|
||||
{
|
||||
$oOption{$strOptionName}{negate} = true;
|
||||
|
||||
if (cfgDefOptionType($iOptionId) eq CFGDEF_TYPE_BOOLEAN)
|
||||
{
|
||||
$oOption{$strOptionName}{value} = false;
|
||||
}
|
||||
}
|
||||
# Else set the value
|
||||
else
|
||||
{
|
||||
# If option is reset, then indicate --reset should be prepended when passing the option to child processes
|
||||
if ($rhOption->{$strOptionName}{reset})
|
||||
{
|
||||
$oOption{$strOptionName}{reset} = true;
|
||||
}
|
||||
|
||||
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};
|
||||
}
|
||||
}
|
||||
}
|
||||
$oOption{$strOptionName}{valid} = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,120 +16,111 @@ perlOptionJson()
|
||||
{
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
{
|
||||
// Skip the option if it is not valid
|
||||
// Skip if not valid
|
||||
if (!cfgOptionValid(optionId))
|
||||
continue;
|
||||
|
||||
String *option = strNew("");
|
||||
// Add comma if not first valid option
|
||||
if (strSize(result) != 1)
|
||||
strCat(result, ",");
|
||||
|
||||
// Output source unless it is default
|
||||
if (cfgOptionSource(optionId) != cfgSourceDefault)
|
||||
// Add valid and source
|
||||
strCatFmt(result, "\"%s\":{\"valid\":true,\"source\":\"", cfgOptionName(optionId));
|
||||
|
||||
switch (cfgOptionSource(optionId))
|
||||
{
|
||||
strCat(option, "\"source\":\"");
|
||||
|
||||
if (cfgOptionSource(optionId) == cfgSourceParam)
|
||||
strCat(option, "param");
|
||||
else
|
||||
strCat(option, "config");
|
||||
|
||||
strCat(option, "\"");
|
||||
}
|
||||
|
||||
// If option was negated
|
||||
if (cfgOptionNegate(optionId))
|
||||
{
|
||||
// Add comma if needed
|
||||
if (strSize(option) != 0)
|
||||
strCat(option, ",");
|
||||
|
||||
strCatFmt(option, "\"negate\":%s", strPtr(varStrForce(varNewBool(true))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If option is reset then add flag
|
||||
if (cfgOptionReset(optionId))
|
||||
case cfgSourceParam:
|
||||
{
|
||||
// Add comma if needed
|
||||
if (strSize(option) != 0)
|
||||
strCat(option, ",");
|
||||
|
||||
strCatFmt(option, "\"reset\":%s", strPtr(varStrForce(varNewBool(true))));
|
||||
strCat(result, "param");
|
||||
break;
|
||||
}
|
||||
|
||||
// If has a value
|
||||
if (cfgOptionTest(optionId))
|
||||
case cfgSourceConfig:
|
||||
{
|
||||
// Add comma if needed
|
||||
if (strSize(option) != 0)
|
||||
strCat(option, ",");
|
||||
strCat(result, "config");
|
||||
break;
|
||||
}
|
||||
|
||||
strCat(option, "\"value\":");
|
||||
case cfgSourceDefault:
|
||||
{
|
||||
strCat(result, "default");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cfgDefOptionType(cfgOptionDefIdFromId(optionId)))
|
||||
strCat(result, "\"");
|
||||
|
||||
// Add negate
|
||||
strCatFmt(result, ",\"negate\":%s", strPtr(varStrForce(varNewBool(cfgOptionNegate(optionId)))));
|
||||
|
||||
// Add reset
|
||||
strCatFmt(result, ",\"reset\":%s", strPtr(varStrForce(varNewBool(cfgOptionReset(optionId)))));
|
||||
|
||||
// Add value if it is set
|
||||
if (cfgOptionTest(optionId))
|
||||
{
|
||||
strCat(result, ",\"value\":");
|
||||
|
||||
switch (cfgDefOptionType(cfgOptionDefIdFromId(optionId)))
|
||||
{
|
||||
case cfgDefOptTypeBoolean:
|
||||
case cfgDefOptTypeFloat:
|
||||
case cfgDefOptTypeInteger:
|
||||
{
|
||||
case cfgDefOptTypeBoolean:
|
||||
case cfgDefOptTypeFloat:
|
||||
case cfgDefOptTypeInteger:
|
||||
strCat(result, strPtr(varStrForce(cfgOption(optionId))));
|
||||
break;
|
||||
}
|
||||
|
||||
case cfgDefOptTypeString:
|
||||
{
|
||||
strCatFmt(result, "\"%s\"", strPtr(cfgOptionStr(optionId)));
|
||||
break;
|
||||
}
|
||||
|
||||
case cfgDefOptTypeHash:
|
||||
{
|
||||
const KeyValue *valueKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(valueKv);
|
||||
|
||||
strCat(result, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < varLstSize(keyList); listIdx++)
|
||||
{
|
||||
strCat(option, strPtr(varStrForce(cfgOption(optionId))));
|
||||
break;
|
||||
if (listIdx != 0)
|
||||
strCat(result, ",");
|
||||
|
||||
strCatFmt(
|
||||
result, "\"%s\":\"%s\"", strPtr(varStr(varLstGet(keyList, listIdx))),
|
||||
strPtr(varStr(kvGet(valueKv, varLstGet(keyList, listIdx)))));
|
||||
}
|
||||
|
||||
case cfgDefOptTypeString:
|
||||
strCat(result, "}");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cfgDefOptTypeList:
|
||||
{
|
||||
StringList *valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
|
||||
strCat(result, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < strLstSize(valueList); listIdx++)
|
||||
{
|
||||
strCatFmt(option, "\"%s\"", strPtr(cfgOptionStr(optionId)));
|
||||
break;
|
||||
if (listIdx != 0)
|
||||
strCat(result, ",");
|
||||
|
||||
strCatFmt(result, "\"%s\":true", strPtr(strLstGet(valueList, listIdx)));
|
||||
}
|
||||
|
||||
case cfgDefOptTypeHash:
|
||||
{
|
||||
const KeyValue *valueKv = cfgOptionKv(optionId);
|
||||
const VariantList *keyList = kvKeyList(valueKv);
|
||||
strCat(result, "}");
|
||||
|
||||
strCat(option, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < varLstSize(keyList); listIdx++)
|
||||
{
|
||||
if (listIdx != 0)
|
||||
strCat(option, ",");
|
||||
|
||||
strCatFmt(
|
||||
option, "\"%s\":\"%s\"", strPtr(varStr(varLstGet(keyList, listIdx))),
|
||||
strPtr(varStr(kvGet(valueKv, varLstGet(keyList, listIdx)))));
|
||||
}
|
||||
|
||||
strCat(option, "}");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cfgDefOptTypeList:
|
||||
{
|
||||
StringList *valueList = strLstNewVarLst(cfgOptionLst(optionId));
|
||||
|
||||
strCat(option, "{");
|
||||
|
||||
for (unsigned int listIdx = 0; listIdx < strLstSize(valueList); listIdx++)
|
||||
{
|
||||
if (listIdx != 0)
|
||||
strCat(option, ",");
|
||||
|
||||
strCatFmt(option, "\"%s\":true", strPtr(strLstGet(valueList, listIdx)));
|
||||
}
|
||||
|
||||
strCat(option, "}");
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add option to main JSON blob
|
||||
if (strSize(result) != 1)
|
||||
strCat(result, ",");
|
||||
|
||||
strCatFmt(result, "\"%s\":{%s}", cfgOptionName(optionId), strPtr(option));
|
||||
strCat(result, "}");
|
||||
}
|
||||
|
||||
strCat(result, "}");
|
||||
|
@ -10,7 +10,7 @@ void
|
||||
testRun()
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
if (testBegin("perlMain()"))
|
||||
if (testBegin("perlOptionJson()"))
|
||||
{
|
||||
cfgInit();
|
||||
TEST_RESULT_STR(strPtr(perlOptionJson()), "{}", "no options");
|
||||
@ -51,15 +51,15 @@ testRun()
|
||||
TEST_RESULT_STR(
|
||||
strPtr(perlOptionJson()),
|
||||
"{"
|
||||
"\"archive-queue-max\":{\"source\":\"param\",\"value\":999999999999},"
|
||||
"\"backup-standby\":{\"source\":\"param\",\"reset\":true,\"value\":false},"
|
||||
"\"compress\":{\"source\":\"param\",\"value\":true},"
|
||||
"\"compress-level\":{\"source\":\"config\",\"value\":3},"
|
||||
"\"config\":{\"source\":\"param\",\"negate\":true},"
|
||||
"\"online\":{\"source\":\"param\",\"negate\":true},"
|
||||
"\"pg1-host\":{\"reset\":true},"
|
||||
"\"protocol-timeout\":{\"source\":\"param\",\"value\":1.1},"
|
||||
"\"stanza\":{\"value\":\"db\"}"
|
||||
"\"archive-queue-max\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,\"value\":999999999999},"
|
||||
"\"backup-standby\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":true,\"value\":false},"
|
||||
"\"compress\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,\"value\":true},"
|
||||
"\"compress-level\":{\"valid\":true,\"source\":\"config\",\"negate\":false,\"reset\":false,\"value\":3},"
|
||||
"\"config\":{\"valid\":true,\"source\":\"param\",\"negate\":true,\"reset\":false},"
|
||||
"\"online\":{\"valid\":true,\"source\":\"param\",\"negate\":true,\"reset\":false,\"value\":false},"
|
||||
"\"pg1-host\":{\"valid\":true,\"source\":\"default\",\"negate\":false,\"reset\":true},"
|
||||
"\"protocol-timeout\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,\"value\":1.1},"
|
||||
"\"stanza\":{\"valid\":true,\"source\":\"default\",\"negate\":false,\"reset\":false,\"value\":\"db\"}"
|
||||
"}",
|
||||
"simple options");
|
||||
|
||||
@ -94,9 +94,12 @@ testRun()
|
||||
TEST_RESULT_STR(
|
||||
strPtr(perlOptionJson()),
|
||||
"{"
|
||||
"\"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\"}}"
|
||||
"\"db-include\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,"
|
||||
"\"value\":{\"db1\":true,\"db2\":true}},"
|
||||
"\"perl-option\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,"
|
||||
"\"value\":{\"-I.\":true,\"-MDevel::Cover=-silent,1\":true}},"
|
||||
"\"recovery-option\":{\"valid\":true,\"source\":\"param\",\"negate\":false,\"reset\":false,"
|
||||
"\"value\":{\"standby_mode\":\"on\",\"primary_conn_info\":\"blah\"}}"
|
||||
"}",
|
||||
"complex options");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user