1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-09-16 09:06:18 +02:00

Improve defaults and allow lists with option value dependencies.

Some defaults and allow lists were determined in cfgLoadUpdateOption() because they depended on the values of other options, .e.g. compress-level.

Instead build this functionality into the config parser. Not only does this standardize the defaults and allow lists but it makes it possible to automate the documentation, which is also done in this commit.
This commit is contained in:
David Steele
2025-06-16 17:21:33 -04:00
parent 435f8a3ad7
commit 44e3ee33d2
22 changed files with 1033 additions and 404 deletions

View File

@@ -44,30 +44,57 @@ referenceOptionRender(
xmlNodeChildAdd(xmlOption, optHlp->description);
// Add default value
// Add default value or default map
StringList *const blockList = strLstNew();
const String *const defaultValue =
const BldCfgOptionDefault *const defaultValue =
optCmdCfg != NULL && optCmdCfg->defaultValue != NULL ? optCmdCfg->defaultValue : optCfg->defaultValue;
if (optCfg->defaultType == defaultTypeDynamic)
{
ASSERT(strEqZ(optCfg->defaultValue, "bin"));
ASSERT(strEqZ(defaultValue->value, "bin"));
strLstAddZ(blockList, "default: [path of executed pgbackrest binary]");
}
else if (defaultValue != NULL)
{
if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR))
strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue, "true") ? "y" : "n");
if (defaultValue->value != NULL)
{
if (strEq(optCfg->type, OPT_TYPE_BOOLEAN_STR))
strLstAddFmt(blockList, "default: %s", strEqZ(defaultValue->value, "true") ? "y" : "n");
else
strLstAddFmt(blockList, "default: %s", strZ(defaultValue->value));
}
else
strLstAddFmt(blockList, "default: %s", strZ(defaultValue));
{
strLstAddFmt(blockList, "default (depending on %s):", strZ(optCfg->depend->option->name));
for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultValue->mapList); mapIdx++)
{
const BldCfgOptionDefaultMap *const map = lstGet(defaultValue->mapList, mapIdx);
strLstAddFmt(blockList, " %s - %s", strZ(map->map), strZ(map->value));
}
strLstAddZ(blockList, "");
}
}
// Add allow range
if (optCfg->allowRangeMin != NULL)
if (optCfg->allowRange != NULL)
{
ASSERT(optCfg->allowRangeMax != NULL);
strLstAddFmt(blockList, "allowed: %s-%s", strZ(optCfg->allowRangeMin), strZ(optCfg->allowRangeMax));
if (optCfg->allowRange->mapList != NULL)
{
strLstAddFmt(blockList, "allow range (depending on %s):", strZ(optCfg->depend->option->name));
for (unsigned int mapIdx = 0; mapIdx < lstSize(optCfg->allowRange->mapList); mapIdx++)
{
const BldCfgOptionAllowRangeMap *const map = lstGet(optCfg->allowRange->mapList, mapIdx);
strLstAddFmt(blockList, " %s - [%s, %s]", strZ(map->map), strZ(map->min), strZ(map->max));
}
strLstAddZ(blockList, "");
}
else
strLstAddFmt(blockList, "allowed: [%s, %s]", strZ(optCfg->allowRange->min), strZ(optCfg->allowRange->max));
}
// Add examples
@@ -110,7 +137,7 @@ referenceOptionRender(
}
if (!strLstEmpty(blockList))
xmlNodeContentSet(xmlNodeAdd(xmlOption, STRDEF("code-block")), strLstJoin(blockList, "\n"));
xmlNodeContentSet(xmlNodeAdd(xmlOption, STRDEF("code-block")), strTrim(strLstJoin(blockList, "\n")));
// Add deprecated names
if (optCfg->deprecateList != NULL)

View File

@@ -774,7 +774,25 @@ option:
section: global
type: integer
required: false
default:
- bz2: 9
- gz: 6
- lz4: 1
- zst: 3
allow-range:
- bz2: [1, 9]
- gz: [-1, 9]
- lz4: [-5, 12]
- zst: [-7, 22]
command: compress
depend:
option: compress-type
default: 0
list:
- bz2
- gz
- lz4
- zst
command-role:
async: {}
main: {}
@@ -1570,6 +1588,13 @@ option:
default: ~
required: false
allow-range: [0, 65535]
default:
- tls: 8432
depend:
option: pg-host-type
list:
- ssh
- tls
deprecate:
db-ssh-port: {}
db?-ssh-port: {}
@@ -2228,13 +2253,18 @@ option:
type: integer
required: false
allow-range: [0, 65535]
default:
- tls: 8432
depend:
option: repo-host-type
list:
- ssh
- tls
command: repo-host-cmd
command-role:
async: {}
main: {}
local: {}
depend:
option: repo-host
deprecate:
backup-ssh-port: {}
@@ -2621,6 +2651,10 @@ option:
group: repo
type: size
required: false
default:
- azure: 4MiB
- gcs: 4MiB
- s3: 5MiB
allow-range: [64KiB, 1TiB]
command: repo-type
depend:

View File

