mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Add cfgExecParam() to generate parameters for executing commands.
Parameters for the local/remote commands are based on parameters that are passed to the current command. Generate parameters for the new command based on the intersection of parameters between the current command and the command to be executed.
This commit is contained in:
parent
ecd56105e6
commit
06d41b4dc0
@ -33,6 +33,10 @@
|
||||
<p>Add <code>IoHandleRead</code> and <code>IoHandleWrite</code> objects.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>cfgExecParam()</code> to generate parameters for executing commands.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Ignore <id>SIGPIPE</id> signals and check <id>EPIPE</id> result instead.</p>
|
||||
</release-item>
|
||||
|
113
src/config/exec.c
Normal file
113
src/config/exec.c
Normal file
@ -0,0 +1,113 @@
|
||||
/***********************************************************************************************************************************
|
||||
Exec Configuration
|
||||
***********************************************************************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/log.h"
|
||||
#include "config/exec.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Load log settings
|
||||
***********************************************************************************************************************************/
|
||||
StringList *
|
||||
cfgExecParam(ConfigCommand commandId, const KeyValue *optionReplace)
|
||||
{
|
||||
FUNCTION_DEBUG_BEGIN(logLevelTrace);
|
||||
FUNCTION_DEBUG_PARAM(ENUM, commandId);
|
||||
FUNCTION_DEBUG_PARAM(KEY_VALUE, optionReplace);
|
||||
FUNCTION_DEBUG_END();
|
||||
|
||||
StringList *result = NULL;
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Loop though options and add the ones that apply to the specified command
|
||||
result = strLstNew();
|
||||
ConfigDefineCommand commandDefId = cfgCommandDefIdFromId(commandId);
|
||||
|
||||
for (ConfigOption optionId = 0; optionId < CFG_OPTION_TOTAL; optionId++)
|
||||
{
|
||||
ConfigDefineOption optionDefId = cfgOptionDefIdFromId(optionId);
|
||||
|
||||
// Skip the option if it is not valid for the specified command or if is secure
|
||||
if (!cfgDefOptionValid(commandDefId, optionDefId) || cfgDefOptionSecure(optionDefId))
|
||||
continue;
|
||||
|
||||
// First check for a replacement
|
||||
const Variant *value = NULL;
|
||||
|
||||
if (optionReplace != NULL)
|
||||
value = kvGet(optionReplace, varNewStr(strNew(cfgOptionName(optionId))));
|
||||
|
||||
// If no replacement then see if this option is valid for the current command and is not default
|
||||
if (value == NULL && cfgOptionValid(optionId))
|
||||
{
|
||||
if (cfgOptionNegate(optionId))
|
||||
value = varNewBool(false);
|
||||
else if (cfgOptionSource(optionId) != cfgSourceDefault)
|
||||
value = cfgOption(optionId);
|
||||
}
|
||||
|
||||
// Format the value if found
|
||||
if (value != NULL)
|
||||
{
|
||||
if (varType(value) == varTypeBool)
|
||||
{
|
||||
strLstAdd(result, strNewFmt("--%s%s", varBool(value) ? "" : "no-", cfgOptionName(optionId)));
|
||||
}
|
||||
else
|
||||
{
|
||||
StringList *valueList = NULL;
|
||||
|
||||
if (varType(value) == varTypeKeyValue)
|
||||
{
|
||||
valueList = strLstNew();
|
||||
|
||||
const KeyValue *optionKv = varKv(value);
|
||||
const VariantList *keyList = kvKeyList(optionKv);
|
||||
|
||||
for (unsigned int keyIdx = 0; keyIdx < varLstSize(keyList); keyIdx++)
|
||||
{
|
||||
strLstAdd(
|
||||
valueList,
|
||||
strNewFmt(
|
||||
"%s=%s", strPtr(varStr(varLstGet(keyList, keyIdx))),
|
||||
strPtr(varStrForce(kvGet(optionKv, varLstGet(keyList, keyIdx))))));
|
||||
}
|
||||
}
|
||||
else if (varType(value) == varTypeVariantList)
|
||||
{
|
||||
valueList = strLstNewVarLst(varVarLst(value));
|
||||
}
|
||||
// Else only one value
|
||||
else
|
||||
{
|
||||
valueList = strLstNew();
|
||||
strLstAdd(valueList, varStrForce(value));
|
||||
}
|
||||
|
||||
// Output options and values
|
||||
for (unsigned int valueListIdx = 0; valueListIdx < strLstSize(valueList); valueListIdx++)
|
||||
{
|
||||
const String *value = strLstGet(valueList, valueListIdx);
|
||||
|
||||
if (strchr(strPtr(value), ' ') != NULL)
|
||||
value = strNewFmt("\"%s\"", strPtr(value));
|
||||
|
||||
strLstAdd(result, strNewFmt("--%s=%s", cfgOptionName(optionId), strPtr(value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the requested command
|
||||
strLstAddZ(result, cfgCommandName(commandId));
|
||||
|
||||
// Move list to the calling context
|
||||
strLstMove(result, MEM_CONTEXT_OLD());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
FUNCTION_DEBUG_RESULT(STRING_LIST, result);
|
||||
}
|
15
src/config/exec.h
Normal file
15
src/config/exec.h
Normal file
@ -0,0 +1,15 @@
|
||||
/***********************************************************************************************************************************
|
||||
Exec Configuration
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef CONFIG_EXEC_H
|
||||
#define CONFIG_EXEC_H
|
||||
|
||||
#include "common/type/stringList.h"
|
||||
#include "config/config.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
StringList *cfgExecParam(ConfigCommand commandId, const KeyValue *optionReplace);
|
||||
|
||||
#endif
|
@ -420,6 +420,13 @@ unit:
|
||||
coverage:
|
||||
config/load: full
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: exec
|
||||
total: 1
|
||||
|
||||
coverage:
|
||||
config/exec: full
|
||||
|
||||
# ********************************************************************************************************************************
|
||||
- name: storage
|
||||
|
||||
|
69
test/src/module/config/execTest.c
Normal file
69
test/src/module/config/execTest.c
Normal file
@ -0,0 +1,69 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Exec Configuration
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/harnessConfig.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("cfgExecParam()"))
|
||||
{
|
||||
StringList *argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=test1");
|
||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/db path", testPath()));
|
||||
strLstAddZ(argList, "--log-subprocess");
|
||||
strLstAddZ(argList, "--no-config");
|
||||
strLstAddZ(argList, "--reset-neutral-umask");
|
||||
strLstAddZ(argList, "--repo-cipher-type=aes-256-cbc");
|
||||
strLstAddZ(argList, "archive-get");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
// Set repo1-cipher-pass to make sure it is not passed on the command line
|
||||
cfgOptionValidSet(cfgOptRepoCipherPass, true);
|
||||
cfgOptionSet(cfgOptRepoCipherPass, cfgSourceConfig, varNewStrZ("1234"));
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(cfgExecParam(cfgCmdLocal, NULL), "|")),
|
||||
strPtr(
|
||||
strNewFmt(
|
||||
"--no-config|--log-subprocess|--pg1-path=\"%s/db path\"|--repo1-cipher-type=aes-256-cbc|--repo1-path=%s/repo"
|
||||
"|--stanza=test1|local",
|
||||
testPath(), testPath())),
|
||||
"exec archive-get -> local");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstNew();
|
||||
strLstAddZ(argList, "pgbackrest");
|
||||
strLstAddZ(argList, "--stanza=test1");
|
||||
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/db", testPath()));
|
||||
strLstAddZ(argList, "--db-include=1");
|
||||
strLstAddZ(argList, "--db-include=2");
|
||||
strLstAddZ(argList, "--recovery-option=a=b");
|
||||
strLstAddZ(argList, "--recovery-option=c=d");
|
||||
strLstAddZ(argList, "restore");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
KeyValue *optionReplace = kvNew();
|
||||
kvPut(optionReplace, varNewStr(strNew("repo1-path")), varNewStr(strNew("/replace/path")));
|
||||
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strLstJoin(cfgExecParam(cfgCmdRestore, optionReplace), "|")),
|
||||
strPtr(
|
||||
strNewFmt(
|
||||
"--db-include=1|--db-include=2|--pg1-path=%s/db|--recovery-option=a=b|--recovery-option=c=d"
|
||||
"|--repo1-path=/replace/path|--stanza=test1|restore",
|
||||
testPath())),
|
||||
"exec restore -> restore");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
}
|
Loading…
Reference in New Issue
Block a user