Directory: | cvmfs/ |
---|---|
File: | cvmfs/options.h |
Date: | 2025-02-09 02:34:19 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 23 | 23 | 100.0% |
Branches: | 9 | 16 | 56.2% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | */ | ||
4 | |||
5 | #ifndef CVMFS_OPTIONS_H_ | ||
6 | #define CVMFS_OPTIONS_H_ | ||
7 | |||
8 | #include <stdint.h> | ||
9 | |||
10 | #include <cassert> | ||
11 | #include <map> | ||
12 | #include <string> | ||
13 | #include <vector> | ||
14 | |||
15 | #ifdef CVMFS_NAMESPACE_GUARD | ||
16 | namespace CVMFS_NAMESPACE_GUARD { | ||
17 | #endif | ||
18 | |||
19 | /** | ||
20 | * Templating manager used for variable replacement in the config file | ||
21 | */ | ||
22 | class OptionsTemplateManager { | ||
23 | public: | ||
24 | void SetTemplate(std::string name, std::string val); | ||
25 | std::string GetTemplate(std::string name); | ||
26 | bool HasTemplate(std::string name); | ||
27 | bool ParseString(std::string *input); | ||
28 | private: | ||
29 | std::map<std::string, std::string> templates_; | ||
30 | }; | ||
31 | |||
32 | class DefaultOptionsTemplateManager : public OptionsTemplateManager { | ||
33 | public: | ||
34 | explicit DefaultOptionsTemplateManager(std::string fqrn); | ||
35 | private: | ||
36 | static const char *kTemplateIdentFqrn; | ||
37 | static const char *kTemplateIdentOrg; | ||
38 | }; | ||
39 | |||
40 | /** | ||
41 | * This is the abstract base class for the different option parsers. It parses | ||
42 | * and stores the information contained in different config files, keeping | ||
43 | * the last parsed file that changed each property. It stores the information | ||
44 | * in a key-value map so that for each variable name the value and last source | ||
45 | * are stored, and makes each property part of the program's environments | ||
46 | */ | ||
47 | class OptionsManager { | ||
48 | public: | ||
49 | 96 | explicit OptionsManager(OptionsTemplateManager *opt_templ_mgr_param) | |
50 | 96 | : taint_environment_(true) { | |
51 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 84 times.
|
96 | if (opt_templ_mgr_param != NULL) { |
52 | 12 | opt_templ_mgr_ = opt_templ_mgr_param; | |
53 | } else { | ||
54 |
1/2✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
|
84 | opt_templ_mgr_ = new OptionsTemplateManager(); |
55 | } | ||
56 | 96 | } | |
57 | |||
58 | 2 | OptionsManager(const OptionsManager& opt_mgr) { | |
59 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | config_ = opt_mgr.config_; |
60 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | protected_parameters_ = opt_mgr.protected_parameters_; |
61 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | templatable_values_ = opt_mgr.templatable_values_; |
62 | 2 | taint_environment_ = opt_mgr.taint_environment_; | |
63 | |||
64 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | opt_templ_mgr_ = new OptionsTemplateManager(*(opt_mgr.opt_templ_mgr_)); |
65 | 2 | } | |
66 | |||
67 | 194 | virtual ~OptionsManager() { | |
68 |
1/2✓ Branch 0 taken 97 times.
✗ Branch 1 not taken.
|
194 | delete opt_templ_mgr_; |
69 | } | ||
70 | |||
71 | /** | ||
72 | * Switches the Options Templating Manager and reparses the set options | ||
73 | */ | ||
74 | void SwitchTemplateManager(OptionsTemplateManager *opt_templ_mgr_param); | ||
75 | |||
76 | /** | ||
77 | * Opens the config_file and extracts all contained variables and their | ||
78 | * corresponding values. The new variables are set (and overwritten in case | ||
79 | * they were previously defined) as environment variables | ||
80 | * | ||
81 | * @param config_file absolute path to the configuration file | ||
82 | * @param external if true it indicates the configuration file is in the | ||
83 | * repository. If false the configuration file is in /etc | ||
84 | */ | ||
85 | virtual void ParsePath(const std::string &config_file, | ||
86 | const bool external) = 0; | ||
87 | |||
88 | /** | ||
89 | * Parses the default config files for cvmfs | ||
90 | */ | ||
91 | void ParseDefault(const std::string &fqrn); | ||
92 | |||
93 | /** | ||
94 | * Cleans all information about the variables | ||
95 | */ | ||
96 | void ClearConfig(); | ||
97 | |||
98 | /** | ||
99 | * Checks if a concrete key (variable) is defined | ||
100 | * | ||
101 | * @param key variable to be checked in the map | ||
102 | * @return true if there is a value for key, false otherwise | ||
103 | */ | ||
104 | bool IsDefined(const std::string &key); | ||
105 | |||
106 | /** | ||
107 | * Gets the stored value for a concrete variable | ||
108 | * | ||
109 | * @param key variable to be accessed in the map | ||
110 | * @param value container of the received value, if it exists | ||
111 | * @return true if there was a value stored in the map for key | ||
112 | */ | ||
113 | bool GetValue(const std::string &key, std::string *value) const; | ||
114 | |||
115 | /** | ||
116 | * Gets the stored value for a concrete variable. Panics if the value is | ||
117 | * missing. | ||
118 | * | ||
119 | * @param key variable to be accessed in the map | ||
120 | * @param value container of the received value, if it exists | ||
121 | */ | ||
122 | std::string GetValueOrDie(const std::string &key); | ||
123 | |||
124 | /** | ||
125 | * Gets the stored last source of a concrete variable | ||
126 | * | ||
127 | * @param key variable to be accessed in the map | ||
128 | * @param value container of the received value, if it exists | ||
129 | * @return true if that variable was previously defined in | ||
130 | * at least one source | ||
131 | */ | ||
132 | bool GetSource(const std::string &key, std::string *value); | ||
133 | |||
134 | /** | ||
135 | * Checks if a variable contains a boolean value | ||
136 | * | ||
137 | * @param param_value variable to be accessed in the map | ||
138 | * @return true if param has as value "YES", "ON" or "1". False otherwise | ||
139 | */ | ||
140 | bool IsOn(const std::string ¶m_value) const; | ||
141 | |||
142 | /** | ||
143 | * Checks if a variable contains a boolean value | ||
144 | * | ||
145 | * @param param_value variable to be accessed in the map | ||
146 | * @return true if param has as value "NO", "OFF", "0", or "FALSE". | ||
147 | */ | ||
148 | bool IsOff(const std::string ¶m_value) const; | ||
149 | |||
150 | /** | ||
151 | * Retrieves a vector containing all stored keys | ||
152 | * | ||
153 | * @return a vector with all keys contained in the map | ||
154 | */ | ||
155 | std::vector<std::string> GetAllKeys(); | ||
156 | |||
157 | /** | ||
158 | * Returns key=value strings from the options array for all keys that match | ||
159 | * key_prefix. Can be used to construct an environment pointer for execve. | ||
160 | */ | ||
161 | std::vector<std::string> GetEnvironmentSubset( | ||
162 | const std::string &key_prefix, | ||
163 | bool strip_prefix); | ||
164 | |||
165 | /** | ||
166 | * Gets all stored key-values of the map in an string format. This format | ||
167 | * follows the following pattern: | ||
168 | * | ||
169 | * "KEY=VALUE # from SOURCE" | ||
170 | * | ||
171 | * @return a vector containing all key-values in a string format | ||
172 | */ | ||
173 | std::string Dump(); | ||
174 | |||
175 | bool HasConfigRepository(const std::string &fqrn, std::string *config_path); | ||
176 | |||
177 | /** | ||
178 | * Similar to a bash "read-only" parameter: the current value will be locked | ||
179 | * and cannot be changed anymore by succeeding parsings of config files. | ||
180 | */ | ||
181 | void ProtectParameter(const std::string ¶m); | ||
182 | |||
183 | /** | ||
184 | * Artificially inject values in the option manager. | ||
185 | */ | ||
186 | void SetValue(const std::string &key, const std::string &value); | ||
187 | |||
188 | /** | ||
189 | * Artificially inject values in the option manager, marking | ||
190 | cvmfs_talk as the source. | ||
191 | */ | ||
192 | void SetValueFromTalk(const std::string &key, const std::string &value); | ||
193 | |||
194 | /** | ||
195 | * Purge a value from the parameter map. Used in unit tests. | ||
196 | */ | ||
197 | void UnsetValue(const std::string &key); | ||
198 | |||
199 | 23 | void set_taint_environment(bool value) { taint_environment_ = value; } | |
200 | |||
201 | protected: | ||
202 | /** | ||
203 | * The ConfigValue structure contains a concrete value of a variable, as well | ||
204 | * as the source (complete path) of the config file where it was obtained | ||
205 | */ | ||
206 | struct ConfigValue { | ||
207 | std::string value; | ||
208 | std::string source; | ||
209 | }; | ||
210 | |||
211 | std::string TrimParameter(const std::string ¶meter); | ||
212 | std::string SanitizeParameterAssignment(std::string *line, | ||
213 | std::vector <std::string> *tokens); | ||
214 | void PopulateParameter(const std::string ¶m, const ConfigValue val); | ||
215 | void ParseValue(const std::string param, ConfigValue *val); | ||
216 | void UpdateEnvironment( | ||
217 | const std::string ¶m, ConfigValue val); | ||
218 | std::map<std::string, ConfigValue> config_; | ||
219 | std::map<std::string, std::string> protected_parameters_; | ||
220 | std::map<std::string, std::string> templatable_values_; | ||
221 | |||
222 | OptionsTemplateManager *opt_templ_mgr_; | ||
223 | /** | ||
224 | * Whether to add environment variables to the process' environment or not. | ||
225 | * In libcvmfs, we don't want a tainted environment. | ||
226 | */ | ||
227 | bool taint_environment_; | ||
228 | |||
229 | private: | ||
230 | // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp) | ||
231 | OptionsManager & operator= (const OptionsManager & /* other */) { | ||
232 | assert(false); | ||
233 | } | ||
234 | }; // class OptionManager | ||
235 | |||
236 | |||
237 | /** | ||
238 | * Derived class from OptionsManager. This class provides a so-called fast | ||
239 | * parsing procedure which does not create a fork of the process and only | ||
240 | * retrieves those options of the configuration file which strictly are in the | ||
241 | * following format: | ||
242 | * | ||
243 | * "KEY=VALUE". | ||
244 | * | ||
245 | * No comments (#) are allowed. | ||
246 | * | ||
247 | * @note In order to use this parse it is necessary to execute the program | ||
248 | * with the "-o simple_options_parsing" flag | ||
249 | * @note If using IgProf profiling tool it is necessary to use this parser in | ||
250 | * order to avoid a fork | ||
251 | */ | ||
252 | class SimpleOptionsParser : public OptionsManager { | ||
253 | public: | ||
254 | 78 | explicit SimpleOptionsParser( | |
255 | OptionsTemplateManager *opt_templ_mgr_param = NULL) | ||
256 | 78 | : OptionsManager(opt_templ_mgr_param) { } | |
257 | 9 | virtual void ParsePath( | |
258 | const std::string &config_file, | ||
259 | const bool external __attribute__((unused))) { | ||
260 | 9 | (void) TryParsePath(config_file); | |
261 | 9 | } | |
262 | // Libcvmfs returns success or failure, the fuse module fails silently | ||
263 | bool TryParsePath(const std::string &config_file); | ||
264 | }; // class SimpleOptionsManager | ||
265 | |||
266 | |||
267 | /** | ||
268 | * Derived class from OptionsManager. This class provides the | ||
269 | * complete parsing of the configuration files. In order to parse the | ||
270 | * configuration files it retrieves the "KEY=VALUE" pairs and uses bash for | ||
271 | * the rest, so that you can execute slightly complex scripts | ||
272 | */ | ||
273 | class BashOptionsManager : public OptionsManager { | ||
274 | public: | ||
275 | 18 | explicit BashOptionsManager( | |
276 | OptionsTemplateManager *opt_templ_mgr_param = NULL) | ||
277 | 18 | : OptionsManager(opt_templ_mgr_param) { } | |
278 | void ParsePath(const std::string &config_file, const bool external); | ||
279 | }; // class BashOptionsManager | ||
280 | |||
281 | |||
282 | |||
283 | #ifdef CVMFS_NAMESPACE_GUARD | ||
284 | } // namespace CVMFS_NAMESPACE_GUARD | ||
285 | #endif | ||
286 | |||
287 | #endif // CVMFS_OPTIONS_H_ | ||
288 |