You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-05 00:28:52 +02:00
Add beta feature infrastructure.
This allows options to be marked as beta, which will require that the --beta option be supplied to prevent accidental usage of a beta feature. The online and command-line documentation also show warnings when options are beta.
This commit is contained in:
@ -19,6 +19,7 @@ use pgBackRestDoc::ProjectInfo;
|
|||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
# Help types
|
# Help types
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
|
use constant CONFIG_HELP_BETA => 'beta';
|
||||||
use constant CONFIG_HELP_COMMAND => 'command';
|
use constant CONFIG_HELP_COMMAND => 'command';
|
||||||
push @EXPORT, qw(CONFIG_HELP_COMMAND);
|
push @EXPORT, qw(CONFIG_HELP_COMMAND);
|
||||||
use constant CONFIG_HELP_CURRENT => 'current';
|
use constant CONFIG_HELP_CURRENT => 'current';
|
||||||
@ -319,6 +320,7 @@ sub process
|
|||||||
$$oCommandOption{&CONFIG_HELP_EXAMPLE} = $oOptionDoc->fieldGet('example');
|
$$oCommandOption{&CONFIG_HELP_EXAMPLE} = $oOptionDoc->fieldGet('example');
|
||||||
$oCommandOption->{&CONFIG_HELP_INTERNAL} =
|
$oCommandOption->{&CONFIG_HELP_INTERNAL} =
|
||||||
cfgDefineCommand()->{$strCommand}{&CFGDEF_INTERNAL} ? true : $oOptionDefine->{$strOption}{&CFGDEF_INTERNAL};
|
cfgDefineCommand()->{$strCommand}{&CFGDEF_INTERNAL} ? true : $oOptionDefine->{$strOption}{&CFGDEF_INTERNAL};
|
||||||
|
$oCommandOption->{&CONFIG_HELP_BETA} = $oOptionDefine->{$strOption}{&CFGDEF_BETA};
|
||||||
|
|
||||||
# If internal is defined for the option/command it overrides everthing else
|
# If internal is defined for the option/command it overrides everthing else
|
||||||
if (defined($oOptionDefine->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_INTERNAL}))
|
if (defined($oOptionDefine->{$strOption}{&CFGDEF_COMMAND}{$strCommand}{&CFGDEF_INTERNAL}))
|
||||||
@ -370,6 +372,7 @@ sub process
|
|||||||
$$oOption{&CONFIG_HELP_DESCRIPTION} = $$oCommandOption{&CONFIG_HELP_DESCRIPTION};
|
$$oOption{&CONFIG_HELP_DESCRIPTION} = $$oCommandOption{&CONFIG_HELP_DESCRIPTION};
|
||||||
$$oOption{&CONFIG_HELP_EXAMPLE} = $oOptionDoc->fieldGet('example');
|
$$oOption{&CONFIG_HELP_EXAMPLE} = $oOptionDoc->fieldGet('example');
|
||||||
$oOption->{&CONFIG_HELP_INTERNAL} = $oOptionDefine->{$strOption}{&CFGDEF_INTERNAL};
|
$oOption->{&CONFIG_HELP_INTERNAL} = $oOptionDefine->{$strOption}{&CFGDEF_INTERNAL};
|
||||||
|
$oOption->{&CONFIG_HELP_BETA} = $oOptionDefine->{$strOption}{&CFGDEF_BETA};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -819,6 +822,12 @@ sub helpOptionGet
|
|||||||
$oOptionElement->
|
$oOptionElement->
|
||||||
nodeAdd('p')->textSet($$oOptionHash{&CONFIG_HELP_SUMMARY});
|
nodeAdd('p')->textSet($$oOptionHash{&CONFIG_HELP_SUMMARY});
|
||||||
|
|
||||||
|
# Add beta warning
|
||||||
|
if ($$oOptionHash{&CONFIG_HELP_BETA})
|
||||||
|
{
|
||||||
|
$oOptionElement->nodeAdd('p')->textSet({name => 'text', children => ['FOR BETA TESTING ONLY. DO NOT USE IN PRODUCTION.']});
|
||||||
|
}
|
||||||
|
|
||||||
$oOptionElement->
|
$oOptionElement->
|
||||||
nodeAdd('p')->textSet($$oOptionHash{&CONFIG_HELP_DESCRIPTION});
|
nodeAdd('p')->textSet($$oOptionHash{&CONFIG_HELP_DESCRIPTION});
|
||||||
|
|
||||||
@ -862,32 +871,38 @@ sub helpOptionGet
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Get the example
|
# Get the example
|
||||||
my $strExample;
|
my $strExample = '';
|
||||||
|
|
||||||
my $strOptionPrefix = $rhConfigDefine->{$strOption}{&CFGDEF_GROUP};
|
my $strOptionPrefix = $rhConfigDefine->{$strOption}{&CFGDEF_GROUP};
|
||||||
my $strOptionIndex = defined($strOptionPrefix) ?
|
my $strOptionIndex = defined($strOptionPrefix) ?
|
||||||
"${strOptionPrefix}1-" . substr($strOption, length($strOptionPrefix) + 1) : $strOption;
|
"${strOptionPrefix}1-" . substr($strOption, length($strOptionPrefix) + 1) : $strOption;
|
||||||
|
|
||||||
if (defined($strCommand))
|
if (defined($strCommand) && docConfigOptionTypeTest($strOption, CFGDEF_TYPE_BOOLEAN))
|
||||||
{
|
{
|
||||||
if (docConfigOptionTypeTest($strOption, CFGDEF_TYPE_BOOLEAN))
|
if ($$oOptionHash{&CONFIG_HELP_EXAMPLE} ne 'n' && $$oOptionHash{&CONFIG_HELP_EXAMPLE} ne 'y')
|
||||||
{
|
{
|
||||||
if ($$oOptionHash{&CONFIG_HELP_EXAMPLE} ne 'n' && $$oOptionHash{&CONFIG_HELP_EXAMPLE} ne 'y')
|
confess &log(ERROR, "option ${strOption} example should be boolean but value is: " .
|
||||||
{
|
$$oOptionHash{&CONFIG_HELP_EXAMPLE});
|
||||||
confess &log(ERROR, "option ${strOption} example should be boolean but value is: " .
|
}
|
||||||
$$oOptionHash{&CONFIG_HELP_EXAMPLE});
|
|
||||||
}
|
|
||||||
|
|
||||||
$strExample = '--' . ($$oOptionHash{&CONFIG_HELP_EXAMPLE} eq 'n' ? 'no-' : '') . $strOptionIndex;
|
$strExample = '--' . ($$oOptionHash{&CONFIG_HELP_EXAMPLE} eq 'n' ? 'no-' : '') . $strOptionIndex;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$strExample = "--${strOptionIndex}=" . $$oOptionHash{&CONFIG_HELP_EXAMPLE};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$strExample = "${strOptionIndex}=" . $$oOptionHash{&CONFIG_HELP_EXAMPLE};
|
foreach my $strLine (split('\\|', $$oOptionHash{&CONFIG_HELP_EXAMPLE}))
|
||||||
|
{
|
||||||
|
if ($strExample ne '')
|
||||||
|
{
|
||||||
|
$strExample .= ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined($strCommand))
|
||||||
|
{
|
||||||
|
$strExample .= '--';
|
||||||
|
}
|
||||||
|
|
||||||
|
$strExample .= "${strOptionIndex}=${strLine}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$strCodeBlock .= (defined($strCodeBlock) ? "\n" : '') . "example: ${strExample}";
|
$strCodeBlock .= (defined($strCodeBlock) ? "\n" : '') . "example: ${strExample}";
|
||||||
|
@ -147,6 +147,8 @@ use constant CFGDEF_DEFAULT_LITERAL => 'default-
|
|||||||
use constant CFGDEF_GROUP => 'group';
|
use constant CFGDEF_GROUP => 'group';
|
||||||
push @EXPORT, qw(CFGDEF_GROUP);
|
push @EXPORT, qw(CFGDEF_GROUP);
|
||||||
|
|
||||||
|
use constant CFGDEF_BETA => 'beta';
|
||||||
|
push @EXPORT, qw(CFGDEF_BETA);
|
||||||
use constant CFGDEF_INDEX => 'index';
|
use constant CFGDEF_INDEX => 'index';
|
||||||
push @EXPORT, qw(CFGDEF_INDEX);
|
push @EXPORT, qw(CFGDEF_INDEX);
|
||||||
use constant CFGDEF_INHERIT => 'inherit';
|
use constant CFGDEF_INHERIT => 'inherit';
|
||||||
|
@ -610,6 +610,13 @@ option:
|
|||||||
command-role:
|
command-role:
|
||||||
main: {}
|
main: {}
|
||||||
|
|
||||||
|
beta:
|
||||||
|
section: global
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
internal: true
|
||||||
|
beta: true
|
||||||
|
|
||||||
buffer-size:
|
buffer-size:
|
||||||
section: global
|
section: global
|
||||||
type: size
|
type: size
|
||||||
|
@ -42,6 +42,7 @@ STRING_EXTERN(OPT_TYPE_TIME_STR, OPT_TYPE_TIM
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Option constants
|
Option constants
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
STRING_EXTERN(OPT_BETA_STR, OPT_BETA);
|
||||||
STRING_EXTERN(OPT_STANZA_STR, OPT_STANZA);
|
STRING_EXTERN(OPT_STANZA_STR, OPT_STANZA);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
@ -297,6 +298,7 @@ typedef struct BldCfgOptionRaw
|
|||||||
const String *type;
|
const String *type;
|
||||||
const String *section;
|
const String *section;
|
||||||
bool internal;
|
bool internal;
|
||||||
|
bool beta;
|
||||||
const Variant *required;
|
const Variant *required;
|
||||||
const Variant *negate;
|
const Variant *negate;
|
||||||
bool reset;
|
bool reset;
|
||||||
@ -815,6 +817,10 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
|
|||||||
{
|
{
|
||||||
optRaw.internal = yamlBoolParse(optDefVal);
|
optRaw.internal = yamlBoolParse(optDefVal);
|
||||||
}
|
}
|
||||||
|
else if (strEqZ(optDef.value, "beta"))
|
||||||
|
{
|
||||||
|
optRaw.beta = yamlBoolParse(optDefVal);
|
||||||
|
}
|
||||||
else if (strEqZ(optDef.value, "negate"))
|
else if (strEqZ(optDef.value, "negate"))
|
||||||
{
|
{
|
||||||
optRaw.negate = varNewBool(yamlBoolParse(optDefVal));
|
optRaw.negate = varNewBool(yamlBoolParse(optDefVal));
|
||||||
@ -904,6 +910,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
|
|||||||
.type = strDup(optRaw->type),
|
.type = strDup(optRaw->type),
|
||||||
.section = strDup(optRaw->section),
|
.section = strDup(optRaw->section),
|
||||||
.internal = optRaw->internal,
|
.internal = optRaw->internal,
|
||||||
|
.beta = optRaw->beta,
|
||||||
.required = varBool(optRaw->required),
|
.required = varBool(optRaw->required),
|
||||||
.negate = varBool(optRaw->negate),
|
.negate = varBool(optRaw->negate),
|
||||||
.reset = optRaw->reset,
|
.reset = optRaw->reset,
|
||||||
|
@ -51,6 +51,8 @@ STRING_DECLARE(OPT_TYPE_TIME_STR);
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Option constants
|
Option constants
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
#define OPT_BETA "beta"
|
||||||
|
STRING_DECLARE(OPT_BETA_STR);
|
||||||
#define OPT_STANZA "stanza"
|
#define OPT_STANZA "stanza"
|
||||||
STRING_DECLARE(OPT_STANZA_STR);
|
STRING_DECLARE(OPT_STANZA_STR);
|
||||||
|
|
||||||
@ -118,6 +120,7 @@ struct BldCfgOption
|
|||||||
const String *type; // Option type, e.g. integer
|
const String *type; // Option type, e.g. integer
|
||||||
const String *section; // Option section, i.e. stanza or global
|
const String *section; // Option section, i.e. stanza or global
|
||||||
bool internal; // Is the option internal?
|
bool internal; // Is the option internal?
|
||||||
|
bool beta; // Is the option beta?
|
||||||
bool required; // Is the option required?
|
bool required; // Is the option required?
|
||||||
bool negate; // Can the option be negated?
|
bool negate; // Can the option be negated?
|
||||||
bool reset; // Can the option be reset?
|
bool reset; // Can the option be reset?
|
||||||
|
@ -711,6 +711,9 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
|
|||||||
" PARSE_RULE_OPTION_TYPE(%s),\n",
|
" PARSE_RULE_OPTION_TYPE(%s),\n",
|
||||||
strZ(opt->name), strZ(bldEnum("cfgOptType", opt->type)));
|
strZ(opt->name), strZ(bldEnum("cfgOptType", opt->type)));
|
||||||
|
|
||||||
|
if (opt->beta)
|
||||||
|
strCatZ(configOpt, " PARSE_RULE_OPTION_BETA(true),\n");
|
||||||
|
|
||||||
if (opt->negate)
|
if (opt->negate)
|
||||||
strCatZ(configOpt, " PARSE_RULE_OPTION_NEGATE(true),\n");
|
strCatZ(configOpt, " PARSE_RULE_OPTION_NEGATE(true),\n");
|
||||||
|
|
||||||
|
@ -151,6 +151,16 @@
|
|||||||
</text>
|
</text>
|
||||||
|
|
||||||
<config-key-list>
|
<config-key-list>
|
||||||
|
<config-key id="beta" name="Allow Beta Features">
|
||||||
|
<summary>Allow beta features.</summary>
|
||||||
|
|
||||||
|
<text>
|
||||||
|
<p>Allow beta features to be enabled but do not actually enable them. Beta features need to be separately enabled using related options.</p>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<example>2MiB</example>
|
||||||
|
</config-key>
|
||||||
|
|
||||||
<config-key id="buffer-size" name="Buffer Size">
|
<config-key id="buffer-size" name="Buffer Size">
|
||||||
<summary>Buffer size for I/O operations.</summary>
|
<summary>Buffer size for I/O operations.</summary>
|
||||||
|
|
||||||
|
@ -97,11 +97,14 @@ helpRenderSplitSize(const String *string, const char *delimiter, size_t size)
|
|||||||
Helper function for helpRender() to make output look good on a console
|
Helper function for helpRender() to make output look good on a console
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
static String *
|
static String *
|
||||||
helpRenderText(const String *const text, const bool internal, const size_t indent, const bool indentFirst, const size_t length)
|
helpRenderText(
|
||||||
|
const String *const text, const bool internal, const bool beta, const size_t indent, const bool indentFirst,
|
||||||
|
const size_t length)
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
FUNCTION_LOG_PARAM(STRING, text);
|
FUNCTION_LOG_PARAM(STRING, text);
|
||||||
FUNCTION_LOG_PARAM(BOOL, internal);
|
FUNCTION_LOG_PARAM(BOOL, internal);
|
||||||
|
FUNCTION_LOG_PARAM(BOOL, beta);
|
||||||
FUNCTION_LOG_PARAM(SIZE, indent);
|
FUNCTION_LOG_PARAM(SIZE, indent);
|
||||||
FUNCTION_LOG_PARAM(BOOL, indentFirst);
|
FUNCTION_LOG_PARAM(BOOL, indentFirst);
|
||||||
FUNCTION_LOG_PARAM(SIZE, length);
|
FUNCTION_LOG_PARAM(SIZE, length);
|
||||||
@ -116,7 +119,12 @@ helpRenderText(const String *const text, const bool internal, const size_t inden
|
|||||||
{
|
{
|
||||||
// Split the text into paragraphs
|
// Split the text into paragraphs
|
||||||
const StringList *const lineList = strLstNewSplitZ(
|
const StringList *const lineList = strLstNewSplitZ(
|
||||||
strNewFmt("%s%s", strZ(text), internal ? "\n\nFOR INTERNAL USE ONLY. DO NOT USE IN PRODUCTION." : ""), "\n");
|
strNewFmt(
|
||||||
|
"%s%s", strZ(text),
|
||||||
|
beta ?
|
||||||
|
"\n\nFOR BETA TESTING ONLY. DO NOT USE IN PRODUCTION." :
|
||||||
|
(internal ? "\n\nFOR INTERNAL USE ONLY. DO NOT USE IN PRODUCTION." : "")),
|
||||||
|
"\n");
|
||||||
|
|
||||||
// Iterate through each paragraph and split the lines according to the line length
|
// Iterate through each paragraph and split the lines according to the line length
|
||||||
for (unsigned int lineIdx = 0; lineIdx < strLstSize(lineList); lineIdx++)
|
for (unsigned int lineIdx = 0; lineIdx < strLstSize(lineList); lineIdx++)
|
||||||
@ -313,7 +321,7 @@ helpRender(const Buffer *const helpData)
|
|||||||
strCatFmt(
|
strCatFmt(
|
||||||
result, " %s%*s%s\n", cfgParseCommandName(commandId),
|
result, " %s%*s%s\n", cfgParseCommandName(commandId),
|
||||||
(int)(commandSizeMax - strlen(cfgParseCommandName(commandId)) + 2), "",
|
(int)(commandSizeMax - strlen(cfgParseCommandName(commandId)) + 2), "",
|
||||||
strZ(helpRenderText(commandData[commandId].summary, false, commandSizeMax + 6, false, CONSOLE_WIDTH)));
|
strZ(helpRenderText(commandData[commandId].summary, false, false, commandSizeMax + 6, false, CONSOLE_WIDTH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct message for more help
|
// Construct message for more help
|
||||||
@ -405,10 +413,10 @@ helpRender(const Buffer *const helpData)
|
|||||||
"%s\n"
|
"%s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"%s\n",
|
"%s\n",
|
||||||
strZ(helpRenderText(commandData[commandId].summary, false, 0, true, CONSOLE_WIDTH)),
|
strZ(helpRenderText(commandData[commandId].summary, false, false, 0, true, CONSOLE_WIDTH)),
|
||||||
strZ(
|
strZ(
|
||||||
helpRenderText(
|
helpRenderText(
|
||||||
commandData[commandId].description, commandData[commandId].internal, 0, true, CONSOLE_WIDTH)));
|
commandData[commandId].description, commandData[commandId].internal, false, 0, true, CONSOLE_WIDTH)));
|
||||||
|
|
||||||
// Construct key/value of sections and options
|
// Construct key/value of sections and options
|
||||||
KeyValue *optionKv = kvNew();
|
KeyValue *optionKv = kvNew();
|
||||||
@ -484,7 +492,7 @@ helpRender(const Buffer *const helpData)
|
|||||||
strCatFmt(
|
strCatFmt(
|
||||||
result, " --%s%*s%s\n",
|
result, " --%s%*s%s\n",
|
||||||
cfgParseOptionName(optionId), (int)(optionSizeMax - strlen(cfgParseOptionName(optionId)) + 2), "",
|
cfgParseOptionName(optionId), (int)(optionSizeMax - strlen(cfgParseOptionName(optionId)) + 2), "",
|
||||||
strZ(helpRenderText(summary, false, optionSizeMax + 6, false, CONSOLE_WIDTH)));
|
strZ(helpRenderText(summary, false, false, optionSizeMax + 6, false, CONSOLE_WIDTH)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +515,7 @@ helpRender(const Buffer *const helpData)
|
|||||||
if (!option.found || !cfgParseOptionValid(cfgCommand(), cfgCmdRoleMain, option.id))
|
if (!option.found || !cfgParseOptionValid(cfgCommand(), cfgCmdRoleMain, option.id))
|
||||||
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", strZ(optionName), commandName);
|
THROW_FMT(OptionInvalidError, "option '%s' is not valid for command '%s'", strZ(optionName), commandName);
|
||||||
|
|
||||||
// Output option summary and description. Add a warning for internal options.
|
// Output option summary and description. Add a warning for internal and beta options.
|
||||||
CHECK(
|
CHECK(
|
||||||
AssertError, optionData[option.id].summary != NULL && optionData[option.id].description != NULL,
|
AssertError, optionData[option.id].summary != NULL && optionData[option.id].description != NULL,
|
||||||
"option help missing");
|
"option help missing");
|
||||||
@ -520,9 +528,11 @@ helpRender(const Buffer *const helpData)
|
|||||||
"\n"
|
"\n"
|
||||||
"%s\n",
|
"%s\n",
|
||||||
cfgParseOptionName(option.id),
|
cfgParseOptionName(option.id),
|
||||||
strZ(helpRenderText(optionData[option.id].summary, false, 0, true, CONSOLE_WIDTH)),
|
strZ(helpRenderText(optionData[option.id].summary, false, false, 0, true, CONSOLE_WIDTH)),
|
||||||
strZ(
|
strZ(
|
||||||
helpRenderText(optionData[option.id].description, optionData[option.id].internal, 0, true, CONSOLE_WIDTH)));
|
helpRenderText(
|
||||||
|
optionData[option.id].description, optionData[option.id].internal, option.beta, 0, true,
|
||||||
|
CONSOLE_WIDTH)));
|
||||||
|
|
||||||
// Output current and default values if they exist
|
// Output current and default values if they exist
|
||||||
const String *defaultValue = cfgOptionDefault(option.id);
|
const String *defaultValue = cfgOptionDefault(option.id);
|
||||||
|
@ -55,6 +55,7 @@ Option constants
|
|||||||
#define CFGOPT_ARCHIVE_PUSH_QUEUE_MAX "archive-push-queue-max"
|
#define CFGOPT_ARCHIVE_PUSH_QUEUE_MAX "archive-push-queue-max"
|
||||||
#define CFGOPT_ARCHIVE_TIMEOUT "archive-timeout"
|
#define CFGOPT_ARCHIVE_TIMEOUT "archive-timeout"
|
||||||
#define CFGOPT_BACKUP_STANDBY "backup-standby"
|
#define CFGOPT_BACKUP_STANDBY "backup-standby"
|
||||||
|
#define CFGOPT_BETA "beta"
|
||||||
#define CFGOPT_BUFFER_SIZE "buffer-size"
|
#define CFGOPT_BUFFER_SIZE "buffer-size"
|
||||||
#define CFGOPT_CHECKSUM_PAGE "checksum-page"
|
#define CFGOPT_CHECKSUM_PAGE "checksum-page"
|
||||||
#define CFGOPT_CIPHER_PASS "cipher-pass"
|
#define CFGOPT_CIPHER_PASS "cipher-pass"
|
||||||
@ -131,7 +132,7 @@ Option constants
|
|||||||
#define CFGOPT_TYPE "type"
|
#define CFGOPT_TYPE "type"
|
||||||
#define CFGOPT_VERBOSE "verbose"
|
#define CFGOPT_VERBOSE "verbose"
|
||||||
|
|
||||||
#define CFG_OPTION_TOTAL 164
|
#define CFG_OPTION_TOTAL 165
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Option value constants
|
Option value constants
|
||||||
@ -372,6 +373,7 @@ typedef enum
|
|||||||
cfgOptArchivePushQueueMax,
|
cfgOptArchivePushQueueMax,
|
||||||
cfgOptArchiveTimeout,
|
cfgOptArchiveTimeout,
|
||||||
cfgOptBackupStandby,
|
cfgOptBackupStandby,
|
||||||
|
cfgOptBeta,
|
||||||
cfgOptBufferSize,
|
cfgOptBufferSize,
|
||||||
cfgOptChecksumPage,
|
cfgOptChecksumPage,
|
||||||
cfgOptCipherPass,
|
cfgOptCipherPass,
|
||||||
|
@ -1112,6 +1112,88 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
|
|||||||
), // opt/backup-standby
|
), // opt/backup-standby
|
||||||
), // opt/backup-standby
|
), // opt/backup-standby
|
||||||
// -----------------------------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------------------------
|
||||||
|
PARSE_RULE_OPTION // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTION_NAME("beta"), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_TYPE(cfgOptTypeBoolean), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_BETA(true), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_NEGATE(true), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_RESET(true), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_REQUIRED(true), // opt/beta
|
||||||
|
PARSE_RULE_OPTION_SECTION(cfgSectionGlobal), // opt/beta
|
||||||
|
// opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdAnnotate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchiveGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchivePush) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdBackup) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdCheck) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdExpire) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdInfo) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoCreate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoLs) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoPut) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoRm) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRestore) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdServer) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdServerPing) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaCreate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaDelete) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaUpgrade) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStart) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStop) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdVerify) // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
// opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND_ROLE_ASYNC_VALID_LIST // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchiveGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchivePush) // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
// opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND_ROLE_LOCAL_VALID_LIST // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchiveGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchivePush) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdBackup) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRestore) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdVerify) // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
// opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND_ROLE_REMOTE_VALID_LIST // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdAnnotate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchiveGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdArchivePush) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdBackup) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdCheck) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdInfo) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoCreate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoGet) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoLs) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoPut) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRepoRm) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdRestore) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaCreate) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaDelete) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdStanzaUpgrade) // opt/beta
|
||||||
|
PARSE_RULE_OPTION_COMMAND(cfgCmdVerify) // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
// opt/beta
|
||||||
|
PARSE_RULE_OPTIONAL // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTIONAL_GROUP // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_OPTIONAL_DEFAULT // opt/beta
|
||||||
|
( // opt/beta
|
||||||
|
PARSE_RULE_VAL_BOOL_FALSE, // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
), // opt/beta
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------------------
|
||||||
PARSE_RULE_OPTION // opt/buffer-size
|
PARSE_RULE_OPTION // opt/buffer-size
|
||||||
( // opt/buffer-size
|
( // opt/buffer-size
|
||||||
PARSE_RULE_OPTION_NAME("buffer-size"), // opt/buffer-size
|
PARSE_RULE_OPTION_NAME("buffer-size"), // opt/buffer-size
|
||||||
@ -9575,6 +9657,7 @@ static const uint8_t optionResolveOrder[] =
|
|||||||
cfgOptArchivePushQueueMax, // opt-resolve-order
|
cfgOptArchivePushQueueMax, // opt-resolve-order
|
||||||
cfgOptArchiveTimeout, // opt-resolve-order
|
cfgOptArchiveTimeout, // opt-resolve-order
|
||||||
cfgOptBackupStandby, // opt-resolve-order
|
cfgOptBackupStandby, // opt-resolve-order
|
||||||
|
cfgOptBeta, // opt-resolve-order
|
||||||
cfgOptBufferSize, // opt-resolve-order
|
cfgOptBufferSize, // opt-resolve-order
|
||||||
cfgOptChecksumPage, // opt-resolve-order
|
cfgOptChecksumPage, // opt-resolve-order
|
||||||
cfgOptCipherPass, // opt-resolve-order
|
cfgOptCipherPass, // opt-resolve-order
|
||||||
|
@ -125,6 +125,7 @@ typedef struct ParseRuleOption
|
|||||||
{
|
{
|
||||||
const char *name; // Name
|
const char *name; // Name
|
||||||
unsigned int type : 4; // e.g. string, int, boolean
|
unsigned int type : 4; // e.g. string, int, boolean
|
||||||
|
bool beta : 1; // Is the option a beta feature?
|
||||||
bool negate : 1; // Can the option be negated on the command line?
|
bool negate : 1; // Can the option be negated on the command line?
|
||||||
bool reset : 1; // Can the option be reset on the command line?
|
bool reset : 1; // Can the option be reset on the command line?
|
||||||
bool required : 1; // Is the option required?
|
bool required : 1; // Is the option required?
|
||||||
@ -168,6 +169,9 @@ typedef enum
|
|||||||
#define PARSE_RULE_OPTION_TYPE(typeParam) \
|
#define PARSE_RULE_OPTION_TYPE(typeParam) \
|
||||||
.type = typeParam
|
.type = typeParam
|
||||||
|
|
||||||
|
#define PARSE_RULE_OPTION_BETA(betaParam) \
|
||||||
|
.beta = betaParam
|
||||||
|
|
||||||
#define PARSE_RULE_OPTION_NEGATE(negateParam) \
|
#define PARSE_RULE_OPTION_NEGATE(negateParam) \
|
||||||
.negate = negateParam
|
.negate = negateParam
|
||||||
|
|
||||||
@ -343,6 +347,32 @@ parseOptionIdxValue(ParseOption *optionList, unsigned int optionId, unsigned int
|
|||||||
FUNCTION_TEST_RETURN_TYPE_P(ParseOptionValue, &optionList[optionId].indexList[optionKeyIdx]);
|
FUNCTION_TEST_RETURN_TYPE_P(ParseOptionValue, &optionList[optionId].indexList[optionKeyIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Check that --beta is set if a beta option is used
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
static void
|
||||||
|
parseOptionBeta(
|
||||||
|
const unsigned int optionId, const unsigned int optionKeyIdx, const bool beta, const ParseOption *const parseOptionBeta)
|
||||||
|
{
|
||||||
|
FUNCTION_TEST_BEGIN();
|
||||||
|
FUNCTION_TEST_PARAM(UINT, optionId);
|
||||||
|
FUNCTION_TEST_PARAM(UINT, optionKeyIdx);
|
||||||
|
FUNCTION_TEST_PARAM(BOOL, beta);
|
||||||
|
FUNCTION_TEST_PARAM_P(PARSE_OPTION, parseOptionBeta);
|
||||||
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
|
if (beta && optionId != cfgOptBeta && (parseOptionBeta->indexListTotal == 0 || parseOptionBeta->indexList[0].negate))
|
||||||
|
{
|
||||||
|
THROW_FMT(
|
||||||
|
OptionInvalidError,
|
||||||
|
"option '%s' is not valid without option '" CFGOPT_BETA "'\n"
|
||||||
|
"HINT: beta features require the --" CFGOPT_BETA " option to prevent accidental usage.",
|
||||||
|
cfgParseOptionKeyIdxName(optionId, optionKeyIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Get command id by name
|
Get command id by name
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
@ -681,6 +711,9 @@ cfgParseOption(const String *const optionCandidate, const CfgParseOptionParam pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the beta flag
|
||||||
|
result.beta = optionFound->beta;
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_TYPE(CfgParseOptionResult, result);
|
FUNCTION_TEST_RETURN_TYPE(CfgParseOptionResult, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2158,6 +2191,9 @@ configParse(const Storage *storage, unsigned int argListSize, const char *argLis
|
|||||||
configOptionValue->set = true;
|
configOptionValue->set = true;
|
||||||
configOptionValue->source = parseOptionValue->source;
|
configOptionValue->source = parseOptionValue->source;
|
||||||
|
|
||||||
|
// Check beta status
|
||||||
|
parseOptionBeta(optionId, optionKeyIdx, parseRuleOption[optionId].beta, &parseOptionList[cfgOptBeta]);
|
||||||
|
|
||||||
if (optionType == cfgOptTypeBoolean)
|
if (optionType == cfgOptTypeBoolean)
|
||||||
{
|
{
|
||||||
configOptionValue->value.boolean = !parseOptionValue->negate;
|
configOptionValue->value.boolean = !parseOptionValue->negate;
|
||||||
|
@ -67,6 +67,7 @@ typedef struct CfgParseOptionResult
|
|||||||
bool negate; // Was the option negated?
|
bool negate; // Was the option negated?
|
||||||
bool reset; // Was the option reset?
|
bool reset; // Was the option reset?
|
||||||
bool deprecated; // Is the option deprecated?
|
bool deprecated; // Is the option deprecated?
|
||||||
|
bool beta; // Is the option in beta?
|
||||||
} CfgParseOptionResult;
|
} CfgParseOptionResult;
|
||||||
|
|
||||||
#define cfgParseOptionP(optionName, ...) \
|
#define cfgParseOptionP(optionName, ...) \
|
||||||
|
@ -1090,6 +1090,7 @@ sub configCreate
|
|||||||
|
|
||||||
# General options
|
# General options
|
||||||
# ------------------------------------------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'beta'} = 'y';
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'job-retry'} = 0;
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'job-retry'} = 0;
|
||||||
|
|
||||||
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'log-level-console'} = lc(DETAIL);
|
$oParamHash{&CFGDEF_SECTION_GLOBAL}{'log-level-console'} = lc(DETAIL);
|
||||||
|
@ -152,6 +152,7 @@ option:
|
|||||||
|
|
||||||
# Options that are not used but must be present for modules to compile. All must have a default or not be required.
|
# Options that are not used but must be present for modules to compile. All must have a default or not be required.
|
||||||
#---------------------------------------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
beta: {type: boolean, default: false, command: {noop: {}}}
|
||||||
compress-level-network: {type: string, required: false, command: {noop: {}}}
|
compress-level-network: {type: string, required: false, command: {noop: {}}}
|
||||||
config: {
|
config: {
|
||||||
type: string, internal: true, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, default-literal: true, negate: true}
|
type: string, internal: true, default: CFGOPTDEF_CONFIG_PATH "/" PROJECT_CONFIG_FILE, default-literal: true, negate: true}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<operation>
|
<operation>
|
||||||
<operation-general>
|
<operation-general>
|
||||||
<option-list>
|
<option-list>
|
||||||
|
<option id="beta"><summary></summary><text><p></p></text></option>
|
||||||
<option id="config"><summary></summary><text><p></p></text></option>
|
<option id="config"><summary></summary><text><p></p></text></option>
|
||||||
<option id="config-path"><summary></summary><text><p></p></text></option>
|
<option id="config-path"><summary></summary><text><p></p></text></option>
|
||||||
<option id="config-include-path"><summary></summary><text><p></p></text></option>
|
<option id="config-include-path"><summary></summary><text><p></p></text></option>
|
||||||
|
@ -42,6 +42,10 @@ hrnCfgLoad(ConfigCommand commandId, const StringList *argListParam, const HrnCfg
|
|||||||
// Add standard options needed in most cases
|
// Add standard options needed in most cases
|
||||||
if (!param.noStd)
|
if (!param.noStd)
|
||||||
{
|
{
|
||||||
|
// Enable beta features
|
||||||
|
if (cfgParseOptionValid(commandId, param.role, cfgOptBeta))
|
||||||
|
strLstInsert(argList, 0, STRDEF("--" CFGOPT_BETA));
|
||||||
|
|
||||||
// Set job retry to 0 if it is valid
|
// Set job retry to 0 if it is valid
|
||||||
if (cfgParseOptionValid(commandId, param.role, cfgOptJobRetry))
|
if (cfgParseOptionValid(commandId, param.role, cfgOptJobRetry))
|
||||||
strLstInsert(argList, 0, strNewFmt("--" CFGOPT_JOB_RETRY "=%u", param.jobRetry));
|
strLstInsert(argList, 0, strNewFmt("--" CFGOPT_JOB_RETRY "=%u", param.jobRetry));
|
||||||
|
@ -401,6 +401,7 @@ testRun(void)
|
|||||||
" backup-standby:\n"
|
" backup-standby:\n"
|
||||||
" section: global\n"
|
" section: global\n"
|
||||||
" type: boolean\n"
|
" type: boolean\n"
|
||||||
|
" beta: true\n"
|
||||||
" default: false\n"
|
" default: false\n"
|
||||||
" depend:\n"
|
" depend:\n"
|
||||||
" option: online\n"
|
" option: online\n"
|
||||||
@ -759,6 +760,7 @@ testRun(void)
|
|||||||
" (\n"
|
" (\n"
|
||||||
" PARSE_RULE_OPTION_NAME(\"backup-standby\"),\n"
|
" PARSE_RULE_OPTION_NAME(\"backup-standby\"),\n"
|
||||||
" PARSE_RULE_OPTION_TYPE(cfgOptTypeBoolean),\n"
|
" PARSE_RULE_OPTION_TYPE(cfgOptTypeBoolean),\n"
|
||||||
|
" PARSE_RULE_OPTION_BETA(true),\n"
|
||||||
" PARSE_RULE_OPTION_NEGATE(true),\n"
|
" PARSE_RULE_OPTION_NEGATE(true),\n"
|
||||||
" PARSE_RULE_OPTION_RESET(true),\n"
|
" PARSE_RULE_OPTION_RESET(true),\n"
|
||||||
" PARSE_RULE_OPTION_REQUIRED(true),\n"
|
" PARSE_RULE_OPTION_REQUIRED(true),\n"
|
||||||
|
@ -98,17 +98,24 @@ testRun(void)
|
|||||||
if (testBegin("helpRenderText()"))
|
if (testBegin("helpRenderText()"))
|
||||||
{
|
{
|
||||||
TEST_RESULT_STR_Z(
|
TEST_RESULT_STR_Z(
|
||||||
helpRenderText(STRDEF("this is a short sentence"), false, 0, false, 80), "this is a short sentence", "one line");
|
helpRenderText(STRDEF("this is a short sentence"), false, false, 0, false, 80), "this is a short sentence", "one line");
|
||||||
|
|
||||||
TEST_RESULT_STR_Z(
|
TEST_RESULT_STR_Z(
|
||||||
helpRenderText(STRDEF("this is a short sentence"), false, 4, false, 14),
|
helpRenderText(STRDEF("this is a short sentence"), false, false, 4, false, 14),
|
||||||
"this is a\n"
|
"this is a\n"
|
||||||
" short\n"
|
" short\n"
|
||||||
" sentence",
|
" sentence",
|
||||||
"three lines, no indent first");
|
"three lines, no indent first");
|
||||||
|
|
||||||
TEST_RESULT_STR_Z(
|
TEST_RESULT_STR_Z(
|
||||||
helpRenderText(STRDEF("This is a short paragraph.\n\nHere is another one."), true, 2, true, 16),
|
helpRenderText(STRDEF("this is a short sentence"), true, true, 4, true, 132),
|
||||||
|
" this is a short sentence\n"
|
||||||
|
"\n"
|
||||||
|
" FOR BETA TESTING ONLY. DO NOT USE IN PRODUCTION.",
|
||||||
|
"beta feature");
|
||||||
|
|
||||||
|
TEST_RESULT_STR_Z(
|
||||||
|
helpRenderText(STRDEF("This is a short paragraph.\n\nHere is another one."), true, false, 2, true, 16),
|
||||||
" This is a\n"
|
" This is a\n"
|
||||||
" short\n"
|
" short\n"
|
||||||
" paragraph.\n"
|
" paragraph.\n"
|
||||||
|
@ -1634,7 +1634,7 @@ testRun(void)
|
|||||||
RECOVERY_SETTING_HEADER
|
RECOVERY_SETTING_HEADER
|
||||||
"a_setting = 'a'\n"
|
"a_setting = 'a'\n"
|
||||||
"b_setting = 'b'\n"
|
"b_setting = 'b'\n"
|
||||||
"restore_command = '" TEST_PROJECT_EXE " --lock-path=" HRN_PATH "/lock --log-path=" HRN_PATH " --pg1-path=/pg"
|
"restore_command = '" TEST_PROJECT_EXE " --beta --lock-path=" HRN_PATH "/lock --log-path=" HRN_PATH " --pg1-path=/pg"
|
||||||
" --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n",
|
" --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n",
|
||||||
"check recovery options");
|
"check recovery options");
|
||||||
|
|
||||||
@ -1648,8 +1648,8 @@ testRun(void)
|
|||||||
TEST_RESULT_STR_Z(
|
TEST_RESULT_STR_Z(
|
||||||
restoreRecoveryConf(PG_VERSION_94, restoreLabel),
|
restoreRecoveryConf(PG_VERSION_94, restoreLabel),
|
||||||
RECOVERY_SETTING_HEADER
|
RECOVERY_SETTING_HEADER
|
||||||
"restore_command = '/usr/local/bin/pg_wrapper.sh --lock-path=" HRN_PATH "/lock --log-path=" HRN_PATH " --pg1-path=/pg"
|
"restore_command = '/usr/local/bin/pg_wrapper.sh --beta --lock-path=" HRN_PATH "/lock --log-path=" HRN_PATH
|
||||||
" --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n",
|
" --pg1-path=/pg --repo1-path=/repo --stanza=test1 archive-get %f \"%p\"'\n",
|
||||||
"restore_command invokes /usr/local/bin/pg_wrapper.sh per --cmd option");
|
"restore_command invokes /usr/local/bin/pg_wrapper.sh per --cmd option");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1163,6 +1163,37 @@ testRun(void)
|
|||||||
"HINT: this option could expose secrets in the process list.\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.");
|
"HINT: specify the option in a configuration file or an environment variable instead.");
|
||||||
|
|
||||||
|
// These tests cheat a bit but there may not always be a beta option available for more general testing
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
|
TEST_TITLE("beta option dependency");
|
||||||
|
|
||||||
|
// Need to parse a command so there will be a valid index for the error message
|
||||||
|
argList = strLstNew();
|
||||||
|
strLstAddZ(argList, TEST_BACKREST_EXE);
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/db");
|
||||||
|
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||||
|
strLstAddZ(argList, TEST_COMMAND_BACKUP);
|
||||||
|
|
||||||
|
ParseOption betaOption = {0};
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
parseOptionBeta(cfgOptRepoPath, 0, true, &betaOption), OptionInvalidError,
|
||||||
|
"option 'repo1-path' is not valid without option 'beta'\n"
|
||||||
|
"HINT: beta features require the --beta option to prevent accidental usage.");
|
||||||
|
|
||||||
|
betaOption.indexListTotal = 1;
|
||||||
|
ParseOptionValue betaOptionValue = {.negate = true};
|
||||||
|
betaOption.indexList = &betaOptionValue;
|
||||||
|
|
||||||
|
TEST_ERROR(
|
||||||
|
parseOptionBeta(cfgOptRepoPath, 0, true, &betaOption), OptionInvalidError,
|
||||||
|
"option 'repo1-path' is not valid without option 'beta'\n"
|
||||||
|
"HINT: beta features require the --beta option to prevent accidental usage.");
|
||||||
|
|
||||||
|
betaOption.indexList[0].negate = false;
|
||||||
|
|
||||||
|
TEST_RESULT_VOID(parseOptionBeta(cfgOptRepoPath, 0, true, &betaOption), "beta option set");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("dependent option missing");
|
TEST_TITLE("dependent option missing");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user