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