Directory: | cvmfs/ |
---|---|
File: | cvmfs/options.cc |
Date: | 2025-06-29 02:35:41 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 269 | 353 | 76.2% |
Branches: | 274 | 655 | 41.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | * | ||
4 | * Fills an internal map of key-value pairs from ASCII files in key=value | ||
5 | * style. Parameters can be overwritten. Used to read configuration from | ||
6 | * /etc/cvmfs/... | ||
7 | */ | ||
8 | |||
9 | |||
10 | #include "options.h" | ||
11 | |||
12 | #include <fcntl.h> | ||
13 | #include <sys/wait.h> | ||
14 | #include <unistd.h> | ||
15 | |||
16 | #include <cassert> | ||
17 | #include <cstdio> | ||
18 | #include <cstdlib> | ||
19 | #include <utility> | ||
20 | |||
21 | #include "sanitizer.h" | ||
22 | #include "util/exception.h" | ||
23 | #include "util/logging.h" | ||
24 | #include "util/posix.h" | ||
25 | #include "util/string.h" | ||
26 | |||
27 | using namespace std; // NOLINT | ||
28 | |||
29 | #ifdef CVMFS_NAMESPACE_GUARD | ||
30 | namespace CVMFS_NAMESPACE_GUARD { | ||
31 | #endif | ||
32 | |||
33 | |||
34 | 10853 | static string EscapeShell(const std::string &raw) { | |
35 |
2/2✓ Branch 1 taken 164297 times.
✓ Branch 2 taken 10770 times.
|
175067 | for (unsigned i = 0, l = raw.length(); i < l; ++i) { |
36 |
6/6✓ Branch 1 taken 144870 times.
✓ Branch 2 taken 19427 times.
✓ Branch 4 taken 129770 times.
✓ Branch 5 taken 15100 times.
✓ Branch 6 taken 83 times.
✓ Branch 7 taken 164214 times.
|
313494 | if (!(((raw[i] >= '0') && (raw[i] <= '9')) |
37 |
4/4✓ Branch 1 taken 129253 times.
✓ Branch 2 taken 19944 times.
✓ Branch 4 taken 116441 times.
✓ Branch 5 taken 12812 times.
|
149197 | || ((raw[i] >= 'A') && (raw[i] <= 'Z')) |
38 |
5/6✓ Branch 1 taken 108571 times.
✓ Branch 2 taken 27814 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 108571 times.
✓ Branch 7 taken 14794 times.
✓ Branch 8 taken 13020 times.
|
136385 | || ((raw[i] >= 'a') && (raw[i] <= 'z')) || (raw[i] == '/') |
39 |
6/6✓ Branch 1 taken 14339 times.
✓ Branch 2 taken 455 times.
✓ Branch 4 taken 8121 times.
✓ Branch 5 taken 6218 times.
✓ Branch 7 taken 251 times.
✓ Branch 8 taken 7870 times.
|
14794 | || (raw[i] == ':') || (raw[i] == '.') || (raw[i] == '_') |
40 |
3/4✓ Branch 1 taken 83 times.
✓ Branch 2 taken 168 times.
✓ Branch 4 taken 83 times.
✗ Branch 5 not taken.
|
251 | || (raw[i] == '-') || (raw[i] == ','))) { |
41 | 83 | goto escape_shell_quote; | |
42 | } | ||
43 | } | ||
44 |
1/2✓ Branch 1 taken 10770 times.
✗ Branch 2 not taken.
|
10770 | return raw; |
45 | |||
46 | 83 | escape_shell_quote: | |
47 |
1/2✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
|
166 | string result = "'"; |
48 |
2/2✓ Branch 1 taken 2530 times.
✓ Branch 2 taken 83 times.
|
2613 | for (unsigned i = 0, l = raw.length(); i < l; ++i) { |
49 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2530 times.
|
2530 | if (raw[i] == '\'') |
50 | ✗ | result += "\\"; | |
51 |
1/2✓ Branch 2 taken 2530 times.
✗ Branch 3 not taken.
|
2530 | result += raw[i]; |
52 | } | ||
53 |
1/2✓ Branch 1 taken 83 times.
✗ Branch 2 not taken.
|
83 | result += "'"; |
54 | 83 | return result; | |
55 | } | ||
56 | |||
57 | |||
58 | 7216 | string OptionsManager::TrimParameter(const string ¶meter) { | |
59 | 7216 | string result = Trim(parameter); | |
60 | // Strip "readonly" | ||
61 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7216 times.
|
7216 | if (result.find("readonly ") == 0) { |
62 | ✗ | result = result.substr(9); | |
63 | ✗ | result = Trim(result); | |
64 |
2/2✓ Branch 1 taken 336 times.
✓ Branch 2 taken 6880 times.
|
7216 | } else if (result.find("export ") == 0) { |
65 |
1/2✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
|
336 | result = result.substr(7); |
66 |
1/2✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
|
336 | result = Trim(result); |
67 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6880 times.
|
6880 | } else if (result.find("eval ") == 0) { |
68 | ✗ | result = result.substr(5); | |
69 | ✗ | result = Trim(result); | |
70 | } | ||
71 | 7216 | return result; | |
72 | } | ||
73 | |||
74 | 8224 | string OptionsManager::SanitizeParameterAssignment(string *line, | |
75 | vector<string> *tokens) { | ||
76 | 8224 | const size_t comment_idx = line->find("#"); | |
77 |
2/2✓ Branch 0 taken 672 times.
✓ Branch 1 taken 7552 times.
|
8224 | if (comment_idx != string::npos) |
78 |
1/2✓ Branch 1 taken 672 times.
✗ Branch 2 not taken.
|
672 | *line = line->substr(0, comment_idx); |
79 |
1/2✓ Branch 1 taken 8224 times.
✗ Branch 2 not taken.
|
8224 | *line = Trim(*line); |
80 |
2/2✓ Branch 1 taken 672 times.
✓ Branch 2 taken 7552 times.
|
8224 | if (line->empty()) |
81 |
1/2✓ Branch 2 taken 672 times.
✗ Branch 3 not taken.
|
672 | return ""; |
82 |
1/2✓ Branch 1 taken 7552 times.
✗ Branch 2 not taken.
|
7552 | *tokens = SplitString(*line, '='); |
83 |
2/2✓ Branch 1 taken 336 times.
✓ Branch 2 taken 7216 times.
|
7552 | if (tokens->size() < 2) |
84 |
1/2✓ Branch 2 taken 336 times.
✗ Branch 3 not taken.
|
336 | return ""; |
85 |
1/2✓ Branch 2 taken 7216 times.
✗ Branch 3 not taken.
|
7216 | string parameter = TrimParameter((*tokens)[0]); |
86 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7216 times.
|
7216 | if (parameter.find(" ") != string::npos) |
87 | ✗ | return ""; | |
88 | 7216 | return parameter; | |
89 | 7216 | } | |
90 | |||
91 | 379 | void OptionsManager::SwitchTemplateManager( | |
92 | OptionsTemplateManager *opt_templ_mgr_param) { | ||
93 |
1/2✓ Branch 0 taken 379 times.
✗ Branch 1 not taken.
|
379 | delete opt_templ_mgr_; |
94 |
1/2✓ Branch 0 taken 379 times.
✗ Branch 1 not taken.
|
379 | if (opt_templ_mgr_param != NULL) { |
95 | 379 | opt_templ_mgr_ = opt_templ_mgr_param; | |
96 | } else { | ||
97 | ✗ | opt_templ_mgr_ = new OptionsTemplateManager(); | |
98 | } | ||
99 | 379 | for (std::map<std::string, std::string>::iterator it = | |
100 | 379 | templatable_values_.begin(); | |
101 |
2/2✓ Branch 2 taken 138 times.
✓ Branch 3 taken 379 times.
|
517 | it != templatable_values_.end(); |
102 | 138 | it++) { | |
103 |
2/4✓ Branch 3 taken 138 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 138 times.
✗ Branch 7 not taken.
|
138 | config_[it->first].value = it->second; |
104 |
2/4✓ Branch 2 taken 138 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 138 times.
✗ Branch 6 not taken.
|
138 | opt_templ_mgr_->ParseString(&(config_[it->first].value)); |
105 |
2/4✓ Branch 2 taken 138 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 138 times.
✗ Branch 6 not taken.
|
138 | UpdateEnvironment(it->first, config_[it->first]); |
106 | } | ||
107 | 379 | } | |
108 | |||
109 | 414 | bool SimpleOptionsParser::TryParsePath(const string &config_file) { | |
110 |
1/2✓ Branch 2 taken 414 times.
✗ Branch 3 not taken.
|
414 | LogCvmfs(kLogCvmfs, kLogDebug, "Fast-parsing config file %s", |
111 | config_file.c_str()); | ||
112 | 414 | string line; | |
113 |
1/2✓ Branch 2 taken 414 times.
✗ Branch 3 not taken.
|
414 | FILE *fconfig = fopen(config_file.c_str(), "r"); |
114 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 368 times.
|
414 | if (fconfig == NULL) |
115 | 46 | return false; | |
116 | |||
117 | // Read line by line and extract parameters | ||
118 |
3/4✓ Branch 1 taken 5704 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5336 times.
✓ Branch 4 taken 368 times.
|
5704 | while (GetLineFile(fconfig, &line)) { |
119 | 5336 | vector<string> tokens; | |
120 |
1/2✓ Branch 1 taken 5336 times.
✗ Branch 2 not taken.
|
5336 | const string parameter = SanitizeParameterAssignment(&line, &tokens); |
121 |
2/2✓ Branch 1 taken 1380 times.
✓ Branch 2 taken 3956 times.
|
5336 | if (parameter.empty()) |
122 | 1380 | continue; | |
123 | |||
124 | // Strip quotes from value | ||
125 |
1/2✓ Branch 3 taken 3956 times.
✗ Branch 4 not taken.
|
3956 | tokens.erase(tokens.begin()); |
126 |
3/6✓ Branch 2 taken 3956 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3956 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3956 times.
✗ Branch 9 not taken.
|
7912 | string value = Trim(JoinStrings(tokens, "=")); |
127 | 3956 | const unsigned value_length = value.length(); | |
128 |
2/2✓ Branch 0 taken 2852 times.
✓ Branch 1 taken 1104 times.
|
3956 | if (value_length > 2) { |
129 |
3/7✓ Branch 1 taken 2852 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 276 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 276 times.
|
3128 | if (((value[0] == '"') && ((value[value_length - 1] == '"'))) |
130 |
9/13✓ Branch 0 taken 276 times.
✓ Branch 1 taken 2576 times.
✓ Branch 3 taken 2576 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 276 times.
✓ Branch 6 taken 2300 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 276 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 276 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 552 times.
✓ Branch 13 taken 2300 times.
|
3128 | || ((value[0] == '\'') && ((value[value_length - 1] == '\'')))) { |
131 |
1/2✓ Branch 1 taken 552 times.
✗ Branch 2 not taken.
|
552 | value = value.substr(1, value_length - 2); |
132 | } | ||
133 | } | ||
134 | |||
135 | 3956 | ConfigValue config_value; | |
136 |
1/2✓ Branch 1 taken 3956 times.
✗ Branch 2 not taken.
|
3956 | config_value.source = config_file; |
137 |
1/2✓ Branch 1 taken 3956 times.
✗ Branch 2 not taken.
|
3956 | config_value.value = value; |
138 |
2/4✓ Branch 1 taken 3956 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3956 times.
✗ Branch 5 not taken.
|
3956 | PopulateParameter(parameter, config_value); |
139 |
4/4✓ Branch 3 taken 3956 times.
✓ Branch 4 taken 1380 times.
✓ Branch 6 taken 3956 times.
✓ Branch 7 taken 1380 times.
|
6716 | } |
140 |
1/2✓ Branch 1 taken 368 times.
✗ Branch 2 not taken.
|
368 | fclose(fconfig); |
141 | 368 | return true; | |
142 | 414 | } | |
143 | |||
144 | 282 | void BashOptionsManager::ParsePath(const string &config_file, | |
145 | const bool external) { | ||
146 |
1/2✓ Branch 2 taken 282 times.
✗ Branch 3 not taken.
|
282 | LogCvmfs(kLogCvmfs, kLogDebug, "Parsing config file %s", config_file.c_str()); |
147 | int retval; | ||
148 | int pipe_open[2]; | ||
149 | int pipe_quit[2]; | ||
150 | 282 | pid_t pid_child = 0; | |
151 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 282 times.
|
282 | if (external) { |
152 | // cvmfs can run in the process group of automount in which case | ||
153 | // autofs won't mount an additional config repository. We create a | ||
154 | // short-lived process that detaches from the process group and triggers | ||
155 | // autofs to mount the config repository, if necessary. It holds a file | ||
156 | // handle to the config file until the main process opened the file, too. | ||
157 | ✗ | MakePipe(pipe_open); | |
158 | ✗ | MakePipe(pipe_quit); | |
159 | ✗ | switch (pid_child = fork()) { | |
160 | ✗ | case -1: | |
161 | ✗ | PANIC(NULL); | |
162 | ✗ | case 0: { // Child | |
163 | ✗ | close(pipe_open[0]); | |
164 | ✗ | close(pipe_quit[1]); | |
165 | // If this is not a process group leader, create a new session | ||
166 | ✗ | if (getpgrp() != getpid()) { | |
167 | ✗ | const pid_t new_session = setsid(); | |
168 | ✗ | assert(new_session != (pid_t)-1); | |
169 | } | ||
170 | ✗ | (void)open(config_file.c_str(), O_RDONLY); | |
171 | ✗ | char ready = 'R'; | |
172 | ✗ | WritePipe(pipe_open[1], &ready, 1); | |
173 | ✗ | retval = read(pipe_quit[0], &ready, 1); | |
174 | ✗ | _exit(retval); // Don't flush shared file descriptors | |
175 | } | ||
176 | } | ||
177 | // Parent | ||
178 | ✗ | close(pipe_open[1]); | |
179 | ✗ | close(pipe_quit[0]); | |
180 | ✗ | char ready = 0; | |
181 | ✗ | ReadPipe(pipe_open[0], &ready, 1); | |
182 | ✗ | assert(ready == 'R'); | |
183 | ✗ | close(pipe_open[0]); | |
184 | } | ||
185 |
1/2✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
|
282 | const string config_path = GetParentPath(config_file); |
186 |
1/2✓ Branch 2 taken 282 times.
✗ Branch 3 not taken.
|
282 | FILE *fconfig = fopen(config_file.c_str(), "r"); |
187 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 282 times.
|
282 | if (pid_child > 0) { |
188 | ✗ | char c = 'C'; | |
189 | ✗ | WritePipe(pipe_quit[1], &c, 1); | |
190 | int statloc; | ||
191 | ✗ | waitpid(pid_child, &statloc, 0); | |
192 | ✗ | close(pipe_quit[1]); | |
193 | } | ||
194 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 272 times.
|
282 | if (!fconfig) { |
195 |
2/8✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
|
10 | if (external && !DirectoryExists(config_path)) { |
196 | ✗ | string repo_required; | |
197 | ✗ | if (GetValue("CVMFS_CONFIG_REPO_REQUIRED", &repo_required) | |
198 | ✗ | && IsOn(repo_required)) { | |
199 | ✗ | LogCvmfs( | |
200 | kLogCvmfs, kLogStderr | kLogSyslogErr, | ||
201 | "required configuration repository directory does not exist: %s", | ||
202 | config_path.c_str()); | ||
203 | // Do not crash as in abort(), which can trigger core file creation | ||
204 | // from the mount helper | ||
205 | ✗ | exit(1); | |
206 | } | ||
207 | |||
208 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn, | |
209 | "configuration repository directory does not exist: %s", | ||
210 | config_path.c_str()); | ||
211 | } | ||
212 | 10 | return; | |
213 | } | ||
214 | |||
215 | int fd_stdin; | ||
216 | int fd_stdout; | ||
217 | int fd_stderr; | ||
218 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | retval = Shell(&fd_stdin, &fd_stdout, &fd_stderr); |
219 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 272 times.
|
272 | assert(retval); |
220 | |||
221 | // Let the shell read the file | ||
222 | 544 | string line; | |
223 |
1/2✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
|
544 | const string newline = "\n"; |
224 |
5/15✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 8 taken 272 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 272 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 272 times.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 272 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
544 | const string cd = "cd \"" + ((config_path == "") ? "/" : config_path) + "\"" |
225 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
544 | + newline; |
226 |
1/2✓ Branch 3 taken 272 times.
✗ Branch 4 not taken.
|
272 | WritePipe(fd_stdin, cd.data(), cd.length()); |
227 |
3/4✓ Branch 1 taken 3160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2888 times.
✓ Branch 4 taken 272 times.
|
3160 | while (GetLineFile(fconfig, &line)) { |
228 |
1/2✓ Branch 3 taken 2888 times.
✗ Branch 4 not taken.
|
2888 | WritePipe(fd_stdin, line.data(), line.length()); |
229 |
1/2✓ Branch 3 taken 2888 times.
✗ Branch 4 not taken.
|
2888 | WritePipe(fd_stdin, newline.data(), newline.length()); |
230 | } | ||
231 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | rewind(fconfig); |
232 | |||
233 | // Read line by line and extract parameters | ||
234 |
3/4✓ Branch 1 taken 3160 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2888 times.
✓ Branch 4 taken 272 times.
|
3160 | while (GetLineFile(fconfig, &line)) { |
235 | 2888 | vector<string> tokens; | |
236 |
1/2✓ Branch 1 taken 2888 times.
✗ Branch 2 not taken.
|
2888 | const string parameter = SanitizeParameterAssignment(&line, &tokens); |
237 |
2/2✓ Branch 1 taken 300 times.
✓ Branch 2 taken 2588 times.
|
2888 | if (parameter.empty()) |
238 | 300 | continue; | |
239 | |||
240 | 2588 | ConfigValue value; | |
241 |
1/2✓ Branch 1 taken 2588 times.
✗ Branch 2 not taken.
|
2588 | value.source = config_file; |
242 |
2/4✓ Branch 1 taken 2588 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2588 times.
✗ Branch 5 not taken.
|
2588 | const string sh_echo = "echo $" + parameter + "\n"; |
243 |
1/2✓ Branch 3 taken 2588 times.
✗ Branch 4 not taken.
|
2588 | WritePipe(fd_stdin, sh_echo.data(), sh_echo.length()); |
244 |
1/2✓ Branch 1 taken 2588 times.
✗ Branch 2 not taken.
|
2588 | GetLineFd(fd_stdout, &value.value); |
245 |
2/4✓ Branch 1 taken 2588 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2588 times.
✗ Branch 5 not taken.
|
2588 | PopulateParameter(parameter, value); |
246 |
4/4✓ Branch 3 taken 2588 times.
✓ Branch 4 taken 300 times.
✓ Branch 6 taken 2588 times.
✓ Branch 7 taken 300 times.
|
3188 | } |
247 | |||
248 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | close(fd_stderr); |
249 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | close(fd_stdout); |
250 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | close(fd_stdin); |
251 |
1/2✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
|
272 | fclose(fconfig); |
252 | } | ||
253 | |||
254 | |||
255 | 1001 | bool OptionsManager::HasConfigRepository(const string &fqrn, | |
256 | string *config_path) { | ||
257 | 1001 | string cvmfs_mount_dir; | |
258 |
3/6✓ Branch 2 taken 1001 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1001 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1001 times.
|
1001 | if (!GetValue("CVMFS_MOUNT_DIR", &cvmfs_mount_dir)) { |
259 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, "CVMFS_MOUNT_DIR missing"); | |
260 | ✗ | return false; | |
261 | } | ||
262 | |||
263 | 1001 | string config_repository; | |
264 |
4/6✓ Branch 2 taken 1001 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1001 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 63 times.
✓ Branch 10 taken 938 times.
|
1001 | if (GetValue("CVMFS_CONFIG_REPOSITORY", &config_repository)) { |
265 |
3/6✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 63 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 63 times.
|
63 | if (config_repository.empty() || (config_repository == fqrn)) |
266 | ✗ | return false; | |
267 |
1/2✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
|
63 | const sanitizer::RepositorySanitizer repository_sanitizer; |
268 |
2/4✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
|
63 | if (!repository_sanitizer.IsValid(config_repository)) { |
269 | ✗ | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, | |
270 | "invalid CVMFS_CONFIG_REPOSITORY: %s", | ||
271 | config_repository.c_str()); | ||
272 | ✗ | return false; | |
273 | } | ||
274 |
3/6✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 63 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 63 times.
✗ Branch 8 not taken.
|
63 | *config_path = cvmfs_mount_dir + "/" + config_repository + "/etc/cvmfs/"; |
275 | 63 | return true; | |
276 | 63 | } | |
277 | 938 | return false; | |
278 | 1001 | } | |
279 | |||
280 | |||
281 | ✗ | void OptionsManager::ParseDefault(const string &fqrn) { | |
282 | ✗ | if (taint_environment_) { | |
283 | ✗ | const int retval = setenv("CVMFS_FQRN", fqrn.c_str(), 1); | |
284 | ✗ | assert(retval == 0); | |
285 | } | ||
286 | |||
287 | ✗ | protected_parameters_.clear(); | |
288 | ✗ | ParsePath("/etc/cvmfs/default.conf", false); | |
289 | vector<string> dist_defaults = FindFilesBySuffix("/etc/cvmfs/default.d", | ||
290 | ✗ | ".conf"); | |
291 | ✗ | for (unsigned i = 0; i < dist_defaults.size(); ++i) { | |
292 | ✗ | ParsePath(dist_defaults[i], false); | |
293 | } | ||
294 | ✗ | ProtectParameter("CVMFS_CONFIG_REPOSITORY"); | |
295 | ✗ | string external_config_path; | |
296 | ✗ | if ((fqrn != "") && HasConfigRepository(fqrn, &external_config_path)) | |
297 | ✗ | ParsePath(external_config_path + "default.conf", true); | |
298 | ✗ | ParsePath("/etc/cvmfs/default.local", false); | |
299 | |||
300 | ✗ | if (fqrn != "") { | |
301 | ✗ | string domain; | |
302 | ✗ | vector<string> tokens = SplitString(fqrn, '.'); | |
303 | ✗ | assert(tokens.size() > 1); | |
304 | ✗ | tokens.erase(tokens.begin()); | |
305 | ✗ | domain = JoinStrings(tokens, "."); | |
306 | |||
307 | ✗ | if (HasConfigRepository(fqrn, &external_config_path)) | |
308 | ✗ | ParsePath(external_config_path + "domain.d/" + domain + ".conf", true); | |
309 | ✗ | ParsePath("/etc/cvmfs/domain.d/" + domain + ".conf", false); | |
310 | ✗ | ParsePath("/etc/cvmfs/domain.d/" + domain + ".local", false); | |
311 | |||
312 | ✗ | if (HasConfigRepository(fqrn, &external_config_path)) | |
313 | ✗ | ParsePath(external_config_path + "config.d/" + fqrn + ".conf", true); | |
314 | ✗ | ParsePath("/etc/cvmfs/config.d/" + fqrn + ".conf", false); | |
315 | ✗ | ParsePath("/etc/cvmfs/config.d/" + fqrn + ".local", false); | |
316 | } | ||
317 | } | ||
318 | |||
319 | |||
320 | 16494 | void OptionsManager::PopulateParameter(const string ¶m, ConfigValue val) { | |
321 |
1/2✓ Branch 1 taken 16494 times.
✗ Branch 2 not taken.
|
16494 | const map<string, string>::const_iterator iter = protected_parameters_.find( |
322 | 16494 | param); | |
323 |
5/6✓ Branch 3 taken 56 times.
✓ Branch 4 taken 16438 times.
✓ Branch 7 taken 56 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 56 times.
✓ Branch 10 taken 16438 times.
|
16494 | if ((iter != protected_parameters_.end()) && (iter->second != val.value)) { |
324 |
1/3✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
112 | LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, |
325 | "error in cvmfs configuration: attempt to change protected %s " | ||
326 | "from %s to %s", | ||
327 | 56 | param.c_str(), iter->second.c_str(), val.value.c_str()); | |
328 | 56 | return; | |
329 | } | ||
330 |
2/4✓ Branch 1 taken 16438 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16438 times.
✗ Branch 5 not taken.
|
16438 | ParseValue(param, &val); |
331 |
2/4✓ Branch 1 taken 16438 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16438 times.
✗ Branch 5 not taken.
|
16438 | config_[param] = val; |
332 |
1/2✓ Branch 1 taken 16438 times.
✗ Branch 2 not taken.
|
16438 | UpdateEnvironment(param, val); |
333 | } | ||
334 | |||
335 | 16576 | void OptionsManager::UpdateEnvironment(const string ¶m, ConfigValue val) { | |
336 |
2/2✓ Branch 0 taken 12400 times.
✓ Branch 1 taken 4176 times.
|
16576 | if (taint_environment_) { |
337 | 12400 | const int retval = setenv(param.c_str(), val.value.c_str(), 1); | |
338 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12400 times.
|
12400 | assert(retval == 0); |
339 | } | ||
340 | 16576 | } | |
341 | |||
342 | 16438 | void OptionsManager::ParseValue(std::string param, ConfigValue *val) { | |
343 |
1/2✓ Branch 1 taken 16438 times.
✗ Branch 2 not taken.
|
16438 | const string orig = val->value; |
344 |
1/2✓ Branch 1 taken 16438 times.
✗ Branch 2 not taken.
|
16438 | const bool has_templ = opt_templ_mgr_->ParseString(&(val->value)); |
345 |
2/2✓ Branch 0 taken 418 times.
✓ Branch 1 taken 16020 times.
|
16438 | if (has_templ) { |
346 |
2/4✓ Branch 1 taken 418 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 418 times.
✗ Branch 5 not taken.
|
418 | templatable_values_[param] = orig; |
347 | } | ||
348 | 16438 | } | |
349 | |||
350 | |||
351 | 56 | void OptionsManager::ProtectParameter(const string ¶m) { | |
352 | 56 | string value; | |
353 | // We don't care about the result. If param does not yet exists, we lock it | ||
354 | // to the empty string. | ||
355 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | (void)GetValue(param, &value); |
356 |
2/4✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
|
56 | protected_parameters_[param] = value; |
357 | 56 | } | |
358 | |||
359 | |||
360 | 56 | void OptionsManager::ClearConfig() { config_.clear(); } | |
361 | |||
362 | |||
363 | 10870 | bool OptionsManager::IsDefined(const std::string &key) { | |
364 |
1/2✓ Branch 1 taken 10870 times.
✗ Branch 2 not taken.
|
10870 | const map<string, ConfigValue>::const_iterator iter = config_.find(key); |
365 | 10870 | return iter != config_.end(); | |
366 | } | ||
367 | |||
368 | |||
369 | 114289 | bool OptionsManager::GetValue(const string &key, string *value) const { | |
370 |
1/2✓ Branch 1 taken 114289 times.
✗ Branch 2 not taken.
|
114289 | const map<string, ConfigValue>::const_iterator iter = config_.find(key); |
371 |
2/2✓ Branch 2 taken 26873 times.
✓ Branch 3 taken 87416 times.
|
114289 | if (iter != config_.end()) { |
372 |
1/2✓ Branch 2 taken 26873 times.
✗ Branch 3 not taken.
|
26873 | *value = iter->second.value; |
373 | 26873 | return true; | |
374 | } | ||
375 |
1/2✓ Branch 1 taken 87416 times.
✗ Branch 2 not taken.
|
87416 | *value = ""; |
376 | 87416 | return false; | |
377 | } | ||
378 | |||
379 | |||
380 | 3 | std::string OptionsManager::GetValueOrDie(const string &key) { | |
381 | 3 | std::string value; | |
382 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | const bool retval = GetValue(key, &value); |
383 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!retval) { |
384 | ✗ | PANIC(kLogStderr | kLogDebug, "%s configuration parameter missing", | |
385 | key.c_str()); | ||
386 | } | ||
387 | 3 | return value; | |
388 | } | ||
389 | |||
390 | |||
391 | 11189 | bool OptionsManager::GetSource(const string &key, string *value) { | |
392 |
1/2✓ Branch 1 taken 11189 times.
✗ Branch 2 not taken.
|
11189 | const map<string, ConfigValue>::const_iterator iter = config_.find(key); |
393 |
1/2✓ Branch 3 taken 11189 times.
✗ Branch 4 not taken.
|
11189 | if (iter != config_.end()) { |
394 |
1/2✓ Branch 2 taken 11189 times.
✗ Branch 3 not taken.
|
11189 | *value = iter->second.source; |
395 | 11189 | return true; | |
396 | } | ||
397 | ✗ | *value = ""; | |
398 | ✗ | return false; | |
399 | } | ||
400 | |||
401 | |||
402 | 1905 | bool OptionsManager::IsOn(const std::string ¶m_value) const { | |
403 |
1/2✓ Branch 1 taken 1905 times.
✗ Branch 2 not taken.
|
1905 | const string uppercase = ToUpper(param_value); |
404 |
2/4✓ Branch 2 taken 1737 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1737 times.
✗ Branch 6 not taken.
|
3642 | return ((uppercase == "YES") || (uppercase == "ON") || (uppercase == "1") |
405 |
3/4✓ Branch 0 taken 1737 times.
✓ Branch 1 taken 168 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1737 times.
|
5547 | || (uppercase == "TRUE")); |
406 | 1905 | } | |
407 | |||
408 | |||
409 | ✗ | bool OptionsManager::IsOff(const std::string ¶m_value) const { | |
410 | ✗ | const string uppercase = ToUpper(param_value); | |
411 | ✗ | return ((uppercase == "NO") || (uppercase == "OFF") || (uppercase == "0") | |
412 | ✗ | || (uppercase == "FALSE")); | |
413 | } | ||
414 | |||
415 | |||
416 | 2022 | vector<string> OptionsManager::GetAllKeys() { | |
417 | 2022 | vector<string> result; | |
418 | 2022 | for (map<string, ConfigValue>::const_iterator i = config_.begin(), | |
419 | 2022 | iEnd = config_.end(); | |
420 |
2/2✓ Branch 1 taken 11637 times.
✓ Branch 2 taken 2022 times.
|
13659 | i != iEnd; |
421 | 11637 | ++i) { | |
422 |
1/2✓ Branch 2 taken 11637 times.
✗ Branch 3 not taken.
|
11637 | result.push_back(i->first); |
423 | } | ||
424 | 2022 | return result; | |
425 | } | ||
426 | |||
427 | |||
428 | 264 | vector<string> OptionsManager::GetEnvironmentSubset(const string &key_prefix, | |
429 | bool strip_prefix) { | ||
430 | 264 | vector<string> result; | |
431 | 264 | for (map<string, ConfigValue>::const_iterator i = config_.begin(), | |
432 | 264 | iEnd = config_.end(); | |
433 |
2/2✓ Branch 1 taken 3136 times.
✓ Branch 2 taken 264 times.
|
3400 | i != iEnd; |
434 | 3136 | ++i) { | |
435 | 3136 | const bool ignore_prefix = false; | |
436 |
3/4✓ Branch 2 taken 3136 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 392 times.
✓ Branch 5 taken 2744 times.
|
3136 | if (HasPrefix(i->first, key_prefix, ignore_prefix)) { |
437 | const string output_key = strip_prefix | ||
438 | 56 | ? i->first.substr(key_prefix.length()) | |
439 |
4/6✓ Branch 0 taken 56 times.
✓ Branch 1 taken 336 times.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 336 times.
✗ Branch 9 not taken.
|
448 | : i->first; |
440 |
3/6✓ Branch 2 taken 392 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 392 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 392 times.
✗ Branch 9 not taken.
|
392 | result.push_back(output_key + "=" + i->second.value); |
441 | 392 | } | |
442 | } | ||
443 | 264 | return result; | |
444 | } | ||
445 | |||
446 | |||
447 | 1910 | string OptionsManager::Dump() { | |
448 | 1910 | string result; | |
449 |
1/2✓ Branch 1 taken 1910 times.
✗ Branch 2 not taken.
|
1910 | vector<string> keys = GetAllKeys(); |
450 |
2/2✓ Branch 1 taken 10853 times.
✓ Branch 2 taken 1910 times.
|
12763 | for (unsigned i = 0, l = keys.size(); i < l; ++i) { |
451 | bool retval; | ||
452 | 10853 | string value; | |
453 | 10853 | string source; | |
454 | |||
455 |
1/2✓ Branch 2 taken 10853 times.
✗ Branch 3 not taken.
|
10853 | retval = GetValue(keys[i], &value); |
456 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10853 times.
|
10853 | assert(retval); |
457 |
1/2✓ Branch 2 taken 10853 times.
✗ Branch 3 not taken.
|
10853 | retval = GetSource(keys[i], &source); |
458 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10853 times.
|
10853 | assert(retval); |
459 |
5/10✓ Branch 1 taken 10853 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10853 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10853 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 10853 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 10853 times.
✗ Branch 15 not taken.
|
21706 | result += keys[i] + "=" + EscapeShell(value) + " # from " + source |
460 |
2/4✓ Branch 1 taken 10853 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10853 times.
✗ Branch 5 not taken.
|
10853 | + "\n"; |
461 | 10853 | } | |
462 | 3820 | return result; | |
463 | 1910 | } | |
464 | |||
465 | ✗ | void OptionsManager::SetValueFromTalk(const string &key, const string &value) { | |
466 | ✗ | ConfigValue config_value; | |
467 | ✗ | config_value.source = "cvmfs_talk"; | |
468 | ✗ | config_value.value = value; | |
469 | ✗ | PopulateParameter(key, config_value); | |
470 | } | ||
471 | |||
472 | 9950 | void OptionsManager::SetValue(const string &key, const string &value) { | |
473 | 9950 | ConfigValue config_value; | |
474 |
1/2✓ Branch 1 taken 9950 times.
✗ Branch 2 not taken.
|
9950 | config_value.source = "@INTERNAL@"; |
475 |
1/2✓ Branch 1 taken 9950 times.
✗ Branch 2 not taken.
|
9950 | config_value.value = value; |
476 |
2/4✓ Branch 1 taken 9950 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9950 times.
✗ Branch 5 not taken.
|
9950 | PopulateParameter(key, config_value); |
477 | 9950 | } | |
478 | |||
479 | |||
480 | 441 | void OptionsManager::UnsetValue(const string &key) { | |
481 | 441 | protected_parameters_.erase(key); | |
482 | 441 | config_.erase(key); | |
483 |
2/2✓ Branch 0 taken 385 times.
✓ Branch 1 taken 56 times.
|
441 | if (taint_environment_) |
484 | 385 | unsetenv(key.c_str()); | |
485 | 441 | } | |
486 | |||
487 | const char *DefaultOptionsTemplateManager ::kTemplateIdentFqrn = "fqrn"; | ||
488 | |||
489 | const char *DefaultOptionsTemplateManager ::kTemplateIdentOrg = "org"; | ||
490 | |||
491 | 587 | DefaultOptionsTemplateManager::DefaultOptionsTemplateManager(std::string fqrn) { | |
492 |
3/6✓ Branch 1 taken 587 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 587 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 587 times.
✗ Branch 9 not taken.
|
587 | SetTemplate(kTemplateIdentFqrn, fqrn); |
493 |
1/2✓ Branch 1 taken 587 times.
✗ Branch 2 not taken.
|
587 | vector<string> fqrn_parts = SplitString(fqrn, '.'); |
494 |
3/6✓ Branch 2 taken 587 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 587 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 587 times.
✗ Branch 10 not taken.
|
587 | SetTemplate(kTemplateIdentOrg, fqrn_parts[0]); |
495 | 587 | } | |
496 | |||
497 | 1294 | void OptionsTemplateManager::SetTemplate(std::string name, std::string val) { | |
498 | 1294 | templates_[name] = val; | |
499 | 1294 | } | |
500 | |||
501 | 1532 | std::string OptionsTemplateManager::GetTemplate(std::string name) { | |
502 |
2/2✓ Branch 1 taken 322 times.
✓ Branch 2 taken 1210 times.
|
1532 | if (templates_.count(name)) { |
503 | 322 | return templates_[name]; | |
504 | } else { | ||
505 |
2/4✓ Branch 1 taken 1210 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1210 times.
✗ Branch 5 not taken.
|
1210 | std::string var_name = "@" + name + "@"; |
506 |
1/2✓ Branch 2 taken 1210 times.
✗ Branch 3 not taken.
|
1210 | LogCvmfs(kLogCvmfs, kLogDebug, "Undeclared variable: %s", var_name.c_str()); |
507 | 1210 | return var_name; | |
508 | 1210 | } | |
509 | } | ||
510 | |||
511 | 16640 | bool OptionsTemplateManager::ParseString(std::string *input) { | |
512 | 16640 | std::string result; | |
513 |
1/2✓ Branch 1 taken 16640 times.
✗ Branch 2 not taken.
|
16640 | std::string in = *input; |
514 | 16640 | bool has_vars = false; | |
515 | 16640 | int mode = 0; | |
516 | 16640 | std::string stock; | |
517 |
2/2✓ Branch 1 taken 331275 times.
✓ Branch 2 taken 16640 times.
|
347915 | for (std::string::size_type i = 0; i < in.size(); i++) { |
518 |
2/3✓ Branch 0 taken 322641 times.
✓ Branch 1 taken 8634 times.
✗ Branch 2 not taken.
|
331275 | switch (mode) { |
519 | 322641 | case 0: | |
520 |
3/4✓ Branch 1 taken 322641 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1788 times.
✓ Branch 4 taken 320853 times.
|
322641 | if (in[i] == '@') { |
521 | 1788 | mode = 1; | |
522 | } else { | ||
523 |
2/4✓ Branch 1 taken 320853 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 320853 times.
✗ Branch 5 not taken.
|
320853 | result += in[i]; |
524 | } | ||
525 | 322641 | break; | |
526 | 8634 | case 1: | |
527 |
3/4✓ Branch 1 taken 8634 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1420 times.
✓ Branch 4 taken 7214 times.
|
8634 | if (in[i] == '@') { |
528 | 1420 | mode = 0; | |
529 |
3/6✓ Branch 1 taken 1420 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1420 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1420 times.
✗ Branch 8 not taken.
|
1420 | result += GetTemplate(stock); |
530 |
1/2✓ Branch 1 taken 1420 times.
✗ Branch 2 not taken.
|
1420 | stock = ""; |
531 | 1420 | has_vars = true; | |
532 | } else { | ||
533 |
2/4✓ Branch 1 taken 7214 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7214 times.
✗ Branch 5 not taken.
|
7214 | stock += in[i]; |
534 | } | ||
535 | 8634 | break; | |
536 | } | ||
537 | } | ||
538 |
2/2✓ Branch 0 taken 368 times.
✓ Branch 1 taken 16272 times.
|
16640 | if (mode == 1) { |
539 |
2/4✓ Branch 1 taken 368 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 368 times.
✗ Branch 5 not taken.
|
368 | result += "@" + stock; |
540 | } | ||
541 |
1/2✓ Branch 1 taken 16640 times.
✗ Branch 2 not taken.
|
16640 | *input = result; |
542 | 16640 | return has_vars; | |
543 | 16640 | } | |
544 | |||
545 | 112 | bool OptionsTemplateManager::HasTemplate(std::string name) { | |
546 | 112 | return templates_.count(name); | |
547 | } | ||
548 | |||
549 | #ifdef CVMFS_NAMESPACE_GUARD | ||
550 | } // namespace CVMFS_NAMESPACE_GUARD | ||
551 | #endif | ||
552 |