@@ -267,6 +267,32 @@ bldCfgParseOptionGroupList(Yaml *const yaml)
/***********************************************************************************************************************************
Parse option list
***********************************************************************************************************************************/
typedef struct BldCfgOptionAllowRangeMapRaw // See BldCfgOptionAllowRangeMap for comments
{
const String *map;
const String *min;
const String *max;
} BldCfgOptionAllowRangeMapRaw;
typedef struct BldCfgOptionAllowRangeRaw // See BldCfgOptionAllowRange for comments
{
const String *min;
const String *max;
List *mapList;
} BldCfgOptionAllowRangeRaw;
typedef struct BldCfgOptionDefaultMapRaw
{
const String *map; // See BldCfgOptionDefaultMap for comments
const String *value;
} BldCfgOptionDefaultMapRaw;
typedef struct BldCfgOptionDefaultRaw
{
const String *value; // See BldCfgOptionDefault for comments
List *mapList;
} BldCfgOptionDefaultRaw;
typedef struct BldCfgOptionDependRaw
{
const String *option; // See BldCfgOptionDepend for comments
@@ -286,7 +312,7 @@ typedef struct BldCfgOptionCommandRaw
const String *name; // See BldCfgOptionCommand for comments
const Variant *internal;
const Variant *required;
const String *defaultValue;
const BldCfgOptionDefaultRaw *defaultValue;
const BldCfgOptionDependRaw *depend;
const List *allowList;
const StringList *roleList;
@@ -304,13 +330,12 @@ typedef struct BldCfgOptionRaw
const Variant *negate;
bool reset;
DefaultType defaultType;
const String *defaultValue;
const BldCfgOptionDefaultRaw *defaultValue;
const String *group;
bool secure;
const BldCfgOptionDependRaw *depend;
const List *allowList;
const String *allowRangeMin;
const String *allowRangeMax;
const BldCfgOptionAllowRangeRaw *allowRange;
const List *cmdList;
const StringList *cmdRoleList;
const List *deprecateList;
@@ -411,26 +436,213 @@ bldCfgParseAllowList(Yaml *const yaml, const List *const optList)
}
// Helper to parse allow range
static void
bldCfgParseAllowRange(Yaml *const yaml, BldCfgOptionRaw *const opt)
static const BldCfgOptionAllowRange *
bldCfgParseAllowRangeDup(const BldCfgOptionAllowRangeRaw *const allowRangeRaw)
{
BldCfgOptionAllowRange *result = NULL;
if (allowRangeRaw != NULL)
{
result = memNew(sizeof(BldCfgOptionAllowRange));
*result = (BldCfgOptionAllowRange){0};
result->min = strDup(allowRangeRaw->min);
result->max = strDup(allowRangeRaw->max);
if (allowRangeRaw->mapList != NULL)
{
List *const mapList = lstNewP(sizeof(BldCfgOptionAllowRangeMap), .comparator = lstComparatorStr);
for (unsigned int mapIdx = 0; mapIdx < lstSize(allowRangeRaw->mapList); mapIdx++)
{
const BldCfgOptionAllowRangeMapRaw *const allowRangeMapRaw = lstGet(allowRangeRaw->mapList, mapIdx);
const BldCfgOptionAllowRangeMap allowRangeMap =
{
.map = strDup(allowRangeMapRaw->map),
.min = strDup(allowRangeMapRaw->min),
.max = strDup(allowRangeMapRaw->max),
};
lstAdd(mapList, &allowRangeMap);
}
result->mapList = mapList;
}
}
return result;
}
static const BldCfgOptionAllowRangeRaw *
bldCfgParseAllowRange(Yaml *const yaml)
{
BldCfgOptionAllowRangeRaw *result = memNew(sizeof(BldCfgOptionAllowRangeRaw));
*result = (BldCfgOptionAllowRangeRaw){0};
MEM_CONTEXT_TEMP_BEGIN()
{
yamlEventNextCheck(yaml, yamlEventTypeSeqBegin);
YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
MEM_CONTEXT_PRIOR_BEGIN()
if (yamlEventPeek(yaml).type == yamlEventTypeScalar)
{
opt->allowRangeMin = strDup(allowRangeMinVal.value);
opt->allowRangeMax = strDup(allowRangeMaxVal.value);
}
MEM_CONTEXT_PRIOR_END();
YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
yamlEventNextCheck(yaml, yamlEventTypeSeqEnd);
MEM_CONTEXT_PRIOR_BEGIN()
{
result->min = strDup(allowRangeMinVal.value);
result->max = strDup(allowRangeMaxVal.value);
}
MEM_CONTEXT_PRIOR_END();
yamlEventNextCheck(yaml, yamlEventTypeSeqEnd);
}
else
{
YamlEvent allowRangeVal = yamlEventNext(yaml);
MEM_CONTEXT_PRIOR_BEGIN()
{
result->mapList = lstNewP(sizeof(BldCfgOptionAllowRangeMapRaw));
}
MEM_CONTEXT_PRIOR_END();
do
{
yamlEventCheck(allowRangeVal, yamlEventTypeMapBegin);
const String *const map = yamlEventNextCheck(yaml, yamlEventTypeScalar).value;
yamlEventNextCheck(yaml, yamlEventTypeSeqBegin);
YamlEvent allowRangeMinVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
YamlEvent allowRangeMaxVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
MEM_CONTEXT_PRIOR_BEGIN()
{
const BldCfgOptionAllowRangeMapRaw allowRangeMap =
{
.map = strDup(map),
.min = strDup(allowRangeMinVal.value),
.max = strDup(allowRangeMaxVal.value),
};
lstAdd(result->mapList, &allowRangeMap);
}
MEM_CONTEXT_PRIOR_END();
yamlEventNextCheck(yaml, yamlEventTypeSeqEnd);
yamlEventNextCheck(yaml, yamlEventTypeMapEnd);
allowRangeVal = yamlEventNext(yaml);
}
while (allowRangeVal.type != yamlEventTypeSeqEnd);
}
}
MEM_CONTEXT_TEMP_END();
return result;
}
// Helper to parse default
static const BldCfgOptionDefault *
bldCfgParseDefaultDup(const BldCfgOptionDefaultRaw *const defaultRaw)
{
BldCfgOptionDefault *result = NULL;
if (defaultRaw != NULL)
{
result = memNew(sizeof(BldCfgOptionDefault));
*result = (BldCfgOptionDefault){0};
result->value = strDup(defaultRaw->value);
if (defaultRaw->mapList != NULL)
{
List *const mapList = lstNewP(sizeof(BldCfgOptionDefaultMap), .comparator = lstComparatorStr);
for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultRaw->mapList); mapIdx++)
{
const BldCfgOptionDefaultMapRaw *const defaultMapRaw = lstGet(defaultRaw->mapList, mapIdx);
const BldCfgOptionDefaultMap defaultMap =
{
.map = strDup(defaultMapRaw->map),
.value = strDup(defaultMapRaw->value),
};
lstAdd(mapList, &defaultMap);
}
result->mapList = mapList;
}
}
return result;
}
static const BldCfgOptionDefaultRaw *
bldCfgParseDefault(Yaml *const yaml)
{
BldCfgOptionDefaultRaw *result = memNew(sizeof(BldCfgOptionDefaultRaw));
*result = (BldCfgOptionDefaultRaw){0};
MEM_CONTEXT_TEMP_BEGIN()
{
YamlEvent defaultVal = yamlEventNext(yaml);
if (defaultVal.type == yamlEventTypeScalar)
{
// If an override to inheritance then set to NULL
if (strEqZ(defaultVal.value, "~"))
result = NULL;
else
{
MEM_CONTEXT_PRIOR_BEGIN()
{
result->value = strDup(defaultVal.value);
}
MEM_CONTEXT_PRIOR_END();
}
}
else
{
yamlEventCheck(defaultVal, yamlEventTypeSeqBegin);
defaultVal = yamlEventNext(yaml);
MEM_CONTEXT_PRIOR_BEGIN()
{
result->mapList = lstNewP(sizeof(BldCfgOptionDefaultMapRaw));
}
MEM_CONTEXT_PRIOR_END();
do
{
yamlEventCheck(defaultVal, yamlEventTypeMapBegin);
const String *const map = yamlEventNextCheck(yaml, yamlEventTypeScalar).value;
const String *const value = yamlEventNextCheck(yaml, yamlEventTypeScalar).value;
MEM_CONTEXT_PRIOR_BEGIN()
{
const BldCfgOptionDefaultMapRaw defaultMap =
{
.map = strDup(map),
.value = strDup(value),
};
lstAdd(result->mapList, &defaultMap);
}
MEM_CONTEXT_PRIOR_END();
yamlEventNextCheck(yaml, yamlEventTypeMapEnd);
defaultVal = yamlEventNext(yaml);
}
while (defaultVal.type != yamlEventTypeSeqEnd);
}
}
MEM_CONTEXT_TEMP_END();
return result;
}
// Helper to parse depend
@@ -531,8 +743,11 @@ bldCfgParseDependReconcile(
if (optDependRaw != NULL)
{
if (optDependRaw->defaultValue != NULL && !strEq(optRaw->type, OPT_TYPE_BOOLEAN_STR))
THROW_FMT(FormatError, "dependency default invalid for non-boolean option '%s'", strZ(optRaw->name));
if (optDependRaw->defaultValue != NULL && !strEq(optRaw->type, OPT_TYPE_BOOLEAN_STR) &&
!strEq(optRaw->type, OPT_TYPE_INTEGER_STR))
{
THROW_FMT(FormatError, "dependency default invalid for non integer/boolean option '%s'", strZ(optRaw->name));
}
const BldCfgOption *const optDepend = lstFind(optList, &optDependRaw->option);
@@ -686,22 +901,19 @@ bldCfgParseOptionCommandList(Yaml *const yaml, const List *const optList)
}
MEM_CONTEXT_END();
}
else if (strEqZ(optCmdDef.value, "default"))
{
MEM_CONTEXT_BEGIN(lstMemContext(optCmdRawList))
{
optCmdRaw.defaultValue = bldCfgParseDefault(yaml);
}
MEM_CONTEXT_END();
}
else
{
YamlEvent optCmdDefVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
if (strEqZ(optCmdDef.value, "default"))
{
// If an override to inheritance
if (strEqZ(optCmdDefVal.value, "~"))
{
optCmdRaw.defaultValue = NULL;
}
// Else set the value
else
optCmdRaw.defaultValue = optCmdDefVal.value;
}
else if (strEqZ(optCmdDef.value, "internal"))
if (strEqZ(optCmdDef.value, "internal"))
{
optCmdRaw.internal = varNewBool(yamlBoolParse(optCmdDefVal));
}
@@ -727,7 +939,7 @@ bldCfgParseOptionCommandList(Yaml *const yaml, const List *const optList)
.name = strDup(optCmdRaw.name),
.internal = varDup(optCmdRaw.internal),
.required = varDup(optCmdRaw.required),
.defaultValue = strDup(optCmdRaw.defaultValue),
.defaultValue = optCmdRaw.defaultValue,
.depend = optCmdRaw.depend,
.allowList = bldCfgParseAllowListDup(optCmdRaw.allowList),
.roleList = strLstDup(optCmdRaw.roleList),
@@ -798,7 +1010,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
}
else if (strEqZ(optDef.value, "allow-range"))
{
bldCfgParseAllowRange(yaml, &optRaw);
optRaw.allowRange = bldCfgParseAllowRange(yaml);
}
else if (strEqZ(optDef.value, "command"))
{
@@ -808,6 +1020,10 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
{
optRaw.cmdRoleList = bldCfgParseCommandRole(yaml);
}
else if (strEqZ(optDef.value, "default"))
{
optRaw.defaultValue = bldCfgParseDefault(yaml);
}
else if (strEqZ(optDef.value, "depend"))
{
optRaw.depend = bldCfgParseDepend(yaml, optListRaw);
@@ -820,18 +1036,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
{
YamlEvent optDefVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
if (strEqZ(optDef.value, "default"))
{
// If an override to inheritance
if (strEqZ(optDefVal.value, "~"))
{
optRaw.defaultValue = NULL;
}
// Else set the value
else
optRaw.defaultValue = optDefVal.value;
}
else if (strEqZ(optDef.value, "default-type"))
if (strEqZ(optDef.value, "default-type"))
{
if (strEqZ(optDefVal.value, "quote"))
optRaw.defaultType = defaultTypeQuote;
@@ -973,12 +1178,11 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
.negate = varBool(optRaw->negate),
.reset = optRaw->reset,
.defaultType = optRaw->defaultType,
.defaultValue = strDup(optRaw->defaultValue),
.defaultValue = bldCfgParseDefaultDup(optRaw->defaultValue),
.group = strDup(optRaw->group),
.secure = optRaw->secure,
.allowList = bldCfgParseAllowListDup(optRaw->allowList),
.allowRangeMin = strDup(optRaw->allowRangeMin),
.allowRangeMax = strDup(optRaw->allowRangeMax),
.allowRange = bldCfgParseAllowRangeDup(optRaw->allowRange),
.deprecateList = bldCfgParseOptionDeprecateReconcile(optRaw->deprecateList),
};
@@ -1049,7 +1253,7 @@ bldCfgParseOptionList(Yaml *const yaml, const List *const cmdList, const List *c
.name = strDup(optCmd.name),
.internal = varBool(optCmd.internal),
.required = varBool(optCmd.required),
.defaultValue = strDup(optCmd.defaultValue),
.defaultValue = bldCfgParseDefaultDup(optCmd.defaultValue),
.depend = bldCfgParseDependReconcile(optRaw, optCmd.depend, result),
.allowList = bldCfgParseAllowListDup(optCmd.allowList),
.roleList = strLstDup(optCmd.roleList),

View File

@@ -99,6 +99,32 @@ typedef struct BldCfgOptionGroup
typedef struct BldCfgOption BldCfgOption; // Forward declaration
typedef struct BldCfgOptionAllowRangeMap
{
const String *map; // Map value
const String *min; // Min value
const String *max; // Max value
} BldCfgOptionAllowRangeMap;
typedef struct BldCfgOptionAllowRange
{
const String *min; // Min value
const String *max; // Max value
const List *mapList; // List of default mappings
} BldCfgOptionAllowRange;
typedef struct BldCfgOptionDefaultMap
{
const String *map; // Map value
const String *value; // Default value
} BldCfgOptionDefaultMap;
typedef struct BldCfgOptionDefault
{
const String *value; // Default value
const List *mapList; // List of default mappings
} BldCfgOptionDefault;
typedef struct BldCfgOptionDepend
{
const BldCfgOption *option; // Option dependency is on
@@ -118,7 +144,7 @@ typedef struct BldCfgOptionCommand
const String *name; // Name
bool internal; // Is the option internal?
bool required; // Is the option required?
const String *defaultValue; // Default value, if any
const BldCfgOptionDefault *defaultValue; // Default value, if any
const BldCfgOptionDepend *depend; // Dependency, if any
const List *allowList; // Allowed value list
const StringList *roleList; // Roles valid for the command
@@ -142,13 +168,12 @@ struct BldCfgOption
bool negate; // Can the option be negated?
bool reset; // Can the option be reset?
DefaultType defaultType; // Type of default
const String *defaultValue; // Default value, if any
const BldCfgOptionDefault *defaultValue; // Default value, if any
const String *group; // Option group, if any
bool secure; // Does the option contain a secret?
const BldCfgOptionDepend *depend; // Dependency, if any
const List *allowList; // Allowed value list
const String *allowRangeMin; // Allow range min, if any
const String *allowRangeMax; // Allow range max, if any
const BldCfgOptionAllowRange *allowRange; // Allow range, if any
const List *cmdList; // Command override list
const List *deprecateList; // List of option deprecations
};

View File

@@ -397,7 +397,7 @@ bldCfgRenderScalar(const String *const scalar, const String *const optType)
// Helper to render validity
static String *
bldCfgRenderValid(const BldCfgOptionDepend *const depend)
bldCfgRenderValid(const String *const type, const BldCfgOptionDepend *const depend)
{
ASSERT(depend != NULL);
@@ -412,8 +412,7 @@ bldCfgRenderValid(const BldCfgOptionDepend *const depend)
{
strCatFmt(
result,
" PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(%s),\n",
strZ(bldCfgRenderScalar(depend->defaultValue, OPT_TYPE_BOOLEAN_STR)));
" PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(%s),\n", strZ(bldCfgRenderScalar(depend->defaultValue, type)));
}
strCatFmt(
@@ -444,20 +443,57 @@ bldCfgRenderValid(const BldCfgOptionDepend *const depend)
// Helper to render allow range
static String *
bldCfgRenderAllowRange(const String *const allowRangeMin, const String *const allowRangeMax, const String *const optType)
bldCfgRenderAllowRange(const BldCfgOptionAllowRange *const allowRange, const String *const optType)
{
ASSERT(allowRangeMin != NULL);
ASSERT(allowRangeMax != NULL);
ASSERT((allowRange->min != NULL && allowRange->min != NULL) || (allowRange->min == NULL && allowRange->min == NULL));
ASSERT((allowRange->mapList == NULL && allowRange->min != NULL) || (allowRange->mapList != NULL && allowRange->min == NULL));
ASSERT(optType != NULL);
return strNewFmt(
String *const result = strCatZ(
strNew(),
" PARSE_RULE_OPTIONAL_ALLOW_RANGE\n"
" (\n"
" %s,\n"
" %s,\n"
" )",
strZ(bldCfgRenderScalar(allowRangeMin, optType)),
strZ(bldCfgRenderScalar(allowRangeMax, optType)));
" (\n");
if (allowRange->mapList != NULL)
{
strCatFmt(
result,
" PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n"
" (\n");
for (unsigned int mapIdx = 0; mapIdx < lstSize(allowRange->mapList); mapIdx++)
{
const BldCfgOptionAllowRangeMap *const allowRangeMap = lstGet(allowRange->mapList, mapIdx);
strCatFmt(
result,
" %s,\n"
" %s,\n"
" %s,\n",
strZ(bldCfgRenderScalar(allowRangeMap->map, OPT_TYPE_STRING_ID_STR)),
strZ(bldCfgRenderScalar(allowRangeMap->min, optType)),
strZ(bldCfgRenderScalar(allowRangeMap->max, optType)));
}
strCatZ(
result,
" ),\n");
}
else
{
strCatFmt(
result,
" %s,\n"
" %s,\n",
strZ(bldCfgRenderScalar(allowRange->min, optType)),
strZ(bldCfgRenderScalar(allowRange->max, optType)));
}
strCatZ(
result,
" )");
return result;
}
// Helper to render allow list
@@ -497,9 +533,36 @@ bldCfgRenderAllowList(const List *const allowList, const String *const optType)
}
// Helper to render default
static void
bldCfgRenderDefaultValue(
String *const result, const String *const defaultValue, const DefaultType defaultType, const String *const optType,
const bool indent)
{
ASSERT(defaultValue != NULL);
ASSERT(optType != NULL);
if (indent)
strCatZ(result, " ");
if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR))
{
strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType)));
}
else
{
strCatFmt(
result,
" %s,\n",
strZ(
bldCfgRenderScalar(
strNewFmt(
"%s%s%s", defaultType == defaultTypeLiteral ? "" : "\"", strZ(defaultValue),
defaultType == defaultTypeLiteral ? "" : "\""), OPT_TYPE_STRING_STR)));
}
}
static String *
bldCfgRenderDefault(
const String *const defaultValue, const DefaultType defaultType, const String *const optType)
bldCfgRenderDefault(const BldCfgOptionDefault *const defaultValue, const DefaultType defaultType, const String *const optType)
{
ASSERT(defaultValue != NULL);
ASSERT(optType != NULL);
@@ -513,20 +576,29 @@ bldCfgRenderDefault(
if (defaultType == defaultTypeDynamic)
{
strCatFmt(result, " PARSE_RULE_DEFAULT_DYNAMIC(%s),\n", strZ(bldEnum("", defaultValue)));
strCatFmt(result, " PARSE_RULE_DEFAULT_DYNAMIC(%s),\n", strZ(bldEnum("", defaultValue->value)));
}
else if (!strEq(optType, OPT_TYPE_STRING_STR) && !strEq(optType, OPT_TYPE_PATH_STR))
strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(defaultValue, optType)));
else if (defaultValue->value != NULL)
bldCfgRenderDefaultValue(result, defaultValue->value, defaultType, optType, false);
else
{
strCatFmt(
ASSERT(defaultValue->mapList != NULL);
strCatZ(
result,
" %s,\n",
strZ(
bldCfgRenderScalar(
strNewFmt(
"%s%s%s", defaultType == defaultTypeLiteral ? "" : "\"", strZ(defaultValue),
defaultType == defaultTypeLiteral ? "" : "\""), OPT_TYPE_STRING_STR)));
" PARSE_RULE_OPTIONAL_DEFAULT_MAP\n"
" (\n");
for (unsigned int mapIdx = 0; mapIdx < lstSize(defaultValue->mapList); mapIdx++)
{
const BldCfgOptionDefaultMap *const map = lstGet(defaultValue->mapList, mapIdx);
strCatFmt(result, " %s,\n", strZ(bldCfgRenderScalar(map->map, OPT_TYPE_STRING_ID_STR)));
bldCfgRenderDefaultValue(result, map->value, defaultType, optType, true);
}
strCatZ(result, " ),\n");
}
strCatZ(result, " )");
@@ -867,7 +939,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
// Build list of dynamic defaults
if (opt->defaultType == defaultTypeDynamic)
strLstAddIfMissing(dynamicDefaultList, opt->defaultValue);
strLstAddIfMissing(dynamicDefaultList, opt->defaultValue->value);
if (optIdx != 0)
strCatZ(config, COMMENT_SEPARATOR "\n");
@@ -972,16 +1044,27 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
const Variant *const ruleList[] = {ruleDepend, ruleAllowRange, ruleAllowList, ruleDefault, ruleRequire};
if (opt->depend)
kvAdd(optionalDefaultRule, ruleDepend, VARSTR(bldCfgRenderValid(opt->depend)));
kvAdd(optionalDefaultRule, ruleDepend, VARSTR(bldCfgRenderValid(opt->type, opt->depend)));
if (opt->allowRangeMin != NULL)
if (opt->allowRange != NULL)
{
kvAdd(
optionalDefaultRule, ruleAllowRange,
VARSTR(bldCfgRenderAllowRange(opt->allowRangeMin, opt->allowRangeMax, opt->type)));
kvAdd(optionalDefaultRule, ruleAllowRange, VARSTR(bldCfgRenderAllowRange(opt->allowRange, opt->type)));
bldCfgRenderValueAdd(opt->type, false, opt->allowRangeMin, ruleValMap);
bldCfgRenderValueAdd(opt->type, false, opt->allowRangeMax, ruleValMap);
if (opt->allowRange->mapList != NULL)
{
for (unsigned int mapIdx = 0; mapIdx < lstSize(opt->allowRange->mapList); mapIdx++)
{
const BldCfgOptionAllowRangeMap *const allowRangeMap = lstGet(opt->allowRange->mapList, mapIdx);
bldCfgRenderValueAdd(opt->type, false, allowRangeMap->min, ruleValMap);
bldCfgRenderValueAdd(opt->type, false, allowRangeMap->max, ruleValMap);
}
}
else
{
bldCfgRenderValueAdd(opt->type, false, opt->allowRange->min, ruleValMap);
bldCfgRenderValueAdd(opt->type, false, opt->allowRange->max, ruleValMap);
}
}
if (opt->allowList != NULL)
@@ -997,10 +1080,24 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
if (opt->defaultValue != NULL)
{
kvAdd(optionalDefaultRule, ruleDefault, VARSTR(bldCfgRenderDefault(opt->defaultValue, opt->defaultType, opt->type)));
kvAdd(
optionalDefaultRule, ruleDefault,
VARSTR(bldCfgRenderDefault(opt->defaultValue, opt->defaultType, opt->type)));
if (!strEq(opt->type, OPT_TYPE_BOOLEAN_STR))
bldCfgRenderValueAdd(opt->type, opt->defaultType, opt->defaultValue, ruleValMap);
{
if (opt->defaultValue->value != NULL)
bldCfgRenderValueAdd(opt->type, opt->defaultType, opt->defaultValue->value, ruleValMap);
if (opt->defaultValue->mapList != NULL)
{
for (unsigned int mapIdx = 0; mapIdx < lstSize(opt->defaultValue->mapList); mapIdx++)
{
const BldCfgOptionDefaultMap *const map = lstGet(opt->defaultValue->mapList, mapIdx);
bldCfgRenderValueAdd(opt->type, opt->defaultType, map->value, ruleValMap);
}
}
}
}
// Build command optional rules
@@ -1013,7 +1110,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
// Depends
if (optCmd->depend != NULL)
kvAdd(optionalCmdRuleType, ruleDepend, VARSTR(bldCfgRenderValid(optCmd->depend)));
kvAdd(optionalCmdRuleType, ruleDepend, VARSTR(bldCfgRenderValid(opt->type, optCmd->depend)));
// Allow lists
if (optCmd->allowList != NULL)
@@ -1035,7 +1132,7 @@ bldCfgRenderParseAutoC(const Storage *const storageRepo, const BldCfg bldCfg, co
VARSTR(bldCfgRenderDefault(optCmd->defaultValue, opt->defaultType, opt->type)));
if (!strEq(opt->type, OPT_TYPE_BOOLEAN_STR))
bldCfgRenderValueAdd(opt->type, opt->defaultType, optCmd->defaultValue, ruleValMap);
bldCfgRenderValueAdd(opt->type, opt->defaultType, optCmd->defaultValue->value, ruleValMap);
}
// Requires

