1 /***********************************************************************************************************************************
2 Harness for Loading Test Configurations
3 ***********************************************************************************************************************************/
4 #include "build.auto.h"
5 
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include "common/io/io.h"
11 #include "config/config.intern.h"
12 #include "config/load.h"
13 #include "config/parse.h"
14 #include "storage/helper.h"
15 #include "version.h"
16 
17 #include "common/harnessConfig.h"
18 #include "common/harnessDebug.h"
19 #include "common/harnessLog.h"
20 #include "common/harnessTest.h"
21 
22 /**********************************************************************************************************************************/
23 void
hrnCfgLoad(ConfigCommand commandId,const StringList * argListParam,const HrnCfgLoadParam param)24 hrnCfgLoad(ConfigCommand commandId, const StringList *argListParam, const HrnCfgLoadParam param)
25 {
26     FUNCTION_HARNESS_BEGIN();
27         FUNCTION_HARNESS_PARAM(ENUM, commandId);
28         FUNCTION_HARNESS_PARAM(STRING_LIST, argListParam);
29         FUNCTION_HARNESS_PARAM(ENUM, param.role);
30     FUNCTION_HARNESS_END();
31 
32     // Make a copy of the arg list that we can modify
33     StringList *argList = strLstDup(argListParam);
34 
35     // Add standard options needed in most cases
36     if (!param.noStd)
37     {
38         // Set job retry to 0 if it is valid
39         if (cfgParseOptionValid(commandId, param.role, cfgOptJobRetry))
40             strLstInsert(argList, 0, STRDEF("--" CFGOPT_JOB_RETRY "=0"));
41 
42         // Set log path if valid
43         if (cfgParseOptionValid(commandId, param.role, cfgOptLogPath))
44             strLstInsert(argList, 0, strNewFmt("--" CFGOPT_LOG_PATH "=%s", hrnPath()));
45 
46         // Set lock path if valid
47         if (cfgParseOptionValid(commandId, param.role, cfgOptLockPath))
48             strLstInsert(argList, 0, strNewFmt("--" CFGOPT_LOCK_PATH "=%s/lock", hrnPath()));
49     }
50 
51     // Insert the command so it does not interfere with parameters
52     if (commandId != cfgCmdNone)
53         strLstInsert(argList, 0, cfgParseCommandRoleName(commandId, param.role, COLON_STR));
54 
55     // Insert the project exe
56     strLstInsert(argList, 0, param.exeBogus ? STRDEF("pgbackrest-bogus") : STRDEF(testProjectExe()));
57 
58     // Log parameters
59     if (param.log)
60     {
61         printf("config load:");
62 
63         for (unsigned int argIdx = 0; argIdx < strLstSize(argList); argIdx++)
64             printf(" %s", strZ(strLstGet(argList, argIdx)));
65 
66         hrnTestResultComment(param.comment);
67     }
68 
69     // Free objects in storage helper
70     storageHelperFree();
71 
72     // Parse config
73     configParse(storageLocal(), strLstSize(argList), strLstPtr(argList), false);
74 
75     // Set dry-run mode for storage and logging
76     harnessLogDryRunSet(cfgOptionValid(cfgOptDryRun) && cfgOptionBool(cfgOptDryRun));
77     storageHelperDryRunInit(cfgOptionValid(cfgOptDryRun) && cfgOptionBool(cfgOptDryRun));
78 
79     // Apply special option rules
80     cfgLoadUpdateOption();
81 
82     // Set buffer size when it is specified explicity -- otherwise the module default will be used. Note that this is *not* the
83     // configuration default, which is much larger.
84     if (cfgOptionTest(cfgOptBufferSize))
85         ioBufferSizeSet(cfgOptionUInt(cfgOptBufferSize));
86 
87     // Use a static exec-id for testing if it is not set explicitly
88     if (cfgOptionValid(cfgOptExecId) && !cfgOptionTest(cfgOptExecId))
89         cfgOptionSet(cfgOptExecId, cfgSourceParam, VARSTRDEF("1-test"));
90 
91     FUNCTION_HARNESS_RETURN_VOID();
92 }
93 
94 /**********************************************************************************************************************************/
95 void
hrnCfgArgRaw(StringList * argList,ConfigOption optionId,const String * value)96 hrnCfgArgRaw(StringList *argList, ConfigOption optionId, const String *value)
97 {
98     hrnCfgArgKeyRawZ(argList, optionId, 1, strZ(value));
99 }
100 
101 void
hrnCfgArgKeyRaw(StringList * argList,ConfigOption optionId,unsigned optionKey,const String * value)102 hrnCfgArgKeyRaw(StringList *argList, ConfigOption optionId, unsigned optionKey, const String *value)
103 {
104     hrnCfgArgKeyRawZ(argList, optionId, optionKey, strZ(value));
105 }
106 
107 void
hrnCfgArgRawFmt(StringList * argList,ConfigOption optionId,const char * format,...)108 hrnCfgArgRawFmt(StringList *argList, ConfigOption optionId, const char *format, ...)
109 {
110     char buffer[256];
111 
112     va_list argument;
113     va_start(argument, format);
114     vsnprintf(buffer, sizeof(buffer) - 1, format, argument);
115     va_end(argument);
116 
117     hrnCfgArgKeyRawZ(argList, optionId, 1, buffer);
118 }
119 
120 void
hrnCfgArgKeyRawFmt(StringList * argList,ConfigOption optionId,unsigned optionKey,const char * format,...)121 hrnCfgArgKeyRawFmt(StringList *argList, ConfigOption optionId, unsigned optionKey, const char *format, ...)
122 {
123     char buffer[256];
124 
125     va_list argument;
126     va_start(argument, format);
127     vsnprintf(buffer, sizeof(buffer) - 1, format, argument);
128     va_end(argument);
129 
130     hrnCfgArgKeyRawZ(argList, optionId, optionKey, buffer);
131 }
132 
133 void
hrnCfgArgRawZ(StringList * argList,ConfigOption optionId,const char * value)134 hrnCfgArgRawZ(StringList *argList, ConfigOption optionId, const char *value)
135 {
136     hrnCfgArgKeyRawZ(argList, optionId, 1, value);
137 }
138 
139 void
hrnCfgArgKeyRawZ(StringList * argList,ConfigOption optionId,unsigned optionKey,const char * value)140 hrnCfgArgKeyRawZ(StringList *argList, ConfigOption optionId, unsigned optionKey, const char *value)
141 {
142     strLstAdd(argList, strNewFmt("--%s=%s", cfgParseOptionKeyIdxName(optionId, optionKey - 1), value));
143 }
144 
145 void
hrnCfgArgRawStrId(StringList * argList,ConfigOption optionId,StringId value)146 hrnCfgArgRawStrId(StringList *argList, ConfigOption optionId, StringId value)
147 {
148     hrnCfgArgKeyRawStrId(argList, optionId, 1, value);
149 }
150 
151 void
hrnCfgArgKeyRawStrId(StringList * argList,ConfigOption optionId,unsigned optionKey,StringId value)152 hrnCfgArgKeyRawStrId(StringList *argList, ConfigOption optionId, unsigned optionKey, StringId value)
153 {
154     char buffer[STRID_MAX + 1];
155     strIdToZ(value, buffer);
156 
157     hrnCfgArgKeyRawZ(argList, optionId, optionKey, buffer);
158 }
159 
160 void
hrnCfgArgRawBool(StringList * argList,ConfigOption optionId,bool value)161 hrnCfgArgRawBool(StringList *argList, ConfigOption optionId, bool value)
162 {
163     hrnCfgArgKeyRawBool(argList, optionId, 1, value);
164 }
165 
166 void
hrnCfgArgKeyRawBool(StringList * argList,ConfigOption optionId,unsigned optionKey,bool value)167 hrnCfgArgKeyRawBool(StringList *argList, ConfigOption optionId, unsigned optionKey, bool value)
168 {
169     strLstAdd(argList, strNewFmt("--%s%s", value ? "" : "no-", cfgParseOptionKeyIdxName(optionId, optionKey - 1)));
170 }
171 
172 void
hrnCfgArgRawNegate(StringList * argList,ConfigOption optionId)173 hrnCfgArgRawNegate(StringList *argList, ConfigOption optionId)
174 {
175     hrnCfgArgKeyRawNegate(argList, optionId, 1);
176 }
177 
178 void
hrnCfgArgKeyRawNegate(StringList * argList,ConfigOption optionId,unsigned optionKey)179 hrnCfgArgKeyRawNegate(StringList *argList, ConfigOption optionId, unsigned optionKey)
180 {
181     strLstAdd(argList, strNewFmt("--no-%s", cfgParseOptionKeyIdxName(optionId, optionKey - 1)));
182 }
183 
184 void
hrnCfgArgRawReset(StringList * argList,ConfigOption optionId)185 hrnCfgArgRawReset(StringList *argList, ConfigOption optionId)
186 {
187     hrnCfgArgKeyRawReset(argList, optionId, 1);
188 }
189 
190 void
hrnCfgArgKeyRawReset(StringList * argList,ConfigOption optionId,unsigned optionKey)191 hrnCfgArgKeyRawReset(StringList *argList, ConfigOption optionId, unsigned optionKey)
192 {
193     strLstAdd(argList, strNewFmt("--reset-%s", cfgParseOptionKeyIdxName(optionId, optionKey - 1)));
194 }
195 
196 /**********************************************************************************************************************************/
197 __attribute__((always_inline)) static inline const char *
hrnCfgEnvName(const ConfigOption optionId,const unsigned optionKey)198 hrnCfgEnvName(const ConfigOption optionId, const unsigned optionKey)
199 {
200     return strZ(
201         strReplaceChr(strUpper(strNewFmt(HRN_PGBACKREST_ENV "%s", cfgParseOptionKeyIdxName(optionId, optionKey - 1))), '-', '_'));
202 }
203 
204 void
hrnCfgEnvRaw(ConfigOption optionId,const String * value)205 hrnCfgEnvRaw(ConfigOption optionId, const String *value)
206 {
207     hrnCfgEnvKeyRawZ(optionId, 1, strZ(value));
208 }
209 
210 void
hrnCfgEnvKeyRaw(ConfigOption optionId,unsigned optionKey,const String * value)211 hrnCfgEnvKeyRaw(ConfigOption optionId, unsigned optionKey, const String *value)
212 {
213     hrnCfgEnvKeyRawZ(optionId, optionKey, strZ(value));
214 }
215 
216 void
hrnCfgEnvRawZ(ConfigOption optionId,const char * value)217 hrnCfgEnvRawZ(ConfigOption optionId, const char *value)
218 {
219     hrnCfgEnvKeyRawZ(optionId, 1, value);
220 }
221 
222 void
hrnCfgEnvKeyRawZ(ConfigOption optionId,unsigned optionKey,const char * value)223 hrnCfgEnvKeyRawZ(ConfigOption optionId, unsigned optionKey, const char *value)
224 {
225     setenv(hrnCfgEnvName(optionId, optionKey), value, true);
226 }
227 
228 void
hrnCfgEnvRemoveRaw(ConfigOption optionId)229 hrnCfgEnvRemoveRaw(ConfigOption optionId)
230 {
231     hrnCfgEnvKeyRemoveRaw(optionId, 1);
232 }
233 
234 void
hrnCfgEnvKeyRemoveRaw(ConfigOption optionId,unsigned optionKey)235 hrnCfgEnvKeyRemoveRaw(ConfigOption optionId, unsigned optionKey)
236 {
237     unsetenv(hrnCfgEnvName(optionId, optionKey));
238 }
239