| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/options.h |
| Date: | 2025-11-09 02:35:23 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 22 | 22 | 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 | |||
| 29 | private: | ||
| 30 | std::map<std::string, std::string> templates_; | ||
| 31 | }; | ||
| 32 | |||
| 33 | class DefaultOptionsTemplateManager : public OptionsTemplateManager { | ||
| 34 | public: | ||
| 35 | explicit DefaultOptionsTemplateManager(std::string fqrn); | ||
| 36 | |||
| 37 | private: | ||
| 38 | static const char *kTemplateIdentFqrn; | ||
| 39 | static const char *kTemplateIdentOrg; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * This is the abstract base class for the different option parsers. It parses | ||
| 44 | * and stores the information contained in different config files, keeping | ||
| 45 | * the last parsed file that changed each property. It stores the information | ||
| 46 | * in a key-value map so that for each variable name the value and last source | ||
| 47 | * are stored, and makes each property part of the program's environments | ||
| 48 | */ | ||
| 49 | class OptionsManager { | ||
| 50 | public: | ||
| 51 | 2079 | explicit OptionsManager(OptionsTemplateManager *opt_templ_mgr_param) | |
| 52 | 2079 | : taint_environment_(true) { | |
| 53 |
2/2✓ Branch 0 taken 264 times.
✓ Branch 1 taken 1815 times.
|
2079 | if (opt_templ_mgr_param != NULL) { |
| 54 | 264 | opt_templ_mgr_ = opt_templ_mgr_param; | |
| 55 | } else { | ||
| 56 |
1/2✓ Branch 1 taken 1815 times.
✗ Branch 2 not taken.
|
1815 | opt_templ_mgr_ = new OptionsTemplateManager(); |
| 57 | } | ||
| 58 | 2079 | } | |
| 59 | |||
| 60 | 36 | OptionsManager(const OptionsManager &opt_mgr) { | |
| 61 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | config_ = opt_mgr.config_; |
| 62 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | protected_parameters_ = opt_mgr.protected_parameters_; |
| 63 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
36 | templatable_values_ = opt_mgr.templatable_values_; |
| 64 | 36 | taint_environment_ = opt_mgr.taint_environment_; | |
| 65 | |||
| 66 |
2/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
|
36 | opt_templ_mgr_ = new OptionsTemplateManager(*(opt_mgr.opt_templ_mgr_)); |
| 67 | 36 | } | |
| 68 | |||
| 69 |
1/2✓ Branch 0 taken 2112 times.
✗ Branch 1 not taken.
|
4224 | virtual ~OptionsManager() { delete opt_templ_mgr_; } |
| 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 | void SetupGlobalEnvironmentParams(); | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Cleans all information about the variables | ||
| 96 | */ | ||
| 97 | void ClearConfig(); | ||
| 98 | |||
| 99 | /** | ||
| 100 | * Checks if a concrete key (variable) is defined | ||
| 101 | * | ||
| 102 | * @param key variable to be checked in the map | ||
| 103 | * @return true if there is a value for key, false otherwise | ||
| 104 | */ | ||
| 105 | bool IsDefined(const std::string &key); | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Gets the stored value for a concrete variable | ||
| 109 | * | ||
| 110 | * @param key variable to be accessed in the map | ||
| 111 | * @param value container of the received value, if it exists | ||
| 112 | * @return true if there was a value stored in the map for key | ||
| 113 | */ | ||
| 114 | bool GetValue(const std::string &key, std::string *value) const; | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Gets the stored value for a concrete variable. Panics if the value is | ||
| 118 | * missing. | ||
| 119 | * | ||
| 120 | * @param key variable to be accessed in the map | ||
| 121 | * @param value container of the received value, if it exists | ||
| 122 | */ | ||
| 123 | std::string GetValueOrDie(const std::string &key); | ||
| 124 | |||
| 125 | /** | ||
| 126 | * Gets the stored last source of a concrete variable | ||
| 127 | * | ||
| 128 | * @param key variable to be accessed in the map | ||
| 129 | * @param value container of the received value, if it exists | ||
| 130 | * @return true if that variable was previously defined in | ||
| 131 | * at least one source | ||
| 132 | */ | ||
| 133 | bool GetSource(const std::string &key, std::string *value); | ||
| 134 | |||
| 135 | /** | ||
| 136 | * Checks if a variable contains a boolean value | ||
| 137 | * | ||
| 138 | * @param param_value variable to be accessed in the map | ||
| 139 | * @return true if param has as value "YES", "ON" or "1". False otherwise | ||
| 140 | */ | ||
| 141 | bool IsOn(const std::string ¶m_value) const; | ||
| 142 | |||
| 143 | /** | ||
| 144 | * Checks if a variable contains a boolean value | ||
| 145 | * | ||
| 146 | * @param param_value variable to be accessed in the map | ||
| 147 | * @return true if param has as value "NO", "OFF", "0", or "FALSE". | ||
| 148 | */ | ||
| 149 | bool IsOff(const std::string ¶m_value) const; | ||
| 150 | |||
| 151 | /** | ||
| 152 | * Retrieves a vector containing all stored keys | ||
| 153 | * | ||
| 154 | * @return a vector with all keys contained in the map | ||
| 155 | */ | ||
| 156 | std::vector<std::string> GetAllKeys(); | ||
| 157 | |||
| 158 | /** | ||
| 159 | * Returns key=value strings from the options array for all keys that match | ||
| 160 | * key_prefix. Can be used to construct an environment pointer for execve. | ||
| 161 | */ | ||
| 162 | std::vector<std::string> GetEnvironmentSubset(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 | 382 | 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(const std::string ¶m, ConfigValue val); | ||
| 217 | std::map<std::string, ConfigValue> config_; | ||
| 218 | std::map<std::string, std::string> protected_parameters_; | ||
| 219 | std::map<std::string, std::string> templatable_values_; | ||
| 220 | |||
| 221 | OptionsTemplateManager *opt_templ_mgr_; | ||
| 222 | /** | ||
| 223 | * Whether to add environment variables to the process' environment or not. | ||
| 224 | * In libcvmfs, we don't want a tainted environment. | ||
| 225 | */ | ||
| 226 | bool taint_environment_; | ||
| 227 | |||
| 228 | private: | ||
| 229 | // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp) | ||
| 230 | OptionsManager &operator=(const OptionsManager & /* other */) { | ||
| 231 | assert(false); | ||
| 232 | } | ||
| 233 | }; // class OptionManager | ||
| 234 | |||
| 235 | |||
| 236 | /** | ||
| 237 | * Derived class from OptionsManager. This class provides a so-called fast | ||
| 238 | * parsing procedure which does not create a fork of the process and only | ||
| 239 | * retrieves those options of the configuration file which strictly are in the | ||
| 240 | * following format: | ||
| 241 | * | ||
| 242 | * "KEY=VALUE". | ||
| 243 | * | ||
| 244 | * No comments (#) are allowed. | ||
| 245 | * | ||
| 246 | * @note In order to use this parse it is necessary to execute the program | ||
| 247 | * with the "-o simple_options_parsing" flag | ||
| 248 | * @note If using IgProf profiling tool it is necessary to use this parser in | ||
| 249 | * order to avoid a fork | ||
| 250 | */ | ||
| 251 | class SimpleOptionsParser : public OptionsManager { | ||
| 252 | public: | ||
| 253 | 1683 | explicit SimpleOptionsParser( | |
| 254 | OptionsTemplateManager *opt_templ_mgr_param = NULL) | ||
| 255 | 1683 | : OptionsManager(opt_templ_mgr_param) { } | |
| 256 | 162 | virtual void ParsePath(const std::string &config_file, | |
| 257 | const bool external __attribute__((unused))) { | ||
| 258 | 162 | (void)TryParsePath(config_file); | |
| 259 | 162 | } | |
| 260 | // Libcvmfs returns success or failure, the fuse module fails silently | ||
| 261 | bool TryParsePath(const std::string &config_file); | ||
| 262 | }; // class SimpleOptionsManager | ||
| 263 | |||
| 264 | |||
| 265 | /** | ||
| 266 | * Derived class from OptionsManager. This class provides the | ||
| 267 | * complete parsing of the configuration files. In order to parse the | ||
| 268 | * configuration files it retrieves the "KEY=VALUE" pairs and uses bash for | ||
| 269 | * the rest, so that you can execute slightly complex scripts | ||
| 270 | */ | ||
| 271 | class BashOptionsManager : public OptionsManager { | ||
| 272 | public: | ||
| 273 | 396 | explicit BashOptionsManager( | |
| 274 | OptionsTemplateManager *opt_templ_mgr_param = NULL) | ||
| 275 | 396 | : OptionsManager(opt_templ_mgr_param) { } | |
| 276 | void ParsePath(const std::string &config_file, const bool external); | ||
| 277 | }; // class BashOptionsManager | ||
| 278 | |||
| 279 | |||
| 280 | #ifdef CVMFS_NAMESPACE_GUARD | ||
| 281 | } // namespace CVMFS_NAMESPACE_GUARD | ||
| 282 | #endif | ||
| 283 | |||
| 284 | #endif // CVMFS_OPTIONS_H_ | ||
| 285 |