View File

@@ -230,15 +230,6 @@
<text>
<p>Sets the level to be used for file compression when <setting>compress-type</setting> does not equal <id>none</id> or <setting>compress=y</setting> (deprecated).</p>
<p>The following are the defaults levels based on <setting>compress-type</setting> when <setting>compress-level</setting> is not specified:</p>
<list>
<list-item><id>bz2</id> - 9</list-item>
<list-item><id>gz</id> - 6</list-item>
<list-item><id>lz4</id> - 1</list-item>
<list-item><id>zst</id> - 3</list-item>
</list>
</text>
<allow>0-9</allow>
@@ -848,6 +839,8 @@
<text>
<p>Use this option to specify a non-default port for the repository host protocol.</p>
<admonition type="note">When <setting>repo-host-type=ssh</setting> there is no default for <setting>repo-host-port</setting>. In this case the port will be whatever is configured for the command specified by <setting>cmd-ssh</setting>.</admonition>
</text>
<example>25</example>
@@ -1263,14 +1256,6 @@
<p>A larger chunk size will generally lead to better performance because it will minimize upload requests and allow more files to be uploaded in a single request rather than in chunks. The disadvantage is that memory usage will be higher and because the chunk buffer must be allocated per process, larger <br-option>process-max</br-option> values will lead to more memory being consumed overall.</p>
<p>Default chunk sizes by repo type:</p>
<list>
<list-item><id>azure</id> - 4MiB</list-item>
<list-item><id>gcs</id> - 4MiB</list-item>
<list-item><id>s3</id> - 5MiB</list-item>
</list>
<p>Note that valid chunk sizes vary by storage type and by platform. For example, <proper>AWS S3</proper> has a minimum chunk size of 5MiB but <proper>S3</proper> clones may accept lower values. Terminology for chunk size varies by storage type, so when searching min/max values use <quote>part size</quote> for <proper>AWS S3</proper>, <quote>chunk size</quote> for <proper>GCS</proper>, and <quote>block size</quote> for <proper>Azure</proper>. No attempt is made to validate configured chunk sizes so selecting an invalid value will lead to errors from the storage service or undefined behavior.</p>
</text>
@@ -1974,6 +1959,8 @@
<text>
<p>Use this option to specify a non-default port for the <postgres/> host protocol.</p>
<admonition type="note">When <setting>pg-host-type=ssh</setting> there is no default for <setting>pg-host-port</setting>. In this case the port will be whatever is configured for the command specified by <setting>cmd-ssh</setting>.</admonition>
</text>
<example>25</example>

View File

@@ -16,7 +16,6 @@ Filter type constant
/***********************************************************************************************************************************
Level constants
***********************************************************************************************************************************/
#define BZ2_COMPRESS_LEVEL_DEFAULT 9
#define BZ2_COMPRESS_LEVEL_MIN 1
#define BZ2_COMPRESS_LEVEL_MAX 9

View File

@@ -16,7 +16,6 @@ Filter type constant
/***********************************************************************************************************************************
Level constants
***********************************************************************************************************************************/
#define GZ_COMPRESS_LEVEL_DEFAULT 6
#define GZ_COMPRESS_LEVEL_MIN -1
#define GZ_COMPRESS_LEVEL_MAX 9

View File

@@ -12,7 +12,6 @@ Compression Helper
#include "common/compress/gz/compress.h"
#include "common/compress/gz/decompress.h"
#include "common/compress/helper.h"
#include "common/compress/helper.intern.h"
#include "common/compress/lz4/common.h"
#include "common/compress/lz4/compress.h"
#include "common/compress/lz4/decompress.h"
@@ -43,9 +42,6 @@ static const struct CompressHelperLocal
IoFilter *(*compressNew)(int, bool); // Function to create new compression filter
StringId decompressType; // Type of the decompression filter
IoFilter *(*decompressNew)(bool); // Function to create new decompression filter
int levelDefault : 8; // Default compression level
int levelMin : 8; // Minimum compression level
int levelMax : 8; // Maximum compression level
} compressHelperLocal[] =
{
{
@@ -61,9 +57,6 @@ static const struct CompressHelperLocal
.compressNew = bz2CompressNew,
.decompressType = BZ2_DECOMPRESS_FILTER_TYPE,
.decompressNew = bz2DecompressNew,
.levelDefault = BZ2_COMPRESS_LEVEL_DEFAULT,
.levelMin = BZ2_COMPRESS_LEVEL_MIN,
.levelMax = BZ2_COMPRESS_LEVEL_MAX,
},
{
.typeId = STRID5("gz", 0x3470),
@@ -73,9 +66,6 @@ static const struct CompressHelperLocal
.compressNew = gzCompressNew,
.decompressType = GZ_DECOMPRESS_FILTER_TYPE,
.decompressNew = gzDecompressNew,
.levelDefault = GZ_COMPRESS_LEVEL_DEFAULT,
.levelMin = GZ_COMPRESS_LEVEL_MIN,
.levelMax = GZ_COMPRESS_LEVEL_MAX,
},
{
.typeId = STRID6("lz4", 0x2068c1),
@@ -85,9 +75,6 @@ static const struct CompressHelperLocal
.compressNew = lz4CompressNew,
.decompressType = LZ4_DECOMPRESS_FILTER_TYPE,
.decompressNew = lz4DecompressNew,
.levelDefault = LZ4_COMPRESS_LEVEL_DEFAULT,
.levelMin = LZ4_COMPRESS_LEVEL_MIN,
.levelMax = LZ4_COMPRESS_LEVEL_MAX,
},
{
.typeId = STRID5("zst", 0x527a0),
@@ -98,9 +85,6 @@ static const struct CompressHelperLocal
.compressNew = zstCompressNew,
.decompressType = ZST_DECOMPRESS_FILTER_TYPE,
.decompressNew = zstDecompressNew,
.levelDefault = ZST_COMPRESS_LEVEL_DEFAULT,
.levelMin = ZST_COMPRESS_LEVEL_MIN,
.levelMax = ZST_COMPRESS_LEVEL_MAX,
#endif
},
{
@@ -185,48 +169,6 @@ compressTypeFromName(const String *const name)
FUNCTION_TEST_RETURN(ENUM, result);
}
/**********************************************************************************************************************************/
FN_EXTERN int
compressLevelDefault(const CompressType type)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, type);
FUNCTION_TEST_END();
ASSERT(type < LENGTH_OF(compressHelperLocal));
compressTypePresent(type);
FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelDefault);
}
/**********************************************************************************************************************************/
FN_EXTERN int
compressLevelMin(const CompressType type)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, type);
FUNCTION_TEST_END();
ASSERT(type < LENGTH_OF(compressHelperLocal));
compressTypePresent(type);
FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelMin);
}
/**********************************************************************************************************************************/
FN_EXTERN int
compressLevelMax(const CompressType type)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(ENUM, type);
FUNCTION_TEST_END();
ASSERT(type < LENGTH_OF(compressHelperLocal));
compressTypePresent(type);
FUNCTION_TEST_RETURN(INT, compressHelperLocal[type].levelMax);
}
/**********************************************************************************************************************************/
FN_EXTERN IoFilter *
compressFilter(const CompressType type, const int level, const CompressFilterParam param)

