5 #include <boost/filesystem.hpp> 6 #include <boost/program_options.hpp> 8 #include "aktualizr_info_config.h" 9 #include "logging/logging.h" 10 #include "package_manager/packagemanagerfactory.h" 11 #include "storage/invstorage.h" 12 #include "storage/sql_utils.h" 13 #include "utilities/aktualizr_version.h" 15 namespace bpo = boost::program_options;
17 static int loadAndPrintDelegations(
const std::shared_ptr<INvStorage> &storage) {
18 std::vector<std::pair<Uptane::Role, std::string> > delegations;
19 bool delegations_fetch_res = storage->loadAllDelegations(delegations);
21 if (!delegations_fetch_res) {
22 std::cout <<
"Failed to load delegations" << std::endl;
26 if (delegations.size() > 0) {
27 for (
const auto &delegation : delegations) {
28 std::cout << delegation.first <<
": " << delegation.second << std::endl;
31 std::cout <<
"Delegations are not present" << std::endl;
36 void checkInfoOptions(
const bpo::options_description &description,
const bpo::variables_map &vm) {
37 if (vm.count(
"help") != 0) {
38 std::cout << description <<
'\n';
41 if (vm.count(
"version") != 0) {
42 std::cout <<
"Current aktualizr-info version is: " << aktualizr_version() <<
"\n";
47 int main(
int argc,
char **argv) {
48 bpo::options_description all(
"aktualizr-info command line options");
49 bpo::options_description description(
"aktualizr-info command line options");
50 bpo::options_description hidden(
"deprecated options");
52 description.add_options()
53 (
"help,h",
"print usage")
54 (
"version,v",
"Current aktualizr version")
55 (
"config,c", bpo::value<std::vector<boost::filesystem::path> >()->composing(),
"configuration file or directory")
56 (
"loglevel", bpo::value<int>(),
"set log level 0-5 (trace, debug, info, warning, error, fatal)")
57 (
"name-only",
"Only output device name (intended for scripting). Cannot be used in combination with other arguments.")
58 (
"tls-creds",
"Outputs TLS credentials")
59 (
"tls-root-ca",
"Outputs TLS Root CA")
60 (
"tls-cert",
"Outputs TLS client certificate")
61 (
"tls-prv-key",
"Output TLS client private key")
62 (
"ecu-keys",
"Outputs Uptane keys")
63 (
"ecu-pub-key",
"Outputs Uptane public key")
64 (
"ecu-prv-key",
"Outputs Uptane private key")
65 (
"image-root",
"Outputs root.json from Image repo")
66 (
"image-timestamp",
"Outputs timestamp.json from Image repo")
67 (
"image-snapshot",
"Outputs snapshot.json from Image repo")
68 (
"image-targets",
"Outputs targets.json from Image repo")
69 (
"delegation",
"Outputs metadata of Image repo Targets' delegations")
70 (
"director-root",
"Outputs root.json from Director repo")
71 (
"director-targets",
"Outputs targets.json from Director repo")
72 (
"allow-migrate",
"Opens database in read/write mode to make possible to migrate database if needed")
73 (
"wait-until-provisioned",
"Outputs metadata when device already provisioned");
76 (
"images-root",
"Outputs root.json from Image repo")
77 (
"images-timestamp",
"Outputs timestamp.json from Image repo")
78 (
"images-snapshot",
"Outputs snapshot.json from Image repo")
79 (
"images-target",
"Outputs targets.json from Image repo")
80 (
"images-targets",
"Outputs targets.json from Image repo")
81 (
"image-target",
"Outputs targets.json from Image repo")
82 (
"director-target",
"Outputs targets.json from Director repo");
86 all.add(description).add(hidden);
87 bpo::variables_map vm;
88 bpo::basic_parsed_options<char> parsed_options = bpo::command_line_parser(argc, argv).options(all).run();
89 bpo::store(parsed_options, vm);
90 checkInfoOptions(description, vm);
92 std::vector<std::string> unregistered_options =
93 bpo::collect_unrecognized(parsed_options.options, bpo::include_positional);
94 if (vm.count(
"help") == 0 && !unregistered_options.empty()) {
95 std::cout << description <<
"\n";
100 if (vm.count(
"loglevel") == 0U) {
101 logger_set_enable(
false);
106 bool secondary_db =
false;
108 bool readonly =
true;
109 if (vm.count(
"allow-migrate") != 0U) {
113 bool wait_provisioning =
false;
114 if (vm.count(
"wait-until-provisioned") != 0) {
115 wait_provisioning =
true;
118 std::shared_ptr<INvStorage> storage;
119 bool cmd_trigger =
false;
120 std::string device_id;
122 bool registered =
false;
123 bool has_metadata =
false;
124 std::string director_root;
125 if (wait_provisioning) {
126 while (!registered || !has_metadata) {
128 storage = INvStorage::newStorage(config.storage, readonly);
130 registered = storage->loadEcuRegistered();
131 has_metadata = storage->loadLatestRoot(&director_root, Uptane::RepositoryType::Director());
132 }
catch (std::exception &e) {
139 storage = INvStorage::newStorage(config.storage, readonly);
142 bool deviceid_loaded =
false;
143 if (storage->loadDeviceId(&device_id)) {
144 deviceid_loaded =
true;
146 if (vm.count(
"name-only") != 0U) {
147 std::cout << device_id << std::endl;
152 registered = registered || storage->loadEcuRegistered();
153 has_metadata = has_metadata || storage->loadLatestRoot(&director_root, Uptane::RepositoryType::Director());
155 bool tlscred_loaded =
false;
161 storage->loadTlsCreds(&ca, &cert, &pkey);
162 if (!ca.empty() || !cert.empty() || !pkey.empty()) {
163 tlscred_loaded =
true;
166 if (vm.count(
"tls-creds") != 0U) {
167 std::cout <<
"Root CA certificate:" << std::endl << ca << std::endl;
168 std::cout <<
"Client certificate:" << std::endl << cert << std::endl;
169 std::cout <<
"Client private key:" << std::endl << pkey << std::endl;
174 if (vm.count(
"tls-root-ca") != 0U) {
176 storage->loadTlsCa(&ca);
177 std::cout << ca << std::endl;
181 if (vm.count(
"tls-cert") != 0U) {
183 storage->loadTlsCert(&cert);
184 std::cout << cert << std::endl;
188 if (vm.count(
"tls-prv-key") != 0U) {
190 storage->loadTlsPkey(&key);
191 std::cout << key << std::endl;
196 bool ecukeys_loaded =
false;
200 storage->loadPrimaryKeys(&pub, &priv);
201 if (!pub.empty() && !priv.empty()) {
202 ecukeys_loaded =
true;
204 if (vm.count(
"ecu-keys") != 0U) {
205 std::cout <<
"Public key:" << std::endl << pub << std::endl;
206 std::cout <<
"Private key:" << std::endl << priv << std::endl;
210 if (vm.count(
"ecu-pub-key") != 0U) {
212 storage->loadPrimaryPublic(&key);
213 std::cout << key << std::endl;
217 if (vm.count(
"ecu-prv-key") != 0U) {
219 storage->loadPrimaryPrivate(&key);
220 std::cout << key << std::endl;
225 std::string msg_metadata_fail =
"Metadata is not available";
226 if (vm.count(
"image-root") != 0U || vm.count(
"images-root") != 0U) {
228 std::cout << msg_metadata_fail << std::endl;
230 std::string images_root;
231 storage->loadLatestRoot(&images_root, Uptane::RepositoryType::Image());
232 std::cout << images_root << std::endl;
237 if (vm.count(
"image-targets") != 0U || vm.count(
"image-target") != 0U || vm.count(
"images-targets") != 0U ||
238 vm.count(
"images-target") != 0U) {
240 std::cout << msg_metadata_fail << std::endl;
242 std::string images_targets;
243 storage->loadNonRoot(&images_targets, Uptane::RepositoryType::Image(), Uptane::Role::Targets());
244 std::cout << images_targets << std::endl;
249 if (vm.count(
"delegation") != 0U) {
251 std::cout << msg_metadata_fail << std::endl;
253 loadAndPrintDelegations(storage);
258 if (vm.count(
"director-root") != 0U) {
260 std::cout << msg_metadata_fail << std::endl;
262 std::cout << director_root << std::endl;
267 if (vm.count(
"director-targets") != 0U || vm.count(
"director-target") != 0U) {
269 std::cout << msg_metadata_fail << std::endl;
271 std::string director_targets;
272 storage->loadNonRoot(&director_targets, Uptane::RepositoryType::Director(), Uptane::Role::Targets());
273 std::cout << director_targets << std::endl;
278 if (vm.count(
"image-snapshot") != 0U || vm.count(
"images-snapshot") != 0U) {
280 std::cout << msg_metadata_fail << std::endl;
282 std::string snapshot;
283 storage->loadNonRoot(&snapshot, Uptane::RepositoryType::Image(), Uptane::Role::Snapshot());
284 std::cout << snapshot << std::endl;
289 if (vm.count(
"image-timestamp") != 0U || vm.count(
"images-timestamp") != 0U) {
291 std::cout << msg_metadata_fail << std::endl;
293 std::string timestamp;
294 storage->loadNonRoot(×tamp, Uptane::RepositoryType::Image(), Uptane::Role::Timestamp());
295 std::cout << timestamp << std::endl;
304 if (!deviceid_loaded && !tlscred_loaded && ecukeys_loaded) {
310 if (!deviceid_loaded) {
311 std::cout <<
"Couldn't load device ID" << std::endl;
313 std::cout <<
"Device ID: " << device_id << std::endl;
317 std::string ecu_name = secondary_db ?
"Secondary" :
"Primary";
319 if (!storage->loadEcuSerials(&serials)) {
320 std::cout <<
"Couldn't load ECU serials" << std::endl;
321 }
else if (serials.size() == 0) {
322 std::cout << ecu_name <<
" serial is not found" << std::endl;
324 std::cout << ecu_name <<
" ECU serial ID: " << serials[0].first << std::endl;
325 std::cout << ecu_name <<
" ECU hardware ID: " << serials[0].second << std::endl;
328 if (serials.size() > 1) {
329 auto it = serials.begin() + 1;
330 std::cout <<
"Secondaries:\n";
331 int secondary_number = 1;
332 for (; it != serials.end(); ++it) {
333 std::cout << secondary_number++ <<
") serial ID: " << it->first << std::endl;
334 std::cout <<
" hardware ID: " << it->second << std::endl;
336 boost::optional<Uptane::Target> current_version;
337 boost::optional<Uptane::Target> pending_version;
339 auto load_installed_version_res =
340 storage->loadInstalledVersions((it->first).ToString(), ¤t_version, &pending_version);
342 if (!load_installed_version_res || (!current_version && !pending_version)) {
343 std::cout <<
" no details about installed nor pending images\n";
345 if (!!current_version) {
346 std::cout <<
" installed image hash: " << current_version->sha256Hash() <<
"\n";
347 std::cout <<
" installed image filename: " << current_version->filename() <<
"\n";
349 if (!!pending_version) {
350 std::cout <<
" pending image hash: " << pending_version->sha256Hash() <<
"\n";
351 std::cout <<
" pending image filename: " << pending_version->filename() <<
"\n";
357 std::vector<MisconfiguredEcu> misconfigured_ecus;
358 storage->loadMisconfiguredEcus(&misconfigured_ecus);
359 if (misconfigured_ecus.size() != 0U) {
360 std::cout <<
"Removed or not registered ECUs:" << std::endl;
361 std::vector<MisconfiguredEcu>::const_iterator it;
362 for (it = misconfigured_ecus.begin(); it != misconfigured_ecus.end(); ++it) {
363 std::cout <<
" '" << it->serial <<
"' with hardware_id '" << it->hardware_id <<
"' " 364 << (it->state == EcuState::kOld ?
"has been removed from config" :
"not registered yet") << std::endl;
369 std::cout <<
"Provisioned on server: " << (registered ?
"yes" :
"no") << std::endl;
371 std::cout <<
"Fetched metadata: " << (has_metadata ?
"yes" :
"no") << std::endl;
373 auto pacman = PackageManagerFactory::makePackageManager(config.pacman, config.bootloader, storage,
nullptr);
377 if (current_target.IsValid()) {
378 std::cout <<
"Current " << ecu_name <<
" ECU running version: " << current_target.sha256Hash() << std::endl;
380 std::cout <<
"No currently running version on " << ecu_name <<
" ECU" << std::endl;
383 std::vector<Uptane::Target> installed_versions;
384 boost::optional<Uptane::Target> pending;
385 storage->loadPrimaryInstalledVersions(
nullptr, &pending);
388 std::cout <<
"Pending " << ecu_name <<
" ECU version: " << pending->sha256Hash() << std::endl;
390 }
catch (
const bpo::error &o) {
391 std::cout << o.what() << std::endl << description;
394 }
catch (
const std::exception &exc) {
395 std::cerr <<
"Error: " << exc.what() << std::endl;