1
0
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:
David Steele 2018-03-09 09:30:50 -05:00
parent 919635b6f4
commit fbe4c40386
4 changed files with 109 additions and 153 deletions

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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, "}");

View File

@ -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");
}