View File

@@ -1,21 +0,0 @@
/***********************************************************************************************************************************
Compression Helper Internal
***********************************************************************************************************************************/
#ifndef COMMON_COMPRESS_HELPER_INTERN_H
#define COMMON_COMPRESS_HELPER_INTERN_H
#include "common/compress/helper.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Default compression level for a compression type, used while loading the configuration
FN_EXTERN int compressLevelDefault(CompressType type);
// Minimum compression level for a compression type, used while loading the configuration
FN_EXTERN int compressLevelMin(CompressType type);
// Maximum compression level for a compression type, used while loading the configuration
FN_EXTERN int compressLevelMax(CompressType type);
#endif

View File

@@ -16,7 +16,6 @@ Filter type constant
/***********************************************************************************************************************************
Level constants
***********************************************************************************************************************************/
#define LZ4_COMPRESS_LEVEL_DEFAULT 1
#define LZ4_COMPRESS_LEVEL_MIN -5
#define LZ4_COMPRESS_LEVEL_MAX 12

View File

@@ -18,7 +18,6 @@ Filter type constant
/***********************************************************************************************************************************
Level constants
***********************************************************************************************************************************/
#define ZST_COMPRESS_LEVEL_DEFAULT 3
#define ZST_COMPRESS_LEVEL_MIN -7
#define ZST_COMPRESS_LEVEL_MAX 22

View File

@@ -9,7 +9,6 @@ Configuration Load
#include "command/command.h"
#include "command/lock.h"
#include "common/compress/helper.intern.h"
#include "common/crypto/common.h"
#include "common/debug.h"
#include "common/io/io.h"
@@ -289,48 +288,6 @@ cfgLoadUpdateOption(void)
}
}
// Set default upload chunk size if not set
if (cfgOptionValid(cfgOptRepoStorageUploadChunkSize))
{
for (unsigned int repoIdx = 0; repoIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); repoIdx++)
{
if (!cfgOptionIdxTest(cfgOptRepoStorageUploadChunkSize, repoIdx))
{
cfgOptionIdxSet(
cfgOptRepoStorageUploadChunkSize, repoIdx, cfgSourceDefault,
VARINT64((cfgOptionIdxStrId(cfgOptRepoType, repoIdx) == CFGOPTVAL_REPO_TYPE_S3 ? 5 : 4) * 1024 * 1024));
}
}
}
// Set pg-host-port/repo-host-port default when pg-host-type/repo-host-type is tls. ??? This should be handled in the parser but
// it requires a default that depends on another option value and that is not currently possible.
#define HOST_PORT_TLS 8432
if (cfgOptionValid(cfgOptRepoHostPort))
{
for (unsigned int repoIdx = 0; repoIdx < cfgOptionGroupIdxTotal(cfgOptGrpRepo); repoIdx++)
{
if (cfgOptionIdxStrId(cfgOptRepoHostType, repoIdx) == CFGOPTVAL_REPO_HOST_TYPE_TLS &&
cfgOptionIdxSource(cfgOptRepoHostPort, repoIdx) == cfgSourceDefault)
{
cfgOptionIdxSet(cfgOptRepoHostPort, repoIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS));
}
}
}
if (cfgOptionValid(cfgOptPgHostPort))
{
for (unsigned int pgIdx = 0; pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg); pgIdx++)
{
if (cfgOptionIdxStrId(cfgOptPgHostType, pgIdx) == CFGOPTVAL_PG_HOST_TYPE_TLS &&
cfgOptionIdxSource(cfgOptPgHostPort, pgIdx) == cfgSourceDefault)
{
cfgOptionIdxSet(cfgOptPgHostPort, pgIdx, cfgSourceDefault, VARINT64(HOST_PORT_TLS));
}
}
}
// Check/update compress-type if compress is valid. There should be no references to the compress option outside this block.
if (cfgOptionValid(cfgOptCompress))
{
@@ -346,7 +303,10 @@ cfgLoadUpdateOption(void)
// Set compress-type to none. Eventually the compress option will be deprecated and removed so this reduces code churn
// when that happens.
if (!cfgOptionBool(cfgOptCompress) && cfgOptionSource(cfgOptCompressType) == cfgSourceDefault)
{
cfgOptionSet(cfgOptCompressType, cfgSourceParam, VARUINT64(CFGOPTVAL_COMPRESS_TYPE_NONE));
cfgOptionSet(cfgOptCompressLevel, cfgSourceDefault, VARINT64(0));
}
}
// Now invalidate compress so it can't be used and won't be passed to child processes
@@ -354,29 +314,7 @@ cfgLoadUpdateOption(void)
cfgOptionSet(cfgOptCompress, cfgSourceDefault, NULL);
}
// Update compress-level default based on the compression type. Also check that level range is valid per compression type.
if (cfgOptionValid(cfgOptCompressLevel))
{
const CompressType compressType = compressTypeEnum(cfgOptionStrId(cfgOptCompressType));
if (cfgOptionSource(cfgOptCompressLevel) == cfgSourceDefault)
{
cfgOptionSet(cfgOptCompressLevel, cfgSourceDefault, VARINT64(compressLevelDefault(compressType)));
}
else if (compressType != compressTypeNone)
{
if (cfgOptionInt(cfgOptCompressLevel) < compressLevelMin(compressType) ||
cfgOptionInt(cfgOptCompressLevel) > compressLevelMax(compressType))
{
THROW_FMT(
OptionInvalidValueError,
"'%d' is out of range for '" CFGOPT_COMPRESS_LEVEL "' option when '" CFGOPT_COMPRESS_TYPE "' option = '%s'",
cfgOptionInt(cfgOptCompressLevel), strZ(strIdToStr(cfgOptionStrId(cfgOptCompressType))));
}
}
}
// Error if repo-sftp-host-key-check-type is explicitly set to anything other than fingerprint and repo-sftp-host-fingerprint
// Error if repo-sftp--host-key-check-type is explicitly set to anything other than fingerprint and repo-sftp-host-fingerprint
// is also specified. For backward compatibility we need to allow repo-sftp-host-fingerprint when
// repo-sftp-host-key-check-type defaults to yes, but emit a warning to let the user know to change the configuration. Also
// set repo-sftp-host-key-check-type=fingerprint so other code does not need to know about this exception.

View File

