Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
config.cc
1 #include "config.h"
2 
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <iomanip>
6 #include <sstream>
7 
8 #include "bootstrap/bootstrap.h"
9 #include "config.h"
10 #include "utilities/exceptions.h"
11 #include "utilities/utils.h"
12 
13 void TlsConfig::updateFromPropertyTree(const boost::property_tree::ptree& pt) {
14  CopyFromConfig(server, "server", pt);
15  CopyFromConfig(server_url_path, "server_url_path", pt);
16  CopyFromConfig(ca_source, "ca_source", pt);
17  CopyFromConfig(cert_source, "cert_source", pt);
18  CopyFromConfig(pkey_source, "pkey_source", pt);
19 }
20 
21 void TlsConfig::writeToStream(std::ostream& out_stream) const {
22  writeOption(out_stream, server, "server");
23  writeOption(out_stream, server_url_path, "server_url_path");
24  writeOption(out_stream, ca_source, "ca_source");
25  writeOption(out_stream, pkey_source, "pkey_source");
26  writeOption(out_stream, cert_source, "cert_source");
27 }
28 
29 void ProvisionConfig::updateFromPropertyTree(const boost::property_tree::ptree& pt) {
30  CopyFromConfig(server, "server", pt);
31  CopyFromConfig(p12_password, "p12_password", pt);
32  CopyFromConfig(expiry_days, "expiry_days", pt);
33  CopyFromConfig(provision_path, "provision_path", pt);
34  CopyFromConfig(device_id, "device_id", pt);
35  CopyFromConfig(primary_ecu_serial, "primary_ecu_serial", pt);
36  CopyFromConfig(primary_ecu_hardware_id, "primary_ecu_hardware_id", pt);
37  CopyFromConfig(ecu_registration_endpoint, "ecu_registration_endpoint", pt);
38  // provision.mode is set in postUpdateValues.
39 }
40 
41 void ProvisionConfig::writeToStream(std::ostream& out_stream) const {
42  writeOption(out_stream, server, "server");
43  writeOption(out_stream, p12_password, "p12_password");
44  writeOption(out_stream, expiry_days, "expiry_days");
45  writeOption(out_stream, provision_path, "provision_path");
46  writeOption(out_stream, device_id, "device_id");
47  writeOption(out_stream, primary_ecu_serial, "primary_ecu_serial");
48  writeOption(out_stream, primary_ecu_hardware_id, "primary_ecu_hardware_id");
49  writeOption(out_stream, ecu_registration_endpoint, "ecu_registration_endpoint");
50  // Skip provision.mode since it is dependent on other options.
51 }
52 
53 void UptaneConfig::updateFromPropertyTree(const boost::property_tree::ptree& pt) {
54  CopyFromConfig(polling_sec, "polling_sec", pt);
55  CopyFromConfig(director_server, "director_server", pt);
56  CopyFromConfig(repo_server, "repo_server", pt);
57  CopyFromConfig(key_source, "key_source", pt);
58  CopyFromConfig(key_type, "key_type", pt);
59  CopyFromConfig(force_install_completion, "force_install_completion", pt);
60  CopyFromConfig(secondary_config_file, "secondary_config_file", pt);
61  CopyFromConfig(secondary_preinstall_wait_sec, "secondary_preinstall_wait_sec", pt);
62 }
63 
64 void UptaneConfig::writeToStream(std::ostream& out_stream) const {
65  writeOption(out_stream, polling_sec, "polling_sec");
66  writeOption(out_stream, director_server, "director_server");
67  writeOption(out_stream, repo_server, "repo_server");
68  writeOption(out_stream, key_source, "key_source");
69  writeOption(out_stream, key_type, "key_type");
70  writeOption(out_stream, force_install_completion, "force_install_completion");
71  writeOption(out_stream, secondary_config_file, "secondary_config_file");
72  writeOption(out_stream, secondary_preinstall_wait_sec, "secondary_preinstall_wait_sec");
73 }
74 
75 /**
76  * \par Description:
77  * Overload the << operator for the configuration class allowing
78  * us to print its content, i.e. for logging purposes.
79  */
80 std::ostream& operator<<(std::ostream& os, const Config& cfg) {
81  cfg.writeToStream(os);
82  return os;
83 }
84 
85 Config::Config() { postUpdateValues(); }
86 
87 Config::Config(const boost::filesystem::path& filename) {
88  updateFromToml(filename);
89  postUpdateValues();
90 }
91 
92 Config::Config(const std::vector<boost::filesystem::path>& config_dirs) {
93  checkDirs(config_dirs);
94  updateFromDirs(config_dirs);
95  postUpdateValues();
96 }
97 
98 Config::Config(const boost::program_options::variables_map& cmd) {
99  // Redundantly check and set the loglevel from the commandline prematurely so
100  // that it is taken account while processing the config.
101  if (cmd.count("loglevel") != 0) {
102  logger.loglevel = cmd["loglevel"].as<int>();
103  logger_set_threshold(logger);
104  loglevel_from_cmdline = true;
105  }
106 
107  if (cmd.count("config") > 0) {
108  const auto configs = cmd["config"].as<std::vector<boost::filesystem::path>>();
109  checkDirs(configs);
110  updateFromDirs(configs);
111  } else {
112  updateFromDirs(config_dirs_);
113  }
114  updateFromCommandLine(cmd);
115  postUpdateValues();
116 }
117 
118 KeyManagerConfig Config::keymanagerConfig() const {
119  return KeyManagerConfig{p11, tls.ca_source, tls.pkey_source, tls.cert_source, uptane.key_type, uptane.key_source};
120 }
121 
122 void Config::postUpdateValues() {
123  logger_set_threshold(logger);
124 
125  provision.mode = provision.provision_path.empty() ? ProvisionMode::kDeviceCred : ProvisionMode::kSharedCred;
126 
127  if (tls.server.empty()) {
128  if (!tls.server_url_path.empty()) {
129  try {
130  tls.server = Utils::readFile(tls.server_url_path, true);
131  } catch (const boost::filesystem::filesystem_error& e) {
132  LOG_ERROR << "Couldn't read gateway URL: " << e.what();
133  tls.server = "";
134  }
135  } else if (!provision.provision_path.empty()) {
136  if (boost::filesystem::exists(provision.provision_path)) {
137  tls.server = Bootstrap::readServerUrl(provision.provision_path);
138  } else {
139  LOG_ERROR << "Provided provision archive " << provision.provision_path << " does not exist!";
140  }
141  }
142  }
143 
144  if (!tls.server.empty()) {
145  if (provision.server.empty()) {
146  provision.server = tls.server;
147  }
148 
149  if (uptane.repo_server.empty()) {
150  uptane.repo_server = tls.server + "/repo";
151  }
152 
153  if (uptane.director_server.empty()) {
154  uptane.director_server = tls.server + "/director";
155  }
156 
157  if (pacman.ostree_server.empty()) {
158  pacman.ostree_server = tls.server + "/treehub";
159  }
160  }
161 
162  if (!uptane.director_server.empty()) {
163  if (provision.ecu_registration_endpoint.empty()) {
164  provision.ecu_registration_endpoint = uptane.director_server + "/ecus";
165  }
166  }
167 
168  LOG_TRACE << "Final configuration that will be used: \n" << (*this);
169 }
170 
171 // For testing
172 void Config::updateFromTomlString(const std::string& contents) {
173  boost::property_tree::ptree pt;
174  std::stringstream stream(contents);
175  boost::property_tree::ini_parser::read_ini(stream, pt);
176  updateFromPropertyTree(pt);
177 }
178 
179 void Config::updateFromPropertyTree(const boost::property_tree::ptree& pt) {
180  // Keep this order the same as in config.h and Config::writeToStream().
181  if (!loglevel_from_cmdline) {
182  CopySubtreeFromConfig(logger, "logger", pt);
183  // If not already set from the commandline, set the loglevel now so that it
184  // affects the rest of the config processing.
185  logger_set_threshold(logger);
186  }
187  CopySubtreeFromConfig(p11, "p11", pt);
188  CopySubtreeFromConfig(tls, "tls", pt);
189  CopySubtreeFromConfig(provision, "provision", pt);
190  CopySubtreeFromConfig(uptane, "uptane", pt);
191  CopySubtreeFromConfig(pacman, "pacman", pt);
192  CopySubtreeFromConfig(storage, "storage", pt);
193  CopySubtreeFromConfig(import, "import", pt);
194  CopySubtreeFromConfig(telemetry, "telemetry", pt);
195  CopySubtreeFromConfig(bootloader, "bootloader", pt);
196 }
197 
198 void Config::updateFromCommandLine(const boost::program_options::variables_map& cmd) {
199  // Try to keep these options in the same order as parse_options() in main.cc.
200  if (cmd.count("loglevel") != 0) {
201  logger.loglevel = cmd["loglevel"].as<int>();
202  }
203  if (cmd.count("tls-server") != 0) {
204  tls.server = cmd["tls-server"].as<std::string>();
205  }
206  if (cmd.count("repo-server") != 0) {
207  uptane.repo_server = cmd["repo-server"].as<std::string>();
208  }
209  if (cmd.count("director-server") != 0) {
210  uptane.director_server = cmd["director-server"].as<std::string>();
211  }
212  if (cmd.count("primary-ecu-serial") != 0) {
213  provision.primary_ecu_serial = cmd["primary-ecu-serial"].as<std::string>();
214  }
215  if (cmd.count("primary-ecu-hardware-id") != 0) {
216  provision.primary_ecu_hardware_id = cmd["primary-ecu-hardware-id"].as<std::string>();
217  }
218  if (cmd.count("secondary-config-file") != 0) {
219  uptane.secondary_config_file = cmd["secondary_config_file"].as<boost::filesystem::path>();
220  }
221 }
222 
223 void Config::writeToStream(std::ostream& sink) const {
224  // Keep this order the same as in config.h and
225  // Config::updateFromPropertyTree().
226  WriteSectionToStream(logger, "logger", sink);
227  WriteSectionToStream(p11, "p11", sink);
228  WriteSectionToStream(tls, "tls", sink);
229  WriteSectionToStream(provision, "provision", sink);
230  WriteSectionToStream(uptane, "uptane", sink);
231  WriteSectionToStream(pacman, "pacman", sink);
232  WriteSectionToStream(storage, "storage", sink);
233  WriteSectionToStream(import, "import", sink);
234  WriteSectionToStream(telemetry, "telemetry", sink);
235  WriteSectionToStream(bootloader, "bootloader", sink);
236 }
Config
Configuration object for an aktualizr instance running on a primary ECU.
Definition: config.h:74
KeyManagerConfig
Definition: keymanager_config.h:9