mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Remove cfgOptionId() and replace it with cfgParseOption().
cfgOptionId() did not recognize deprecated options which made the help command throw errors when they were specified on the command line. cfgParseOption() will correctly identify deprecated options. cfgParseOption() can also be used in cfgParse() to reduce code duplication when parsing info out of the option value returned by optionFind(). Finally, code the option key index separately in parse.auto.c. For now they are simply added back together but future code will need them separated.
This commit is contained in:
parent
6414ae9707
commit
41789d70d1
@ -143,7 +143,7 @@ sub buildConfigParse
|
||||
}
|
||||
|
||||
my $strOptionVal =
|
||||
($iOptionIdx > 1 ? "(" : '') . $strOptionEnum . ($iOptionIdx > 1 ? " + " . ($iOptionIdx - 1) . ')' : '');
|
||||
($rhOption->{&CFGDEF_GROUP} ? "(" . ($iOptionIdx - 1) . " << PARSE_KEY_IDX_SHIFT) | " : '') . $strOptionEnum;
|
||||
|
||||
# Add option
|
||||
$strBuildSource .=
|
||||
|
@ -12,6 +12,7 @@ Help Command
|
||||
#include "common/memContext.h"
|
||||
#include "config/config.h"
|
||||
#include "config/define.h"
|
||||
#include "config/parse.h"
|
||||
#include "version.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -303,19 +304,21 @@ helpRender(void)
|
||||
THROW(ParamInvalidError, "only one option allowed for option help");
|
||||
|
||||
// Ensure the option is valid
|
||||
const char *optionName = strZ(strLstGet(cfgCommandParam(), 0));
|
||||
ConfigOption optionId = cfgOptionId(optionName);
|
||||
const String *optionName = strLstGet(cfgCommandParam(), 0);
|
||||
CfgParseOptionResult option = cfgParseOption(optionName);
|
||||
|
||||
if (cfgOptionId(optionName) == -1)
|
||||
if (!option.found)
|
||||
{
|
||||
if (cfgDefOptionId(optionName) != -1)
|
||||
optionId = cfgOptionIdFromDefId(cfgDefOptionId(optionName), 0);
|
||||
int optionId = cfgDefOptionId(strZ(optionName));
|
||||
|
||||
if (optionId == -1)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", strZ(optionName), commandName);
|
||||
else
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", optionName, commandName);
|
||||
option.id = cfgOptionIdFromDefId((unsigned int)optionId, 0);
|
||||
}
|
||||
|
||||
// Output option summary and description
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(option.id);
|
||||
|
||||
strCatFmt(
|
||||
result,
|
||||
@ -324,16 +327,16 @@ helpRender(void)
|
||||
"%s\n"
|
||||
"\n"
|
||||
"%s\n",
|
||||
optionName,
|
||||
cfgDefOptionName(optionDefId),
|
||||
strZ(helpRenderText(STR(cfgDefOptionHelpSummary(commandId, optionDefId)), 0, true, CONSOLE_WIDTH)),
|
||||
strZ(helpRenderText(STR(cfgDefOptionHelpDescription(commandId, optionDefId)), 0, true, CONSOLE_WIDTH)));
|
||||
|
||||
// Ouput current and default values if they exist
|
||||
const String *defaultValue = helpRenderValue(cfgOptionDefault(optionId));
|
||||
const String *defaultValue = helpRenderValue(cfgOptionDefault(option.id));
|
||||
const String *value = NULL;
|
||||
|
||||
if (cfgOptionSource(optionId) != cfgSourceDefault)
|
||||
value = helpRenderValue(cfgOption(optionId));
|
||||
if (cfgOptionSource(option.id) != cfgSourceDefault)
|
||||
value = helpRenderValue(cfgOption(option.id));
|
||||
|
||||
if (value != NULL || defaultValue != NULL)
|
||||
{
|
||||
|
@ -713,25 +713,6 @@ cfgOptionIndex(ConfigOption optionId)
|
||||
FUNCTION_TEST_RETURN(configOptionData[optionId].index);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
int
|
||||
cfgOptionId(const char *optionName)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRINGZ, optionName);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(optionName != NULL);
|
||||
|
||||
int result = -1;
|
||||
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
if (strcmp(optionName, configOptionData[optionId].name) == 0)
|
||||
result = optionId;
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
ConfigOption
|
||||
cfgOptionIdFromDefId(ConfigDefineOption optionDefId, unsigned int index)
|
||||
|
@ -193,9 +193,6 @@ ConfigDefineOption cfgOptionDefIdFromId(ConfigOption optionId);
|
||||
// Parse a host option and extract the host and port (if it exists)
|
||||
String *cfgOptionHostPort(ConfigOption optionId, unsigned int *port);
|
||||
|
||||
// Get option id by name
|
||||
int cfgOptionId(const char *optionName);
|
||||
|
||||
// Get the id for this option define
|
||||
ConfigOption cfgOptionIdFromDefId(ConfigDefineOption optionDefId, unsigned int index);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -61,8 +61,12 @@ Parse option flags
|
||||
// Indicate that option name has been deprecated and will be removed in a future release
|
||||
#define PARSE_DEPRECATE_FLAG (1 << 27)
|
||||
|
||||
// Mask to exclude all flags and get at the actual option id (only 12 bits allowed for option id, the rest reserved for flags)
|
||||
#define PARSE_OPTION_MASK 0xFFF
|
||||
// Mask for option id (must be 0-255)
|
||||
#define PARSE_OPTION_MASK 0xFF
|
||||
|
||||
// Shift and mask for option key index (must be 0-255)
|
||||
#define PARSE_KEY_IDX_SHIFT 8
|
||||
#define PARSE_KEY_IDX_MASK 0xFF
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Include automatically generated data structure for getopt_long()
|
||||
@ -84,23 +88,46 @@ typedef struct ParseOption
|
||||
#define FUNCTION_LOG_PARSE_OPTION_FORMAT(value, buffer, bufferSize) \
|
||||
typeToLog("ParseOption", buffer, bufferSize)
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Find an option by name in the option list
|
||||
***********************************************************************************************************************************/
|
||||
static unsigned int
|
||||
optionFind(const String *option)
|
||||
/**********************************************************************************************************************************/
|
||||
// Helper to parse the option info into a structure
|
||||
__attribute__((always_inline)) static inline CfgParseOptionResult
|
||||
cfgParseOptionInfo(int info)
|
||||
{
|
||||
unsigned int optionIdx = 0;
|
||||
|
||||
while (optionList[optionIdx].name != NULL)
|
||||
return (CfgParseOptionResult)
|
||||
{
|
||||
if (strcmp(strZ(option), optionList[optionIdx].name) == 0)
|
||||
.found = true,
|
||||
.id = (info & PARSE_OPTION_MASK) + ((info >> PARSE_KEY_IDX_SHIFT) & PARSE_KEY_IDX_MASK),
|
||||
.negate = info & PARSE_NEGATE_FLAG,
|
||||
.reset = info & PARSE_RESET_FLAG,
|
||||
.deprecated = info & PARSE_DEPRECATE_FLAG,
|
||||
};
|
||||
}
|
||||
|
||||
CfgParseOptionResult
|
||||
cfgParseOption(const String *optionName)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, optionName);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(optionName != NULL);
|
||||
|
||||
// Search for the option
|
||||
unsigned int findIdx = 0;
|
||||
|
||||
while (optionList[findIdx].name != NULL)
|
||||
{
|
||||
if (strEqZ(optionName, optionList[findIdx].name))
|
||||
break;
|
||||
|
||||
optionIdx++;
|
||||
findIdx++;
|
||||
}
|
||||
|
||||
return optionIdx;
|
||||
// If the option was found
|
||||
if (optionList[findIdx].name != NULL)
|
||||
FUNCTION_TEST_RETURN(cfgParseOptionInfo(optionList[findIdx].val));
|
||||
|
||||
FUNCTION_TEST_RETURN((CfgParseOptionResult){0});
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -432,7 +459,7 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
|
||||
// Phase 1: parse command line parameters
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
int option; // Code returned by getopt_long
|
||||
int optionValue; // Value returned by getopt_long
|
||||
int optionListIdx; // Index of option is list (if an option was returned)
|
||||
bool argFound = false; // Track args found to decide on error or help at the end
|
||||
StringList *commandParamList = NULL; // List of command parameters
|
||||
@ -449,9 +476,9 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
// Only the first non-option parameter should be treated as a command so track if the command has been set
|
||||
bool commandSet = false;
|
||||
|
||||
while ((option = getopt_long((int)argListSize, (char **)argList, "-:", optionList, &optionListIdx)) != -1)
|
||||
while ((optionValue = getopt_long((int)argListSize, (char **)argList, "-:", optionList, &optionListIdx)) != -1)
|
||||
{
|
||||
switch (option)
|
||||
switch (optionValue)
|
||||
{
|
||||
// Parse arguments that are not options, i.e. commands and parameters passed to commands
|
||||
case 1:
|
||||
@ -517,71 +544,72 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
default:
|
||||
{
|
||||
// Get option id and flags from the option code
|
||||
ConfigOption optionId = option & PARSE_OPTION_MASK;
|
||||
bool negate = option & PARSE_NEGATE_FLAG;
|
||||
bool reset = option & PARSE_RESET_FLAG;
|
||||
CfgParseOptionResult option = cfgParseOptionInfo(optionValue);
|
||||
|
||||
// Make sure the option id is valid
|
||||
ASSERT(optionId < CFG_OPTION_TOTAL);
|
||||
ASSERT(option.id < CFG_OPTION_TOTAL);
|
||||
|
||||
// Error if this option is secure and cannot be passed on the command line
|
||||
if (cfgDefOptionSecure(cfgOptionDefIdFromId(optionId)))
|
||||
if (cfgDefOptionSecure(cfgOptionDefIdFromId(option.id)))
|
||||
{
|
||||
THROW_FMT(
|
||||
OptionInvalidError,
|
||||
"option '%s' is not allowed on the command-line\n"
|
||||
"HINT: this option could expose secrets in the process list.\n"
|
||||
"HINT: specify the option in a configuration file or an environment variable instead.",
|
||||
cfgOptionName(optionId));
|
||||
cfgOptionName(option.id));
|
||||
}
|
||||
|
||||
// If the the option has not been found yet then set it
|
||||
if (!parseOptionList[optionId].found)
|
||||
if (!parseOptionList[option.id].found)
|
||||
{
|
||||
parseOptionList[optionId].found = true;
|
||||
parseOptionList[optionId].negate = negate;
|
||||
parseOptionList[optionId].reset = reset;
|
||||
parseOptionList[optionId].source = cfgSourceParam;
|
||||
parseOptionList[option.id].found = true;
|
||||
parseOptionList[option.id].negate = option.negate;
|
||||
parseOptionList[option.id].reset = option.reset;
|
||||
parseOptionList[option.id].source = cfgSourceParam;
|
||||
|
||||
// Only set the argument if the option requires one
|
||||
if (optionList[optionListIdx].has_arg == required_argument)
|
||||
{
|
||||
parseOptionList[optionId].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[optionId].valueList, STR(optarg));
|
||||
parseOptionList[option.id].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[option.id].valueList, STR(optarg));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure option is not negated more than once. It probably wouldn't hurt anything to accept this case
|
||||
// but there's no point in allowing the user to be sloppy.
|
||||
if (parseOptionList[optionId].negate && negate)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is negated multiple times", cfgOptionName(optionId));
|
||||
if (parseOptionList[option.id].negate && option.negate)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is negated multiple times", cfgOptionName(option.id));
|
||||
|
||||
// Make sure option is not reset more than once. Same justification as negate.
|
||||
if (parseOptionList[optionId].reset && reset)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is reset multiple times", cfgOptionName(optionId));
|
||||
if (parseOptionList[option.id].reset && option.reset)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' is reset multiple times", cfgOptionName(option.id));
|
||||
|
||||
// Don't allow an option to be both negated and reset
|
||||
if ((parseOptionList[optionId].reset && negate) || (parseOptionList[optionId].negate && reset))
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be negated and reset", cfgOptionName(optionId));
|
||||
if ((parseOptionList[option.id].reset && option.negate) ||
|
||||
(parseOptionList[option.id].negate && option.reset))
|
||||
{
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be negated and reset", cfgOptionName(option.id));
|
||||
}
|
||||
|
||||
// Don't allow an option to be both set and negated
|
||||
if (parseOptionList[optionId].negate != negate)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and negated", cfgOptionName(optionId));
|
||||
if (parseOptionList[option.id].negate != option.negate)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and negated", cfgOptionName(option.id));
|
||||
|
||||
// Don't allow an option to be both set and reset
|
||||
if (parseOptionList[optionId].reset != reset)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and reset", cfgOptionName(optionId));
|
||||
if (parseOptionList[option.id].reset != option.reset)
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set and reset", cfgOptionName(option.id));
|
||||
|
||||
// Add the argument
|
||||
if (optionList[optionListIdx].has_arg == required_argument &&
|
||||
cfgDefOptionMulti(cfgOptionDefIdFromId(optionId)))
|
||||
cfgDefOptionMulti(cfgOptionDefIdFromId(option.id)))
|
||||
{
|
||||
strLstAdd(parseOptionList[optionId].valueList, strNew(optarg));
|
||||
strLstAdd(parseOptionList[option.id].valueList, strNew(optarg));
|
||||
}
|
||||
// Error if the option does not accept multiple arguments
|
||||
else
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(optionId));
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(option.id));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -647,29 +675,28 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
const String *value = STR(equalPtr + 1);
|
||||
|
||||
// Find the option
|
||||
unsigned int optionIdx = optionFind(key);
|
||||
CfgParseOptionResult option = cfgParseOption(key);
|
||||
|
||||
// Warn if the option not found
|
||||
if (optionList[optionIdx].name == NULL)
|
||||
if (!option.found)
|
||||
{
|
||||
LOG_WARN_FMT("environment contains invalid option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
// Warn if negate option found in env
|
||||
else if (optionList[optionIdx].val & PARSE_NEGATE_FLAG)
|
||||
else if (option.negate)
|
||||
{
|
||||
LOG_WARN_FMT("environment contains invalid negate option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
// Warn if reset option found in env
|
||||
else if (optionList[optionIdx].val & PARSE_RESET_FLAG)
|
||||
else if (option.reset)
|
||||
{
|
||||
LOG_WARN_FMT("environment contains invalid reset option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigOption optionId = optionList[optionIdx].val & PARSE_OPTION_MASK;
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(option.id);
|
||||
|
||||
// Continue if the option is not valid for this command
|
||||
if (!cfgDefOptionValid(commandId, optionDefId))
|
||||
@ -679,30 +706,30 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
THROW_FMT(OptionInvalidValueError, "environment variable '%s' must have a value", strZ(key));
|
||||
|
||||
// Continue if the option has already been specified on the command line
|
||||
if (parseOptionList[optionId].found)
|
||||
if (parseOptionList[option.id].found)
|
||||
continue;
|
||||
|
||||
parseOptionList[optionId].found = true;
|
||||
parseOptionList[optionId].source = cfgSourceConfig;
|
||||
parseOptionList[option.id].found = true;
|
||||
parseOptionList[option.id].source = cfgSourceConfig;
|
||||
|
||||
// Convert boolean to string
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
{
|
||||
if (strEqZ(value, "n"))
|
||||
parseOptionList[optionId].negate = true;
|
||||
parseOptionList[option.id].negate = true;
|
||||
else if (!strEqZ(value, "y"))
|
||||
THROW_FMT(OptionInvalidValueError, "environment boolean option '%s' must be 'y' or 'n'", strZ(key));
|
||||
}
|
||||
// Else split list/hash into separate values
|
||||
else if (cfgDefOptionMulti(optionDefId))
|
||||
{
|
||||
parseOptionList[optionId].valueList = strLstNewSplitZ(value, ":");
|
||||
parseOptionList[option.id].valueList = strLstNewSplitZ(value, ":");
|
||||
}
|
||||
// Else add the string value
|
||||
else
|
||||
{
|
||||
parseOptionList[optionId].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[optionId].valueList, value);
|
||||
parseOptionList[option.id].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[option.id].valueList, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -750,31 +777,30 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
String *key = strLstGet(keyList, keyIdx);
|
||||
|
||||
// Find the optionName in the main list
|
||||
unsigned int optionIdx = optionFind(key);
|
||||
CfgParseOptionResult option = cfgParseOption(key);
|
||||
|
||||
// Warn if the option not found
|
||||
if (optionList[optionIdx].name == NULL)
|
||||
if (!option.found)
|
||||
{
|
||||
LOG_WARN_FMT("configuration file contains invalid option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
// Warn if negate option found in config
|
||||
else if (optionList[optionIdx].val & PARSE_NEGATE_FLAG)
|
||||
else if (option.negate)
|
||||
{
|
||||
LOG_WARN_FMT("configuration file contains negate option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
// Warn if reset option found in config
|
||||
else if (optionList[optionIdx].val & PARSE_RESET_FLAG)
|
||||
else if (option.reset)
|
||||
{
|
||||
LOG_WARN_FMT("configuration file contains reset option '%s'", strZ(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigOption optionId = optionList[optionIdx].val & PARSE_OPTION_MASK;
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(option.id);
|
||||
|
||||
/// Warn if this option should be command-line only
|
||||
// Warn if this option should be command-line only
|
||||
if (cfgDefOptionSection(optionDefId) == cfgDefSectionCommandLine)
|
||||
{
|
||||
LOG_WARN_FMT("configuration file contains command-line only option '%s'", strZ(key));
|
||||
@ -782,7 +808,7 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
}
|
||||
|
||||
// Make sure this option does not appear in the same section with an alternate name
|
||||
const Variant *optionFoundKey = VARINT(optionId);
|
||||
const Variant *optionFoundKey = VARINT(option.id);
|
||||
const Variant *optionFoundName = kvGet(optionFound, optionFoundKey);
|
||||
|
||||
if (optionFoundName != NULL)
|
||||
@ -820,20 +846,20 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
}
|
||||
|
||||
// Continue if this option has already been found in another section or command-line/environment
|
||||
if (parseOptionList[optionId].found)
|
||||
if (parseOptionList[option.id].found)
|
||||
continue;
|
||||
|
||||
parseOptionList[optionId].found = true;
|
||||
parseOptionList[optionId].source = cfgSourceConfig;
|
||||
parseOptionList[option.id].found = true;
|
||||
parseOptionList[option.id].source = cfgSourceConfig;
|
||||
|
||||
// Process list
|
||||
if (iniSectionKeyIsList(config, section, key))
|
||||
{
|
||||
// Error if the option cannot be specified multiple times
|
||||
if (!cfgDefOptionMulti(optionDefId))
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(optionId));
|
||||
THROW_FMT(OptionInvalidError, "option '%s' cannot be set multiple times", cfgOptionName(option.id));
|
||||
|
||||
parseOptionList[optionId].valueList = iniGetList(config, section, key);
|
||||
parseOptionList[option.id].valueList = iniGetList(config, section, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -850,15 +876,15 @@ configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel)
|
||||
if (cfgDefOptionType(optionDefId) == cfgDefOptTypeBoolean)
|
||||
{
|
||||
if (strEqZ(value, "n"))
|
||||
parseOptionList[optionId].negate = true;
|
||||
parseOptionList[option.id].negate = true;
|
||||
else if (!strEqZ(value, "y"))
|
||||
THROW_FMT(OptionInvalidValueError, "boolean option '%s' must be 'y' or 'n'", strZ(key));
|
||||
}
|
||||
// Else add the string value
|
||||
else
|
||||
{
|
||||
parseOptionList[optionId].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[optionId].valueList, value);
|
||||
parseOptionList[option.id].valueList = strLstNew();
|
||||
strLstAdd(parseOptionList[option.id].valueList, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,4 +12,16 @@ Functions
|
||||
// Parse the command-line arguments and config file to produce final config data
|
||||
void configParse(unsigned int argListSize, const char *argList[], bool resetLogLevel);
|
||||
|
||||
// Parse option name and return option info
|
||||
typedef struct CfgParseOptionResult
|
||||
{
|
||||
bool found; // Was the option found?
|
||||
ConfigOption id; // Option ID
|
||||
bool negate; // Was the option negated?
|
||||
bool reset; // Was the option reset?
|
||||
bool deprecated; // Is the option deprecated?
|
||||
} CfgParseOptionResult;
|
||||
|
||||
CfgParseOptionResult cfgParseOption(const String *optionName);
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@ Configuration Protocol Handler
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "config/config.h"
|
||||
#include "config/parse.h"
|
||||
#include "config/protocol.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -37,7 +38,12 @@ configProtocol(const String *command, const VariantList *paramList, ProtocolServ
|
||||
VariantList *optionList = varLstNew();
|
||||
|
||||
for (unsigned int optionIdx = 0; optionIdx < varLstSize(paramList); optionIdx++)
|
||||
varLstAdd(optionList, varDup(cfgOption(cfgOptionId(strZ(varStr(varLstGet(paramList, optionIdx)))))));
|
||||
{
|
||||
CfgParseOptionResult option = cfgParseOption(varStr(varLstGet(paramList, optionIdx)));
|
||||
CHECK(option.found);
|
||||
|
||||
varLstAdd(optionList, varDup(cfgOption(option.id)));
|
||||
}
|
||||
|
||||
protocolServerResponse(server, varNewVarLst(optionList));
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ testRun(void)
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
optionHelp = strZ(strNewFmt(
|
||||
"%s - 'archive-push' command - 'repo1-s3-host' option help\n"
|
||||
"%s - 'archive-push' command - 'repo-s3-host' option help\n"
|
||||
"\n"
|
||||
"S3 repository host.\n"
|
||||
"\n"
|
||||
@ -379,6 +379,15 @@ testRun(void)
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)), "help for backup command, repo-hardlink option");
|
||||
TEST_RESULT_STR_Z(helpRender(), optionHelp, " check text");
|
||||
|
||||
argList = strLstNew();
|
||||
strLstAddZ(argList, "/path/to/pgbackrest");
|
||||
strLstAddZ(argList, "help");
|
||||
strLstAddZ(argList, "backup");
|
||||
strLstAddZ(argList, "hardlink");
|
||||
TEST_RESULT_VOID(
|
||||
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)), "help for backup command, deprecated hardlink option");
|
||||
TEST_RESULT_STR_Z(helpRender(), optionHelp, " check text");
|
||||
|
||||
// Check admonition
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
optionHelp = strZ(strNewFmt(
|
||||
|
@ -24,9 +24,6 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_INT(cfgOptionDefIdFromId(cfgOptPgHost + 6), cfgDefOptPgHost, "option id to def id");
|
||||
|
||||
TEST_RESULT_INT(cfgOptionId("target"), cfgOptTarget, "option id from name");
|
||||
TEST_RESULT_INT(cfgOptionId(BOGUS_STR), -1, "option id from invalid option name");
|
||||
|
||||
TEST_ERROR(
|
||||
cfgOptionIdFromDefId(999999, 6), AssertError,
|
||||
"assertion 'optionId != CFG_OPTION_TOTAL' failed");
|
||||
|
@ -18,13 +18,15 @@ Test Configuration Parse
|
||||
Option find test -- this is done a lot in the deprecated tests
|
||||
***********************************************************************************************************************************/
|
||||
static void
|
||||
testOptionFind(const char *option, unsigned int value)
|
||||
testOptionFind(const char *optionName, unsigned int optionId, unsigned int optionKeyIdx, bool negate, bool reset, bool deprecated)
|
||||
{
|
||||
// If not testing for a missing option, then add the option offset that is already added to each option in the list
|
||||
if (value != 0)
|
||||
value |= PARSE_OPTION_FLAG;
|
||||
CfgParseOptionResult option = cfgParseOption(STR(optionName));
|
||||
|
||||
TEST_RESULT_INT(optionList[optionFind(strNew(option))].val, value, "check %s", option);
|
||||
TEST_RESULT_BOOL(option.found, true, "check %s found", optionName);
|
||||
TEST_RESULT_UINT(option.id, optionId + optionKeyIdx, "check %s id %u", optionName, optionId + optionKeyIdx);
|
||||
TEST_RESULT_BOOL(option.negate, negate, "check %s negate %d", optionName, negate);
|
||||
TEST_RESULT_BOOL(option.reset, reset, "check %s reset %d", optionName, reset);
|
||||
TEST_RESULT_BOOL(option.deprecated, deprecated, "check %s deprecated %d", optionName, deprecated);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -1433,61 +1435,59 @@ testRun(void)
|
||||
{
|
||||
// Repository options
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
testOptionFind("hardlink", PARSE_DEPRECATE_FLAG | cfgOptRepoHardlink);
|
||||
testOptionFind("no-hardlink", PARSE_DEPRECATE_FLAG | PARSE_NEGATE_FLAG | cfgOptRepoHardlink);
|
||||
testOptionFind("hardlink", cfgOptRepoHardlink, 0, false, false, true);
|
||||
testOptionFind("no-hardlink", cfgOptRepoHardlink, 0, true, false, true);
|
||||
|
||||
testOptionFind("archive-queue-max", PARSE_DEPRECATE_FLAG | cfgOptArchivePushQueueMax);
|
||||
testOptionFind("reset-archive-queue-max", PARSE_DEPRECATE_FLAG | PARSE_RESET_FLAG | cfgOptArchivePushQueueMax);
|
||||
testOptionFind("archive-queue-max", cfgOptArchivePushQueueMax, 0, false, false, true);
|
||||
testOptionFind("reset-archive-queue-max", cfgOptArchivePushQueueMax, 0, false, true, true);
|
||||
|
||||
testOptionFind("backup-cmd", PARSE_DEPRECATE_FLAG | cfgOptRepoHostCmd);
|
||||
testOptionFind("backup-config", PARSE_DEPRECATE_FLAG | cfgOptRepoHostConfig);
|
||||
testOptionFind("backup-host", PARSE_DEPRECATE_FLAG | cfgOptRepoHost);
|
||||
testOptionFind("backup-ssh-port", PARSE_DEPRECATE_FLAG | cfgOptRepoHostPort);
|
||||
testOptionFind("backup-user", PARSE_DEPRECATE_FLAG | cfgOptRepoHostUser);
|
||||
testOptionFind("backup-cmd", cfgOptRepoHostCmd, 0, false, false, true);
|
||||
testOptionFind("backup-config", cfgOptRepoHostConfig, 0, false, false, true);
|
||||
testOptionFind("backup-host", cfgOptRepoHost, 0, false, false, true);
|
||||
testOptionFind("backup-ssh-port", cfgOptRepoHostPort, 0, false, false, true);
|
||||
testOptionFind("backup-user", cfgOptRepoHostUser, 0, false, false, true);
|
||||
|
||||
testOptionFind("repo-cipher-pass", PARSE_DEPRECATE_FLAG | cfgOptRepoCipherPass);
|
||||
testOptionFind("repo-cipher-type", PARSE_DEPRECATE_FLAG | cfgOptRepoCipherType);
|
||||
testOptionFind("repo-path", PARSE_DEPRECATE_FLAG | cfgOptRepoPath);
|
||||
testOptionFind("repo-type", PARSE_DEPRECATE_FLAG | cfgOptRepoType);
|
||||
testOptionFind("repo-cipher-pass", cfgOptRepoCipherPass, 0, false, false, true);
|
||||
testOptionFind("repo-cipher-type", cfgOptRepoCipherType, 0, false, false, true);
|
||||
testOptionFind("repo-path", cfgOptRepoPath, 0, false, false, true);
|
||||
testOptionFind("repo-type", cfgOptRepoType, 0, false, false, true);
|
||||
|
||||
testOptionFind("repo-s3-bucket", PARSE_DEPRECATE_FLAG | cfgOptRepoS3Bucket);
|
||||
testOptionFind("repo-s3-ca-file", PARSE_DEPRECATE_FLAG | cfgOptRepoS3CaFile);
|
||||
testOptionFind("repo-s3-ca-path", PARSE_DEPRECATE_FLAG | cfgOptRepoS3CaPath);
|
||||
testOptionFind("repo-s3-endpoint", PARSE_DEPRECATE_FLAG | cfgOptRepoS3Endpoint);
|
||||
testOptionFind("repo-s3-host", PARSE_DEPRECATE_FLAG | cfgOptRepoS3Host);
|
||||
testOptionFind("repo-s3-key", PARSE_DEPRECATE_FLAG | cfgOptRepoS3Key);
|
||||
testOptionFind("repo-s3-key-secret", PARSE_DEPRECATE_FLAG | cfgOptRepoS3KeySecret);
|
||||
testOptionFind("repo-s3-region", PARSE_DEPRECATE_FLAG | cfgOptRepoS3Region);
|
||||
testOptionFind("repo-s3-verify-ssl", PARSE_DEPRECATE_FLAG | cfgOptRepoS3VerifyTls);
|
||||
testOptionFind("repo1-s3-verify-ssl", PARSE_DEPRECATE_FLAG | cfgOptRepoS3VerifyTls);
|
||||
testOptionFind("no-repo-s3-verify-ssl", PARSE_DEPRECATE_FLAG | PARSE_NEGATE_FLAG | cfgOptRepoS3VerifyTls);
|
||||
testOptionFind("repo-s3-bucket", cfgOptRepoS3Bucket, 0, false, false, true);
|
||||
testOptionFind("repo-s3-ca-file", cfgOptRepoS3CaFile, 0, false, false, true);
|
||||
testOptionFind("repo-s3-ca-path", cfgOptRepoS3CaPath, 0, false, false, true);
|
||||
testOptionFind("repo-s3-endpoint", cfgOptRepoS3Endpoint, 0, false, false, true);
|
||||
testOptionFind("repo-s3-host", cfgOptRepoS3Host, 0, false, false, true);
|
||||
testOptionFind("repo-s3-key", cfgOptRepoS3Key, 0, false, false, true);
|
||||
testOptionFind("repo-s3-key-secret", cfgOptRepoS3KeySecret, 0, false, false, true);
|
||||
testOptionFind("repo-s3-region", cfgOptRepoS3Region, 0, false, false, true);
|
||||
testOptionFind("repo-s3-verify-ssl", cfgOptRepoS3VerifyTls, 0, false, false, true);
|
||||
testOptionFind("repo1-s3-verify-ssl", cfgOptRepoS3VerifyTls, 0, false, false, true);
|
||||
testOptionFind("no-repo-s3-verify-ssl", cfgOptRepoS3VerifyTls, 0, true, false, true);
|
||||
|
||||
// PostreSQL options
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
testOptionFind("db-cmd", PARSE_DEPRECATE_FLAG | cfgOptPgHostCmd);
|
||||
testOptionFind("db-config", PARSE_DEPRECATE_FLAG | cfgOptPgHostConfig);
|
||||
testOptionFind("db-host", PARSE_DEPRECATE_FLAG | cfgOptPgHost);
|
||||
testOptionFind("db-path", PARSE_DEPRECATE_FLAG | cfgOptPgPath);
|
||||
testOptionFind("db-port", PARSE_DEPRECATE_FLAG | cfgOptPgPort);
|
||||
testOptionFind("db-socket-path", PARSE_DEPRECATE_FLAG | cfgOptPgSocketPath);
|
||||
testOptionFind("db-ssh-port", PARSE_DEPRECATE_FLAG | cfgOptPgHostPort);
|
||||
testOptionFind("db-user", PARSE_DEPRECATE_FLAG | cfgOptPgHostUser);
|
||||
testOptionFind("db-cmd", cfgOptPgHostCmd, 0, false, false, true);
|
||||
testOptionFind("db-config", cfgOptPgHostConfig, 0, false, false, true);
|
||||
testOptionFind("db-host", cfgOptPgHost, 0, false, false, true);
|
||||
testOptionFind("db-path", cfgOptPgPath, 0, false, false, true);
|
||||
testOptionFind("db-port", cfgOptPgPort, 0, false, false, true);
|
||||
testOptionFind("db-socket-path", cfgOptPgSocketPath, 0, false, false, true);
|
||||
testOptionFind("db-ssh-port", cfgOptPgHostPort, 0, false, false, true);
|
||||
testOptionFind("db-user", cfgOptPgHostUser, 0, false, false, true);
|
||||
|
||||
testOptionFind("no-db-user", 0);
|
||||
TEST_RESULT_BOOL(cfgParseOption(STR("no-db-user")).found, false, "no-db-user not found");
|
||||
|
||||
for (unsigned int optionIdx = 0; optionIdx < cfgDefOptionIndexTotal(cfgDefOptPgPath); optionIdx++)
|
||||
// Only check 1-8 since 8 was the max index when these option names were deprecated
|
||||
for (unsigned int optionIdx = 0; optionIdx < 8; optionIdx++)
|
||||
{
|
||||
testOptionFind(strZ(strNewFmt("db%u-cmd", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgHostCmd + optionIdx));
|
||||
testOptionFind(
|
||||
strZ(strNewFmt("db%u-config", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgHostConfig + optionIdx));
|
||||
testOptionFind(strZ(strNewFmt("db%u-host", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgHost + optionIdx));
|
||||
testOptionFind(strZ(strNewFmt("db%u-path", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgPath + optionIdx));
|
||||
testOptionFind(strZ(strNewFmt("db%u-port", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgPort + optionIdx));
|
||||
testOptionFind(
|
||||
strZ(strNewFmt("db%u-socket-path", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgSocketPath + optionIdx));
|
||||
testOptionFind(
|
||||
strZ(strNewFmt("db%u-ssh-port", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgHostPort + optionIdx));
|
||||
testOptionFind(strZ(strNewFmt("db%u-user", optionIdx + 1)), PARSE_DEPRECATE_FLAG | (cfgOptPgHostUser + optionIdx));
|
||||
testOptionFind(strZ(strNewFmt("db%u-cmd", optionIdx + 1)), cfgOptPgHostCmd, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-config", optionIdx + 1)), cfgOptPgHostConfig, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-host", optionIdx + 1)), cfgOptPgHost, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-path", optionIdx + 1)), cfgOptPgPath, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-port", optionIdx + 1)), cfgOptPgPort, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-socket-path", optionIdx + 1)), cfgOptPgSocketPath, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-ssh-port", optionIdx + 1)), cfgOptPgHostPort, optionIdx, false, false, true);
|
||||
testOptionFind(strZ(strNewFmt("db%u-user", optionIdx + 1)), cfgOptPgHostUser, optionIdx, false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user