@@ -11,7 +11,9 @@ Rule Strings
static const StringPubConst parseRuleValueStr[] =
{
PARSE_RULE_STRPUB("-1"), // val/str
PARSE_RULE_STRPUB("-5"), // val/str
PARSE_RULE_STRPUB("-7"), // val/str
PARSE_RULE_STRPUB("/tmp/pgbackrest"), // val/str
PARSE_RULE_STRPUB("/var/lib/pgbackrest"), // val/str
PARSE_RULE_STRPUB("/var/log/pgbackrest"), // val/str
@@ -43,6 +45,7 @@ static const StringPubConst parseRuleValueStr[] =
PARSE_RULE_STRPUB("256"), // val/str
PARSE_RULE_STRPUB("256KiB"), // val/str
PARSE_RULE_STRPUB("2MiB"), // val/str
PARSE_RULE_STRPUB("3"), // val/str
PARSE_RULE_STRPUB("30m"), // val/str
PARSE_RULE_STRPUB("31m"), // val/str
PARSE_RULE_STRPUB("32"), // val/str
@@ -54,12 +57,15 @@ static const StringPubConst parseRuleValueStr[] =
PARSE_RULE_STRPUB("4PiB"), // val/str
PARSE_RULE_STRPUB("512KiB"), // val/str
PARSE_RULE_STRPUB("5432"), // val/str
PARSE_RULE_STRPUB("5MiB"), // val/str
PARSE_RULE_STRPUB("6"), // val/str
PARSE_RULE_STRPUB("64KiB"), // val/str
PARSE_RULE_STRPUB("65535"), // val/str
PARSE_RULE_STRPUB("7d"), // val/str
PARSE_RULE_STRPUB("8432"), // val/str
PARSE_RULE_STRPUB("8KiB"), // val/str
PARSE_RULE_STRPUB("8MiB"), // val/str
PARSE_RULE_STRPUB("9"), // val/str
PARSE_RULE_STRPUB("900"), // val/str
PARSE_RULE_STRPUB("999"), // val/str
PARSE_RULE_STRPUB("9999999"), // val/str
@@ -136,7 +142,9 @@ static const StringPubConst parseRuleValueStr[] =
typedef enum
{
parseRuleValStrQT_DS_1_QT, // val/str/enum
parseRuleValStrQT_DS_5_QT, // val/str/enum
parseRuleValStrQT_DS_7_QT, // val/str/enum
parseRuleValStrQT_FS_tmp_FS_pgbackrest_QT, // val/str/enum
parseRuleValStrQT_FS_var_FS_lib_FS_pgbackrest_QT, // val/str/enum
parseRuleValStrQT_FS_var_FS_log_FS_pgbackrest_QT, // val/str/enum
@@ -168,6 +176,7 @@ typedef enum
parseRuleValStrQT_256_QT, // val/str/enum
parseRuleValStrQT_256KiB_QT, // val/str/enum
parseRuleValStrQT_2MiB_QT, // val/str/enum
parseRuleValStrQT_3_QT, // val/str/enum
parseRuleValStrQT_30m_QT, // val/str/enum
parseRuleValStrQT_31m_QT, // val/str/enum
parseRuleValStrQT_32_QT, // val/str/enum
@@ -179,12 +188,15 @@ typedef enum
parseRuleValStrQT_4PiB_QT, // val/str/enum
parseRuleValStrQT_512KiB_QT, // val/str/enum
parseRuleValStrQT_5432_QT, // val/str/enum
parseRuleValStrQT_5MiB_QT, // val/str/enum
parseRuleValStrQT_6_QT, // val/str/enum
parseRuleValStrQT_64KiB_QT, // val/str/enum
parseRuleValStrQT_65535_QT, // val/str/enum
parseRuleValStrQT_7d_QT, // val/str/enum
parseRuleValStrQT_8432_QT, // val/str/enum
parseRuleValStrQT_8KiB_QT, // val/str/enum
parseRuleValStrQT_8MiB_QT, // val/str/enum
parseRuleValStrQT_9_QT, // val/str/enum
parseRuleValStrQT_900_QT, // val/str/enum
parseRuleValStrQT_999_QT, // val/str/enum
parseRuleValStrQT_9999999_QT, // val/str/enum
@@ -463,10 +475,15 @@ Rule Ints
static const int parseRuleValueInt[] =
{
-7, // val/int
-5, // val/int
-1, // val/int
0, // val/int
1, // val/int
2, // val/int
3, // val/int
6, // val/int
9, // val/int
12, // val/int
22, // val/int
32, // val/int
@@ -485,10 +502,15 @@ static const int parseRuleValueInt[] =
static const uint8_t parseRuleValueIntStrMap[] =
{
parseRuleValStrQT_DS_7_QT, // val/int/strmap
parseRuleValStrQT_DS_5_QT, // val/int/strmap
parseRuleValStrQT_DS_1_QT, // val/int/strmap
parseRuleValStrQT_0_QT, // val/int/strmap
parseRuleValStrQT_1_QT, // val/int/strmap
parseRuleValStrQT_2_QT, // val/int/strmap
parseRuleValStrQT_3_QT, // val/int/strmap
parseRuleValStrQT_6_QT, // val/int/strmap
parseRuleValStrQT_9_QT, // val/int/strmap
parseRuleValStrQT_12_QT, // val/int/strmap
parseRuleValStrQT_22_QT, // val/int/strmap
parseRuleValStrQT_32_QT, // val/int/strmap
@@ -507,10 +529,15 @@ static const uint8_t parseRuleValueIntStrMap[] =
typedef enum
{
parseRuleValIntDS_7, // val/int/enum
parseRuleValIntDS_5, // val/int/enum
parseRuleValIntDS_1, // val/int/enum
parseRuleValInt0, // val/int/enum
parseRuleValInt1, // val/int/enum
parseRuleValInt2, // val/int/enum
parseRuleValInt3, // val/int/enum
parseRuleValInt6, // val/int/enum
parseRuleValInt9, // val/int/enum
parseRuleValInt12, // val/int/enum
parseRuleValInt22, // val/int/enum
parseRuleValInt32, // val/int/enum
@@ -546,6 +573,7 @@ static const int64_t parseRuleValueSize[] =
1048576, // val/size
2097152, // val/size
4194304, // val/size
5242880, // val/size
8388608, // val/size
16777216, // val/size
20971520, // val/size
@@ -570,6 +598,7 @@ static const uint8_t parseRuleValueSizeStrMap[] =
parseRuleValStrQT_1MiB_QT, // val/size/strmap
parseRuleValStrQT_2MiB_QT, // val/size/strmap
parseRuleValStrQT_4MiB_QT, // val/size/strmap
parseRuleValStrQT_5MiB_QT, // val/size/strmap
parseRuleValStrQT_8MiB_QT, // val/size/strmap
parseRuleValStrQT_16MiB_QT, // val/size/strmap
parseRuleValStrQT_20MiB_QT, // val/size/strmap
@@ -594,6 +623,7 @@ typedef enum
parseRuleValSize1MiB, // val/size/enum
parseRuleValSize2MiB, // val/size/enum
parseRuleValSize4MiB, // val/size/enum
parseRuleValSize5MiB, // val/size/enum
parseRuleValSize8MiB, // val/size/enum
parseRuleValSize16MiB, // val/size/enum
parseRuleValSize20MiB, // val/size/enum
@@ -1821,6 +1851,56 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
PARSE_RULE_OPTION_COMMAND_ROLE_ASYNC_VALID_LIST // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTION_COMMAND(ArchivePush) // opt/compress-level
), // opt/compress-level
// opt/compress-level
PARSE_RULE_OPTIONAL // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTIONAL_GROUP // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTIONAL_DEPEND // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_INT(0)), // opt/compress-level
PARSE_RULE_VAL_OPT(CompressType), // opt/compress-level
PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level
PARSE_RULE_VAL_STRID(Gz), // opt/compress-level
PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level
PARSE_RULE_VAL_STRID(Zst), // opt/compress-level
), // opt/compress-level
// opt/compress-level
PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP // opt/compress-level
( // opt/compress-level
PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level
PARSE_RULE_VAL_INT(1), // opt/compress-level
PARSE_RULE_VAL_INT(9), // opt/compress-level
PARSE_RULE_VAL_STRID(Gz), // opt/compress-level
PARSE_RULE_VAL_INT(DS_1), // opt/compress-level
PARSE_RULE_VAL_INT(9), // opt/compress-level
PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level
PARSE_RULE_VAL_INT(DS_5), // opt/compress-level
PARSE_RULE_VAL_INT(12), // opt/compress-level
PARSE_RULE_VAL_STRID(Zst), // opt/compress-level
PARSE_RULE_VAL_INT(DS_7), // opt/compress-level
PARSE_RULE_VAL_INT(22), // opt/compress-level
), // opt/compress-level
), // opt/compress-level
// opt/compress-level
PARSE_RULE_OPTIONAL_DEFAULT // opt/compress-level
( // opt/compress-level
PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/compress-level
( // opt/compress-level
PARSE_RULE_VAL_STRID(Bz2), // opt/compress-level
PARSE_RULE_VAL_INT(9), // opt/compress-level
PARSE_RULE_VAL_STRID(Gz), // opt/compress-level
PARSE_RULE_VAL_INT(6), // opt/compress-level
PARSE_RULE_VAL_STRID(Lz4), // opt/compress-level
PARSE_RULE_VAL_INT(1), // opt/compress-level
PARSE_RULE_VAL_STRID(Zst), // opt/compress-level
PARSE_RULE_VAL_INT(3), // opt/compress-level
), // opt/compress-level
), // opt/compress-level
), // opt/compress-level
), // opt/compress-level
), // opt/compress-level
// -----------------------------------------------------------------------------------------------------------------------------
@@ -4138,13 +4218,24 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/pg-host-port
PARSE_RULE_OPTIONAL_DEPEND // opt/pg-host-port
( // opt/pg-host-port
PARSE_RULE_VAL_OPT(PgHost), // opt/pg-host-port
PARSE_RULE_VAL_OPT(PgHostType), // opt/pg-host-port
PARSE_RULE_VAL_STRID(Ssh), // opt/pg-host-port
PARSE_RULE_VAL_STRID(Tls), // opt/pg-host-port
), // opt/pg-host-port
// opt/pg-host-port
PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/pg-host-port
( // opt/pg-host-port
PARSE_RULE_VAL_INT(0), // opt/pg-host-port
PARSE_RULE_VAL_INT(65535), // opt/pg-host-port
), // opt/pg-host-port
// opt/pg-host-port
PARSE_RULE_OPTIONAL_DEFAULT // opt/pg-host-port
( // opt/pg-host-port
PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/pg-host-port
( // opt/pg-host-port
PARSE_RULE_VAL_STRID(Tls), // opt/pg-host-port
PARSE_RULE_VAL_INT(8432), // opt/pg-host-port
), // opt/pg-host-port
), // opt/pg-host-port
), // opt/pg-host-port
), // opt/pg-host-port
@@ -6955,13 +7046,24 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/repo-host-port
PARSE_RULE_OPTIONAL_DEPEND // opt/repo-host-port
( // opt/repo-host-port
PARSE_RULE_VAL_OPT(RepoHost), // opt/repo-host-port
PARSE_RULE_VAL_OPT(RepoHostType), // opt/repo-host-port
PARSE_RULE_VAL_STRID(Ssh), // opt/repo-host-port
PARSE_RULE_VAL_STRID(Tls), // opt/repo-host-port
), // opt/repo-host-port
// opt/repo-host-port
PARSE_RULE_OPTIONAL_ALLOW_RANGE // opt/repo-host-port
( // opt/repo-host-port
PARSE_RULE_VAL_INT(0), // opt/repo-host-port
PARSE_RULE_VAL_INT(65535), // opt/repo-host-port
), // opt/repo-host-port
// opt/repo-host-port
PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-host-port
( // opt/repo-host-port
PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/repo-host-port
( // opt/repo-host-port
PARSE_RULE_VAL_STRID(Tls), // opt/repo-host-port
PARSE_RULE_VAL_INT(8432), // opt/repo-host-port
), // opt/repo-host-port
), // opt/repo-host-port
), // opt/repo-host-port
), // opt/repo-host-port
@@ -9722,6 +9824,19 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
( // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_SIZE(64KiB), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_SIZE(1TiB), // opt/repo-storage-upload-chunk-size
), // opt/repo-storage-upload-chunk-size
// opt/repo-storage-upload-chunk-size
PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-storage-upload-chunk-size
( // opt/repo-storage-upload-chunk-size
PARSE_RULE_OPTIONAL_DEFAULT_MAP // opt/repo-storage-upload-chunk-size
( // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_STRID(Azure), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_SIZE(4MiB), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_STRID(Gcs), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_SIZE(4MiB), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_STRID(S3), // opt/repo-storage-upload-chunk-size
PARSE_RULE_VAL_SIZE(5MiB), // opt/repo-storage-upload-chunk-size
), // opt/repo-storage-upload-chunk-size
), // opt/repo-storage-upload-chunk-size
), // opt/repo-storage-upload-chunk-size
), // opt/repo-storage-upload-chunk-size
@@ -11377,7 +11492,6 @@ static const uint8_t optionResolveOrder[] =
cfgOptCmd, // opt-resolve-order
cfgOptCmdSsh, // opt-resolve-order
cfgOptCompress, // opt-resolve-order
cfgOptCompressLevel, // opt-resolve-order
cfgOptCompressLevelNetwork, // opt-resolve-order
cfgOptCompressType, // opt-resolve-order
cfgOptConfig, // opt-resolve-order
@@ -11469,6 +11583,7 @@ static const uint8_t optionResolveOrder[] =
cfgOptArchiveCheck, // opt-resolve-order
cfgOptArchiveCopy, // opt-resolve-order
cfgOptArchiveModeCheck, // opt-resolve-order
cfgOptCompressLevel, // opt-resolve-order
cfgOptForce, // opt-resolve-order
cfgOptPgDatabase, // opt-resolve-order
cfgOptPgHost, // opt-resolve-order
@@ -11476,7 +11591,6 @@ static const uint8_t optionResolveOrder[] =
cfgOptPgHostConfig, // opt-resolve-order
cfgOptPgHostConfigIncludePath, // opt-resolve-order
cfgOptPgHostConfigPath, // opt-resolve-order
cfgOptPgHostPort, // opt-resolve-order
cfgOptPgHostType, // opt-resolve-order
cfgOptPgHostUser, // opt-resolve-order
cfgOptRecoveryOption, // opt-resolve-order
@@ -11499,7 +11613,6 @@ static const uint8_t optionResolveOrder[] =
cfgOptRepoHostConfig, // opt-resolve-order
cfgOptRepoHostConfigIncludePath, // opt-resolve-order
cfgOptRepoHostConfigPath, // opt-resolve-order
cfgOptRepoHostPort, // opt-resolve-order
cfgOptRepoHostType, // opt-resolve-order
cfgOptRepoHostUser, // opt-resolve-order
cfgOptRepoS3Bucket, // opt-resolve-order
@@ -11536,6 +11649,7 @@ static const uint8_t optionResolveOrder[] =
cfgOptPgHostCaPath, // opt-resolve-order
cfgOptPgHostCertFile, // opt-resolve-order
cfgOptPgHostKeyFile, // opt-resolve-order
cfgOptPgHostPort, // opt-resolve-order
cfgOptRepoGcsBucket, // opt-resolve-order
cfgOptRepoGcsEndpoint, // opt-resolve-order
cfgOptRepoGcsKey, // opt-resolve-order
@@ -11543,6 +11657,7 @@ static const uint8_t optionResolveOrder[] =
cfgOptRepoHostCaPath, // opt-resolve-order
cfgOptRepoHostCertFile, // opt-resolve-order
cfgOptRepoHostKeyFile, // opt-resolve-order
cfgOptRepoHostPort, // opt-resolve-order
cfgOptRepoS3Key, // opt-resolve-order
cfgOptRepoS3KeySecret, // opt-resolve-order
cfgOptRepoSftpHostFingerprint, // opt-resolve-order

View File

@@ -252,13 +252,17 @@ typedef enum
#define PARSE_RULE_OPTIONAL_DEPEND(...) \
PARSE_RULE_U32_1(parseRuleOptionalTypeValid), PARSE_RULE_PACK_SIZE(__VA_ARGS__)
#define PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(value) value
#define PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(value) PARSE_RULE_BOOL_TRUE, value
#define PARSE_RULE_OPTIONAL_ALLOW_LIST(...) \
PARSE_RULE_U32_1(parseRuleOptionalTypeAllowList), PARSE_RULE_PACK_SIZE(__VA_ARGS__)
#define PARSE_RULE_OPTIONAL_ALLOW_RANGE(...) \
PARSE_RULE_U32_1(parseRuleOptionalTypeAllowRange), PARSE_RULE_PACK_SIZE(__VA_ARGS__)
#define PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP(...) \
0x10, __VA_ARGS__ 0x00
#define PARSE_RULE_OPTIONAL_DEFAULT(...) \
PARSE_RULE_U32_1(parseRuleOptionalTypeDefault), PARSE_RULE_PACK_SIZE(__VA_ARGS__)
#define PARSE_RULE_OPTIONAL_DEFAULT_MAP(...) \
0x10, __VA_ARGS__ 0x00
#define PARSE_RULE_OPTIONAL_REQUIRED(...) \
PARSE_RULE_U32_1(parseRuleOptionalTypeRequired), PARSE_RULE_PACK_SIZE(__VA_ARGS__)
#define PARSE_RULE_OPTIONAL_NOT_REQUIRED(...) PARSE_RULE_OPTIONAL_REQUIRED(__VA_ARGS__)
@@ -889,6 +893,65 @@ cfgParseOptionValue(const ConfigOptionType type, unsigned int valueIdx)
FUNCTION_TEST_RETURN(INT64, parseRuleValueTime[valueIdx]);
}
/***********************************************************************************************************************************
Get default value from pack
***********************************************************************************************************************************/
static void
cfgParseOptionValuePack(PackRead *const ruleData, const ConfigOptionType type, ConfigOptionValueType *value, const String **raw)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(PACK_READ, ruleData);
FUNCTION_TEST_PARAM(ENUM, type);
FUNCTION_TEST_PARAM_P(VOID, value);
FUNCTION_TEST_PARAM_PP(VOID, raw);
FUNCTION_TEST_END();
switch (pckReadType(ruleData))
{
case pckTypeBool:
{
value->boolean = pckReadBoolP(ruleData);
if (raw != NULL)
*raw = value->boolean ? Y_STR : N_STR;
break;
}
default:
{
const unsigned int valueIdx = pckReadU32P(ruleData);
switch (type)
{
case cfgOptTypeInteger:
case cfgOptTypeSize:
case cfgOptTypeTime:
value->integer = cfgParseOptionValue(type, valueIdx);
break;
case cfgOptTypePath:
case cfgOptTypeString:
value->string = cfgParseOptionValueStr(type, valueIdx);
break;
default:
{
ASSERT(type == cfgOptTypeStringId);
value->stringId = parseRuleValueStrId[valueIdx];
break;
}
}
if (raw != NULL)
*raw = cfgParseOptionValueStr(type, valueIdx);
}
}
FUNCTION_TEST_RETURN_VOID();
}
/***********************************************************************************************************************************
Find an optional rule
***********************************************************************************************************************************/
@@ -901,12 +964,14 @@ typedef struct CfgParseOptionalRuleState
// Valid
const uint8_t *valid;
size_t validSize;
unsigned int matchValue;
// Allow range
int64_t allowRangeMin;
int64_t allowRangeMax;
unsigned int allowRangeMinIdx;
unsigned int allowRangeMaxIdx;
bool allowRangeMatch;
// Allow list
const uint8_t *allowList;
@@ -940,6 +1005,7 @@ cfgParseOptionalRule(
ASSERT(optionId < CFG_OPTION_TOTAL);
bool result = false;
bool match = false;
// Check for optional rules
const ParseRuleOption *const ruleOption = &parseRuleOption[optionId];
@@ -1038,8 +1104,9 @@ cfgParseOptionalRule(
// If this is the requested optional rule
if (optionalRules->typeNext == optionalRuleType)
{
// Optional rule was found
// Optional rule was found and dependency was matched
result = true;
match = true;
// Process optional rule
switch (optionalRuleType)
@@ -1070,8 +1137,33 @@ cfgParseOptionalRule(
{
PackRead *const ruleData = pckReadPackReadConstP(optionalRules->pack);
optionalRules->allowRangeMinIdx = pckReadU32P(ruleData);
optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData);
pckReadNext(ruleData);
if (pckReadType(ruleData) == pckTypeArray)
{
pckReadArrayBeginP(ruleData);
while (!pckReadNullP(ruleData)) // {uncovered_branch - no options with partial allow range maps}
{
const unsigned int map = pckReadU32P(ruleData);
optionalRules->allowRangeMinIdx = pckReadU32P(ruleData);
optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData);
if (map == optionalRules->matchValue)
{
optionalRules->allowRangeMatch = true;
break;
}
}
match = optionalRules->allowRangeMatch;
}
else
{
optionalRules->allowRangeMinIdx = pckReadU32P(ruleData);
optionalRules->allowRangeMaxIdx = pckReadU32P(ruleData);
}
optionalRules->allowRangeMin = cfgParseOptionValue(ruleOption->type, optionalRules->allowRangeMinIdx);
optionalRules->allowRangeMax = cfgParseOptionValue(ruleOption->type, optionalRules->allowRangeMaxIdx);
@@ -1098,38 +1190,30 @@ cfgParseOptionalRule(
pckReadNext(ruleData);
switch (pckReadType(ruleData))
if (pckReadType(ruleData) == pckTypeArray)
{
case pckTypeBool:
optionalRules->defaultValue.boolean = pckReadBoolP(ruleData);
optionalRules->defaultRaw = optionalRules->defaultValue.boolean ? Y_STR : N_STR;
break;
pckReadArrayBeginP(ruleData);
match = false;
default:
while (!pckReadNullP(ruleData))
{
const unsigned int valueIdx = pckReadU32P(ruleData);
const unsigned int map = pckReadU32P(ruleData);
switch (ruleOption->type)
cfgParseOptionValuePack(
ruleData, ruleOption->type, &optionalRules->defaultValue, &optionalRules->defaultRaw);
if (map == optionalRules->matchValue)
{
case cfgOptTypeInteger:
case cfgOptTypeSize:
case cfgOptTypeTime:
optionalRules->defaultValue.integer = cfgParseOptionValue(ruleOption->type, valueIdx);
break;
case cfgOptTypePath:
case cfgOptTypeString:
optionalRules->defaultValue.string = cfgParseOptionValueStr(ruleOption->type, valueIdx);
break;
case cfgOptTypeStringId:
optionalRules->defaultValue.stringId = parseRuleValueStrId[valueIdx];
break;
match = true;
break;
}
optionalRules->defaultRaw = cfgParseOptionValueStr(ruleOption->type, valueIdx);
}
}
else
{
cfgParseOptionValuePack(
ruleData, ruleOption->type, &optionalRules->defaultValue, &optionalRules->defaultRaw);
}
}
break;
@@ -1160,7 +1244,7 @@ cfgParseOptionalRule(
while (!result);
}
FUNCTION_TEST_RETURN(BOOL, result);
FUNCTION_TEST_RETURN(BOOL, result && match);
}
/***********************************************************************************************************************************
@@ -1168,16 +1252,20 @@ Resolve an option dependency
***********************************************************************************************************************************/
typedef struct CfgParseOptionalFilterDependResult
{
bool valid;
bool defaultExists;
bool defaultValue;
bool valid; // Is the dependency valid?
bool defaultExists; // Is there a default of the dependency is not valid?
ConfigOption dependId; // Option id for the dependency
ConfigOptionValueType defaultValue; // Default value if dependency is not valid
unsigned int matchValue; // Match value if the dependency is valid
} CfgParseOptionalFilterDependResult;
static CfgParseOptionalFilterDependResult
cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config, const unsigned int optionListIdx)
cfgParseOptionalFilterDepend(
PackRead *const filter, const ConfigOptionType optionType, const Config *const config, const unsigned int optionListIdx)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(PACK_READ, filter);
FUNCTION_TEST_PARAM(ENUM, optionType);
FUNCTION_TEST_PARAM_P(VOID, config);
FUNCTION_TEST_PARAM(UINT, optionListIdx);
FUNCTION_TEST_END();
@@ -1189,15 +1277,19 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config,
if (pckReadType(filter) == pckTypeBool)
{
pckReadBoolP(filter);
pckReadNext(filter);
result.defaultExists = true;
result.defaultValue = pckReadBoolP(filter);
cfgParseOptionValuePack(filter, optionType, &result.defaultValue, NULL);
}
// Get the depend option value
const ConfigOption dependId = (ConfigOption)pckReadU32P(filter);
ASSERT(config->option[dependId].index != NULL);
result.dependId = (ConfigOption)pckReadU32P(filter);
ASSERT(config->option[result.dependId].index != NULL);
const ConfigOptionValue *const dependValue =
&config->option[dependId].index[parseRuleOption[dependId].group ? optionListIdx : 0];
&config->option[result.dependId].index[parseRuleOption[result.dependId].group ? optionListIdx : 0];
// Is the dependency resolved?
if (dependValue->set)
@@ -1207,7 +1299,7 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config,
{
do
{
switch (cfgParseOptionDataType(dependId))
switch (cfgParseOptionDataType(result.dependId))
{
case cfgOptDataTypeBoolean:
result.valid = pckReadBoolP(filter) == dependValue->value.boolean;
@@ -1215,13 +1307,18 @@ cfgParseOptionalFilterDepend(PackRead *const filter, const Config *const config,
default:
{
ASSERT(cfgParseOptionDataType(dependId) == cfgOptDataTypeStringId);
ASSERT(cfgParseOptionDataType(result.dependId) == cfgOptDataTypeStringId);
result.matchValue = pckReadU32P(filter);
if (parseRuleValueStrId[pckReadU32P(filter)] == dependValue->value.stringId)
if (parseRuleValueStrId[result.matchValue] == dependValue->value.stringId)
result.valid = true;
break;
}
}
if (result.valid)
break;
}
while (pckReadNext(filter));
}
@@ -2286,11 +2383,14 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
// Is the option valid?
CfgParseOptionalRuleState optionalRules = {.defaultDynamicBin = config->bin};
CfgParseOptionalFilterDependResult dependResult = {.valid = true};
const char *dependOptionName = NULL;
if (cfgParseOptionalRule(&optionalRules, parseRuleOptionalTypeValid, config->command, optionId))
{
PackRead *const filter = pckReadNewC(optionalRules.valid, optionalRules.validSize);
dependResult = cfgParseOptionalFilterDepend(filter, config, optionListIdx);
dependResult = cfgParseOptionalFilterDepend(filter, optionType, config, optionListIdx);
dependOptionName = cfgParseOptionKeyIdxName(
dependResult.dependId, parseRuleOption[dependResult.dependId].group ? optionKeyIdx : 0);
// If depend not resolved and option value is set on the command-line then error. It is OK to have unresolved
// options in the config file because they may be there for another command. For instance, spool-path is only
@@ -2304,12 +2404,13 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
pckReadNext(filter);
if (pckReadType(filter) == pckTypeBool)
{
pckReadBoolP(filter);
pckReadConsume(filter);
}
// Get depend option id and name
const ConfigOption dependId = pckReadU32P(filter);
const String *dependOptionName = STR(
cfgParseOptionKeyIdxName(dependId, parseRuleOption[dependId].group ? optionKeyIdx : 0));
// If depend value is not set
ASSERT(config->option[dependId].index != NULL);
@@ -2318,7 +2419,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
{
THROW_FMT(
OptionInvalidError, "option '%s' not valid without option '%s'",
cfgParseOptionKeyIdxName(optionId, optionKeyIdx), strZ(dependOptionName));
cfgParseOptionKeyIdxName(optionId, optionKeyIdx), dependOptionName);
}
// Build type dependent error data
@@ -2329,7 +2430,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
case cfgOptTypeBoolean:
{
if (!pckReadBoolP(filter))
dependOptionName = strNewFmt("no-%s", strZ(dependOptionName));
dependOptionName = zNewFmt("no-%s", dependOptionName);
break;
}
@@ -2359,9 +2460,12 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
THROW_FMT(
OptionInvalidError, "option '%s' not valid without option '%s'%s",
cfgParseOptionKeyIdxName(optionId, optionKeyIdx), strZ(dependOptionName), strZ(errorValue));
cfgParseOptionKeyIdxName(optionId, optionKeyIdx), dependOptionName, strZ(errorValue));
}
// Store the match value in case we need it to find the default, range, etc.
optionalRules.matchValue = dependResult.matchValue;
pckReadFree(filter);
}
@@ -2482,9 +2586,14 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
{
THROW_FMT(
OptionInvalidValueError,
"'%s' is out of range for '%s' option\n"
"'%s' is out of range for '%s' option%s\n"
"HINT: allowed range is %s to %s inclusive",
strZ(value), cfgParseOptionKeyIdxName(optionId, optionKeyIdx),
optionalRules.allowRangeMatch ?
zNewFmt(
" when '%s' option = '%s'", dependOptionName,
strZ(cfgParseOptionValueStr(cfgOptTypeStringId, optionalRules.matchValue))) :
"",
strZ(cfgParseOptionValueStr(optionType, optionalRules.allowRangeMinIdx)),
strZ(cfgParseOptionValueStr(optionType, optionalRules.allowRangeMaxIdx)));
}
@@ -2651,7 +2760,7 @@ cfgParse(const Storage *const storage, const unsigned int argListSize, const cha
else if (dependResult.defaultExists)
{
configOptionValue->set = true;
configOptionValue->value.boolean = dependResult.defaultValue;
configOptionValue->value = dependResult.defaultValue;
configOptionValue->defaultValue = optionalRules.defaultRaw;
configOptionValue->display = optionalRules.defaultRaw;
}

View File

@@ -1315,10 +1315,6 @@ src/common/compress/helper.h:
class: core
type: c/h
src/common/compress/helper.intern.h:
class: core
type: c/h
src/common/compress/lz4/common.c:
class: core
type: c

View File

@@ -238,7 +238,7 @@ testRun(void)
" option: config\n"
" default: false\n");
TEST_ERROR(bldCfgParse(storageTest), FormatError, "dependency default invalid for non-boolean option 'stanza'");
TEST_ERROR(bldCfgParse(storageTest), FormatError, "dependency default invalid for non integer/boolean option 'stanza'");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("parse and render config");
@@ -321,6 +321,10 @@ testRun(void)
" section: global\n"
" type: string\n"
" default: gz\n"
" allow-list:\n"
" - none\n"
" - bz2\n"
" - gz\n"
" command:\n"
" backup: {}\n"
" archive-get:\n"
@@ -334,9 +338,19 @@ testRun(void)
" section: global\n"
" type: integer\n"
" required: false\n"
" allow-range: [-1, 9]\n"
" default:\n"
" - bz2: 9\n"
" - gz: 6\n"
" allow-range:\n"
" - bz2: [1, 9]\n"
" - gz: [-1, 9]\n"
" depend:\n"
" option: compress-type\n"
" default: 0\n"
" list:\n"
" - bz2\n"
" - gz\n"
" command: compress-type\n"
" depend: compress-type\n"
"\n"
" compress-level-network:\n"
" inherit: compress-level\n"
@@ -449,6 +463,16 @@ testRun(void)
" deprecate:\n"
" backup-standby-old: {}\n"
"\n"
" backup-copy:\n"
" section: global\n"
" type: boolean\n"
" default: false\n"
" depend: backup-standby\n"
" command:\n"
" backup: {}\n"
" command-role:\n"
" main: {}\n"
"\n"
" pg-path:\n"
" section: stanza\n"
" group: pg\n"
@@ -509,6 +533,7 @@ testRun(void)
COMMENT_BLOCK_BEGIN "\n"
"Option constants\n"
COMMENT_BLOCK_END "\n"
"#define CFGOPT_BACKUP_COPY \"backup-copy\"\n"
"#define CFGOPT_BACKUP_STANDBY \"backup-standby\"\n"
"#define CFGOPT_BOOL_LIKE \"bool-like\"\n"
"#define CFGOPT_BUFFER_SIZE \"buffer-size\"\n"
@@ -525,7 +550,7 @@ testRun(void)
"#define CFGOPT_STANZA \"stanza\"\n"
"#define CFGOPT_TIMEOUT \"timeout\"\n"
"\n"
"#define CFG_OPTION_TOTAL 17\n"
"#define CFG_OPTION_TOTAL 18\n"
"\n"
COMMENT_BLOCK_BEGIN "\n"
"Option value constants\n"
@@ -583,6 +608,7 @@ testRun(void)
COMMENT_BLOCK_END "\n"
"typedef enum\n"
"{\n"
" cfgOptBackupCopy,\n"
" cfgOptBackupStandby,\n"
" cfgOptBoolLike,\n"
" cfgOptBufferSize,\n"
@@ -625,14 +651,17 @@ testRun(void)
"{\n"
" PARSE_RULE_STRPUB(\"-1\"),\n"
" PARSE_RULE_STRPUB(\"/include\"),\n"
" PARSE_RULE_STRPUB(\"1\"),\n"
" PARSE_RULE_STRPUB(\"100ms\"),\n"
" PARSE_RULE_STRPUB(\"10s\"),\n"
" PARSE_RULE_STRPUB(\"16KiB\"),\n"
" PARSE_RULE_STRPUB(\"30m\"),\n"
" PARSE_RULE_STRPUB(\"32KiB\"),\n"
" PARSE_RULE_STRPUB(\"6\"),\n"
" PARSE_RULE_STRPUB(\"7w\"),\n"
" PARSE_RULE_STRPUB(\"8KiB\"),\n"
" PARSE_RULE_STRPUB(\"9\"),\n"
" PARSE_RULE_STRPUB(\"bz2\"),\n"
" PARSE_RULE_STRPUB(\"check\"),\n"
" PARSE_RULE_STRPUB(\"debug1\"),\n"
" PARSE_RULE_STRPUB(\"error\"),\n"
@@ -640,6 +669,7 @@ testRun(void)
" PARSE_RULE_STRPUB(\"host1\"),\n"
" PARSE_RULE_STRPUB(\"info\"),\n"
" PARSE_RULE_STRPUB(\"n\"),\n"
" PARSE_RULE_STRPUB(\"none\"),\n"
" PARSE_RULE_STRPUB(\"off\"),\n"
" PARSE_RULE_STRPUB(\"warn\"),\n"
" PARSE_RULE_STRPUB(\"y\"),\n"
@@ -651,14 +681,17 @@ testRun(void)
"{\n"
" parseRuleValStrQT_DS_1_QT,\n"
" parseRuleValStrQT_FS_include_QT,\n"
" parseRuleValStrQT_1_QT,\n"
" parseRuleValStrQT_100ms_QT,\n"
" parseRuleValStrQT_10s_QT,\n"
" parseRuleValStrQT_16KiB_QT,\n"
" parseRuleValStrQT_30m_QT,\n"
" parseRuleValStrQT_32KiB_QT,\n"
" parseRuleValStrQT_6_QT,\n"
" parseRuleValStrQT_7w_QT,\n"
" parseRuleValStrQT_8KiB_QT,\n"
" parseRuleValStrQT_9_QT,\n"
" parseRuleValStrQT_bz2_QT,\n"
" parseRuleValStrQT_check_QT,\n"
" parseRuleValStrQT_debug1_QT,\n"
" parseRuleValStrQT_error_QT,\n"
@@ -666,6 +699,7 @@ testRun(void)
" parseRuleValStrQT_host1_QT,\n"
" parseRuleValStrQT_info_QT,\n"
" parseRuleValStrQT_n_QT,\n"
" parseRuleValStrQT_none_QT,\n"
" parseRuleValStrQT_off_QT,\n"
" parseRuleValStrQT_warn_QT,\n"
" parseRuleValStrQT_y_QT,\n"
@@ -725,18 +759,24 @@ testRun(void)
"static const int parseRuleValueInt[] =\n"
"{\n"
" -1,\n"
" 1,\n"
" 6,\n"
" 9,\n"
"};\n"
"\n"
"static const uint8_t parseRuleValueIntStrMap[] =\n"
"{\n"
" parseRuleValStrQT_DS_1_QT,\n"
" parseRuleValStrQT_1_QT,\n"
" parseRuleValStrQT_6_QT,\n"
" parseRuleValStrQT_9_QT,\n"
"};\n"
"\n"
"typedef enum\n"
"{\n"
" parseRuleValIntDS_1,\n"
" parseRuleValInt1,\n"
" parseRuleValInt6,\n"
" parseRuleValInt9,\n"
"} ParseRuleValueInt;\n"
"\n"
@@ -897,6 +937,39 @@ testRun(void)
"{\n"
" PARSE_RULE_OPTION\n"
" (\n"
" PARSE_RULE_OPTION_NAME(\"backup-copy\"),\n"
" PARSE_RULE_OPTION_TYPE(Boolean),\n"
" PARSE_RULE_OPTION_NEGATE(true),\n"
" PARSE_RULE_OPTION_RESET(true),\n"
" PARSE_RULE_OPTION_REQUIRED(true),\n"
" PARSE_RULE_OPTION_SECTION(Global),\n"
"\n"
" PARSE_RULE_OPTION_COMMAND_ROLE_MAIN_VALID_LIST\n"
" (\n"
" PARSE_RULE_OPTION_COMMAND(Backup)\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL\n"
" (\n"
" PARSE_RULE_OPTIONAL_GROUP\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEPEND\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_BOOL_TRUE),\n"
" PARSE_RULE_VAL_OPT(Online),\n"
" PARSE_RULE_VAL_BOOL_TRUE,\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_VAL_BOOL_FALSE,\n"
" ),\n"
" ),\n"
" ),\n"
" ),\n"
COMMENT_SEPARATOR "\n"
" PARSE_RULE_OPTION\n"
" (\n"
" PARSE_RULE_OPTION_NAME(\"backup-standby\"),\n"
" PARSE_RULE_OPTION_TYPE(Boolean),\n"
" PARSE_RULE_OPTION_BETA(true),\n"
@@ -1094,17 +1167,61 @@ testRun(void)
"\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE\n"
" (\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" ),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEFAULT_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(6),\n"
" ),\n"
" ),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_GROUP\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEPEND\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEPEND_DEFAULT(PARSE_RULE_VAL_INT(0)),\n"
" PARSE_RULE_VAL_OPT(CompressType),\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE\n"
" (\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" ),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_OPTIONAL_DEFAULT_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(6),\n"
" ),\n"
" ),\n"
" ),\n"
" ),\n"
@@ -1158,8 +1275,15 @@ testRun(void)
"\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE\n"
" (\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" ),\n"
" ),\n"
" ),\n"
"\n"
@@ -1174,8 +1298,15 @@ testRun(void)
"\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE\n"
" (\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_OPTIONAL_ALLOW_RANGE_MAP\n"
" (\n"
" PARSE_RULE_VAL_STRID(Bz2),\n"
" PARSE_RULE_VAL_INT(1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" PARSE_RULE_VAL_STRID(Gz),\n"
" PARSE_RULE_VAL_INT(DS_1),\n"
" PARSE_RULE_VAL_INT(9),\n"
" ),\n"
" ),\n"
" ),\n"
" ),\n"
@@ -1233,6 +1364,13 @@ testRun(void)
" PARSE_RULE_VAL_OPT(Config),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_ALLOW_LIST\n"
" (\n"
" PARSE_RULE_VAL_STR(none),\n"
" PARSE_RULE_VAL_STR(bz2),\n"
" PARSE_RULE_VAL_STR(gz),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_VAL_STR(QT_gz_QT),\n"
@@ -1241,6 +1379,13 @@ testRun(void)
"\n"
" PARSE_RULE_OPTIONAL_GROUP\n"
" (\n"
" PARSE_RULE_OPTIONAL_ALLOW_LIST\n"
" (\n"
" PARSE_RULE_VAL_STR(none),\n"
" PARSE_RULE_VAL_STR(bz2),\n"
" PARSE_RULE_VAL_STR(gz),\n"
" ),\n"
"\n"
" PARSE_RULE_OPTIONAL_DEFAULT\n"
" (\n"
" PARSE_RULE_VAL_STR(QT_gz_QT),\n"
@@ -1768,9 +1913,10 @@ testRun(void)
" cfgOptPgHost,\n"
" cfgOptPgPath,\n"
" cfgOptTimeout,\n"
" cfgOptBackupCopy,\n"
" cfgOptBackupStandby,\n"
" cfgOptCompressLevel,\n"
" cfgOptCompressType,\n"
" cfgOptCompressLevel,\n"
" cfgOptCompressLevelNetwork,\n"
"};\n");
}

View File

@@ -361,7 +361,6 @@ testRun(void)
" --repo-storage-port repository storage port\n"
" --repo-storage-tag repository storage tag(s)\n"
" --repo-storage-upload-chunk-size repository storage upload chunk size\n"
" [default=4194304]\n"
" --repo-storage-verify-tls repository storage certificate verify\n"
" --repo-target-time target time for repository\n"
" --repo-type type of storage used for the repository\n"
@@ -656,12 +655,6 @@ testRun(void)
"higher and because the chunk buffer must be allocated per process, larger\n" \
"process-max values will lead to more memory being consumed overall.\n" \
"\n" \
"Default chunk sizes by repo type:\n" \
"\n" \
"* azure - 4MiB\n" \
"* gcs - 4MiB\n" \
"* s3 - 5MiB\n" \
"\n" \
"Note that valid chunk sizes vary by storage type and by platform. For example,\n" \
"AWS S3 has a minimum chunk size of 5MiB but S3 clones may accept lower values.\n" \
"Terminology for chunk size varies by storage type, so when searching min/max\n" \
@@ -674,8 +667,8 @@ testRun(void)
HELP_OPTION_CHUNK
"\n"
"default:\n"
" repo1: 5242880\n"
" repo2: 4194304\n",
" repo1: 5MiB\n"
" repo2: 4MiB\n",
helpVersion);
argList = strLstNew();

View File

@@ -233,13 +233,6 @@ testRun(void)
TEST_ERROR(gzError(Z_VERSION_ERROR), FormatError, "zlib threw error: [-6] incompatible version");
TEST_ERROR(gzError(999), AssertError, "zlib threw error: [999] unknown error");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()");
TEST_RESULT_INT(compressLevelDefault(compressTypeGz), 6, "level default");
TEST_RESULT_INT(compressLevelMin(compressTypeGz), -1, "level default");
TEST_RESULT_INT(compressLevelMax(compressTypeGz), 9, "level default");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("gzDecompressToLog() and gzCompressToLog()");
@@ -282,13 +275,6 @@ testRun(void)
TEST_ERROR(bz2Error(BZ_CONFIG_ERROR), AssertError, "bz2 error: [-9] config error");
TEST_ERROR(bz2Error(-999), AssertError, "bz2 error: [-999] unknown error");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()");
TEST_RESULT_INT(compressLevelDefault(compressTypeBz2), 9, "level default");
TEST_RESULT_INT(compressLevelMin(compressTypeBz2), 1, "level default");
TEST_RESULT_INT(compressLevelMax(compressTypeBz2), 9, "level default");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("bz2DecompressToLog() and bz2CompressToLog()");
@@ -322,13 +308,6 @@ testRun(void)
TEST_RESULT_UINT(lz4Error(0), 0, "check success");
TEST_ERROR(lz4Error((size_t)-2), FormatError, "lz4 error: [-2] ERROR_maxBlockSize_invalid");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()");
TEST_RESULT_INT(compressLevelDefault(compressTypeLz4), 1, "level default");
TEST_RESULT_INT(compressLevelMin(compressTypeLz4), -5, "level default");
TEST_RESULT_INT(compressLevelMax(compressTypeLz4), 12, "level default");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("lz4DecompressToLog() and lz4CompressToLog()");
@@ -365,13 +344,6 @@ testRun(void)
TEST_RESULT_UINT(zstError(0), 0, "check success");
TEST_ERROR(zstError((size_t)-12), FormatError, "zst error: [-12] Version not supported");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("compressLevelDefault(), compressLevelMin(), and compressLevelMax()");
TEST_RESULT_INT(compressLevelDefault(compressTypeZst), 3, "level default");
TEST_RESULT_INT(compressLevelMin(compressTypeZst), -7, "level default");
TEST_RESULT_INT(compressLevelMax(compressTypeZst), 22, "level default");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("zstDecompressToLog() and zstCompressToLog()");

View File

@@ -501,39 +501,16 @@ testRun(void)
TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 9, "compress-level=9");
TEST_RESULT_BOOL(cfgOptionValid(cfgOptCompress), false, "compress is not valid");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("error on invalid compress level");
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptCompressType, "gz");
hrnCfgArgRawZ(argList, cfgOptCompressLevel, "-2");
TEST_ERROR(
hrnCfgLoadP(cfgCmdArchivePush, argList), OptionInvalidValueError,
"'-2' is out of range for 'compress-level' option when 'compress-type' option = 'gz'");
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptCompressType, "gz");
hrnCfgArgRawZ(argList, cfgOptCompressLevel, "10");
TEST_ERROR(
hrnCfgLoadP(cfgCmdArchivePush, argList), OptionInvalidValueError,
"'10' is out of range for 'compress-level' option when 'compress-type' option = 'gz'");
// In practice level should not be used here but preserve the prior behavior in case something depends on it
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("do not check range when compress-type = none");
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptCompressType, "none");
hrnCfgArgRawZ(argList, cfgOptCompressLevel, "3");
HRN_CFG_LOAD(cfgCmdArchivePush, argList);
TEST_RESULT_UINT(cfgOptionStrId(cfgOptCompressType), CFGOPTVAL_COMPRESS_TYPE_NONE, "compress-type=none");
TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 3, "compress-level=3");
TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 0, "compress-level=0");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("warn when compress-type and compress both set");

View File

@@ -1414,6 +1414,18 @@ testRun(void)
"'65536' is out of range for 'process-max' option\n"
"HINT: allowed range is 1 to 999 inclusive");
argList = strLstNew();
strLstAddZ(argList, TEST_BACKREST_EXE);
hrnCfgArgRawZ(argList, cfgOptPgPath, "/path/to/db");
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
hrnCfgArgRawZ(argList, cfgOptCompressType, "gz");
hrnCfgArgRawZ(argList, cfgOptCompressLevel, "-2");
strLstAddZ(argList, TEST_COMMAND_BACKUP);
TEST_ERROR(
cfgParseP(storageTest, strLstSize(argList), strLstPtr(argList), .noResetLogLevel = true), OptionInvalidValueError,
"'-2' is out of range for 'compress-level' option when 'compress-type' option = 'gz'\n"
"HINT: allowed range is -1 to 9 inclusive");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("character value when integer expected");
@@ -1840,7 +1852,7 @@ testRun(void)
BUFSTR(
strNewFmt(
"[global]\n"
"compress-level=3\n"
"compress-type=gz\n"
"spool-path=/path/to/spool\n"
"lock-path=/\n"
"pg1-path=/not/path/to/db\n"
@@ -1872,6 +1884,7 @@ testRun(void)
"%s=ignore\n"
"%s=/path/to/db2\n"
"pg3-host=ignore\n"
"repo1-host=ssh-host\n"
"recovery-option=c=d\n",
cfgParseOptionKeyIdxName(cfgOptPgHost, 1), cfgParseOptionKeyIdxName(cfgOptPgPath, 1))));
@@ -1912,6 +1925,8 @@ testRun(void)
TEST_RESULT_INT(cfgOptionSource(cfgOptPgPath), cfgSourceConfig, "pg1-path is source config");
TEST_RESULT_STR_Z(
cfgOptionIdxStr(cfgOptPgPath, cfgOptionKeyToIdx(cfgOptPgPath, 256)), "/path/to/db256", "pg256-path is set");
TEST_RESULT_STR_Z(cfgOptionIdxStr(cfgOptRepoHost, 0), "ssh-host", "repo1-host is set");
TEST_RESULT_BOOL(cfgOptionIdxTest(cfgOptRepoHostPort, 0), false, "repo1-host-port is not set for ssh");
TEST_RESULT_UINT(varUInt64(cfgOptionVar(cfgOptType)), STRID5("incr", 0x90dc90), "check type");
TEST_RESULT_STR_Z(
cfgOptionDisplayVar(VARUINT64(STRID5("incr", 0x90dc90)), cfgOptTypeStringId), "incr", "check type display");
@@ -1935,8 +1950,8 @@ testRun(void)
TEST_RESULT_INT(cfgOptionSource(cfgOptRepoHardlink), cfgSourceConfig, "repo-hardlink is source config");
TEST_RESULT_UINT(cfgOptionUInt(cfgOptRepoRetentionFull), 55, "repo-retention-full is set");
TEST_RESULT_INT(varInt64(cfgOptionVar(cfgOptRepoRetentionFull)), 55, "repo-retention-full as variant");
TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 3, "compress-level is set");
TEST_RESULT_INT(cfgOptionSource(cfgOptCompressLevel), cfgSourceConfig, "compress-level is source config");
TEST_RESULT_INT(cfgOptionInt(cfgOptCompressLevel), 6, "compress-level is set");
TEST_RESULT_INT(cfgOptionSource(cfgOptCompressLevel), cfgSourceDefault, "compress-level is source config");
TEST_RESULT_UINT(cfgOptionStrId(cfgOptBackupStandby), CFGOPTVAL_BACKUP_STANDBY_N, "backup-standby not is set");
TEST_RESULT_INT(cfgOptionSource(cfgOptBackupStandby), cfgSourceDefault, "backup-standby is source default");
TEST_RESULT_BOOL(cfgOptionIdxReset(cfgOptBackupStandby, 0), true, "backup-standby was reset");
@@ -2212,6 +2227,19 @@ testRun(void)
TEST_RESULT_VOID(cfgOptionIdxSet(cfgOptType, 0, cfgSourceParam, VARSTRDEF("standby")), "set type");
TEST_RESULT_UINT(cfgOptionIdxStrId(cfgOptType, 0), STRID5("standby", 0x6444706930), "check type");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("integer default when dependency invalid");
{
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test");
hrnCfgArgKeyRawZ(argList, cfgOptPgPath, 1, "/pg1");
hrnCfgEnvKeyRawZ(cfgOptRepoRetentionFull, 1, "1");
hrnCfgEnvRawZ(cfgOptCompressType, "none");
HRN_CFG_LOAD(cfgCmdBackup, argList);
TEST_RESULT_UINT(cfgOptionUInt(cfgOptCompressLevel), 0, "compress-level is 0");
}
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("stanza options should not be loaded for commands that don't take a stanza");

View File

@@ -77,6 +77,14 @@ testRun(void)
" default: 1024\n"
" allow-list: [512, 1024, 2048, 4096]\n"
"\n"
" buffer-size-range:\n"
" section: global\n"
" type: integer\n"
" default: 1024\n"
" allow-range: [512, 1024]\n"
" command:\n"
" backup: {}\n"
"\n"
" cmd:\n"
" section: global\n"
" type: string\n"
@@ -97,11 +105,34 @@ testRun(void)
" secure: true\n"
" default: false\n"
"\n"
" compress-type:\n"
" section: global\n"
" type: string-id\n"
" default: gz\n"
" allow-list:\n"
" - none\n"
" - bz2\n"
" - gz\n"
" command:\n"
" backup: {}\n"
" command-role: {}\n"
"\n"
" repo-compress-level:\n"
" group: repo\n"
" type: integer\n"
" default: 9\n"
" allow-range: [0, 9]\n"
" default:\n"
" - bz2: 9\n"
" - gz: 6\n"
" allow-range:\n"
" - bz2: [1, 9]\n"
" - gz: [-1, 9]\n"
" depend:\n"
" option: compress-type\n"
" default: 0\n"
" list:\n"
" - bz2\n"
" - gz\n"
" command:\n"
" backup: {}\n"
" deprecate:\n"
@@ -159,6 +190,11 @@ testRun(void)
" <example>256KiB</example>\n"
" </config-key>\n"
"\n"
" <config-key id=\"compress-type\" name=\"Compress Type\">\n"
" <summary>Compress type option command backup summary.</summary>\n"
" <text><p>Compress type option command backup description.</p></text>\n"
" </config-key>\n"
"\n"
" <config-key id=\"internal\" name=\"Internal\">\n"
" <summary>Internal option summary.</summary>\n"
" <text><p>Internal option description</p></text>\n"
@@ -197,6 +233,12 @@ testRun(void)
" <text><p>Backup command description.</p></text>\n"
"\n"
" <option-list>\n"
" <option id=\"buffer-size-range\" name=\"Buffer Size Range\">\n"
" <summary>Buffer size range option summary.</summary>\n"
" <text><p>Buffer size range option description.</p></text>\n"
" <example>512KiB</example>\n"
" </option>\n"
"\n"
" <option id=\"cmd\" name=\"Cmd\">\n"
" <summary>Cmd option command backup summary.</summary>\n"
" <text><p>Cmd option command backup description.</p></text>\n"
@@ -272,6 +314,12 @@ testRun(void)
"example: buffer-size=128KiB\n"
"example: buffer-size=256KiB</code-block>"
"</section>"
"<section id=\"option-compress-type\">"
"<title>Compress Type Option (<id>--compress-type</id>)</title>"
"<p>Compress type option command backup summary.</p>"
"<p>Compress type option command backup description.</p>"
"<code-block>default: gz</code-block>"
"</section>"
"<section id=\"option-secure\">"
"<title>Secure Option (<id>--secure</id>)</title>"
"<p>Secure option summary.</p>"
@@ -301,7 +349,15 @@ testRun(void)
"<p>Backup command description.</p>"
"<section id=\"category-command\" toc=\"n\">"
"<title>Command Options</title>"
"<section id=\"option-cmd\">"
"<section id=\"option-buffer-size-range\">"
"<title>Buffer Size Range Option (<id>--buffer-size-range</id>)</title>"
"<p>Buffer size range option summary.</p>"
"<p>Buffer size range option description.</p>"
"<code-block>default: 1024\n"
"allowed: [512, 1024]\n"
"example: --buffer-size-range=512KiB</code-block>"
"</section>"
"<section id=\"option-cmd\">"
"<title>Cmd Option (<id>--cmd</id>)</title>"
"<p>Cmd option command backup summary.</p>"
"<p>Cmd option command backup description.</p>"
@@ -320,8 +376,14 @@ testRun(void)
"<title>Repo Compress Level Backup Option (<id>--repo-compress-level</id>)</title>"
"<p>Repo compress level option command backup summary.</p>"
"<p>Repo compress level option command backup description.</p>"
"<code-block>default: 9\n"
"allowed: 0-9\n"
"<code-block>default (depending on compress-type):\n"
" bz2 - 9\n"
" gz - 6\n"
"\n"
"allow range (depending on compress-type):\n"
" bz2 - [1, 9]\n"
" gz - [-1, 9]\n"
"\n"
"example: --repo1-compress-level=4</code-block>"
"</section>"
"</section>"
@@ -391,12 +453,14 @@ testRun(void)
"\n"
"OPTIONS\n"
" Backup Options:\n"
" --buffer-size-range Buffer size range option summary.\n"
" --cmd Cmd option command backup summary.\n"
" --force Force option command backup summary.\n"
" --repo-compress-level Repo compress level option command backup summary.\n"
"\n"
" General Options:\n"
" --buffer-size Buffer size option summary.\n"
" --compress-type Compress type option command backup summary.\n"
" --config config option summary.\n"
" --secure Secure option summary.\n"
"\n"