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 description(
"aktualizr-info command line options");
50 description.add_options()
51 (
"help,h",
"print usage")
52 (
"version,v",
"Current aktualizr version")
53 (
"config,c", bpo::value<std::vector<boost::filesystem::path> >()->composing(),
"configuration file or directory")
54 (
"loglevel", bpo::value<int>(),
"set log level 0-5 (trace, debug, info, warning, error, fatal)")
55 (
"name-only",
"Only output device name (intended for scripting). Cannot be used in combination with other arguments.")
56 (
"tls-creds",
"Outputs TLS credentials")
57 (
"tls-root-ca",
"Outputs TLS Root CA")
58 (
"tls-cert",
"Outputs TLS client certificate")
59 (
"tls-prv-key",
"Output TLS client private key")
60 (
"ecu-keys",
"Outputs UPTANE keys")
61 (
"ecu-pub-key",
"Outputs UPTANE public key")
62 (
"ecu-prv-key",
"Outputs UPTANE private key")
63 (
"images-root",
"Outputs root.json from images repo")
64 (
"images-timestamp",
"Outputs timestamp.json from images repo")
65 (
"images-snapshot",
"Outputs snapshot.json from images repo")
66 (
"images-target",
"Outputs targets.json from images repo")
67 (
"delegation",
"Outputs metadata of image repo targets' delegations")
68 (
"director-root",
"Outputs root.json from director repo")
69 (
"director-target",
"Outputs targets.json from director repo")
70 (
"allow-migrate",
"Opens database in read/write mode to make possible to migrate database if needed")
71 (
"wait-until-provisioned",
"Outputs metadata when device already provisioned");
75 bpo::variables_map vm;
76 std::vector<std::string> unregistered_options;
77 bpo::basic_parsed_options<char> parsed_options = bpo::command_line_parser(argc, argv).options(description).run();
78 bpo::store(parsed_options, vm);
79 checkInfoOptions(description, vm);
81 unregistered_options = bpo::collect_unrecognized(parsed_options.options, bpo::include_positional);
82 if (vm.count(
"help") == 0 && !unregistered_options.empty()) {
83 std::cout << description <<
"\n";
87 if (vm.count(
"loglevel") == 0u) {
88 logger_set_enable(
false);
94 if (vm.count(
"allow-migrate") != 0u) {
98 bool wait_provisioning =
false;
99 if (vm.count(
"wait-until-provisioned") != 0) {
100 wait_provisioning =
true;
103 std::shared_ptr<INvStorage> storage;
104 bool cmd_trigger =
false;
105 std::string device_id;
107 bool registered =
false;
108 bool has_metadata =
false;
109 std::string director_root;
110 if (wait_provisioning) {
111 while (!registered || !has_metadata) {
113 storage = INvStorage::newStorage(config.storage, readonly);
115 registered = storage->loadEcuRegistered();
116 has_metadata = storage->loadLatestRoot(&director_root, Uptane::RepositoryType::Director());
117 }
catch (std::exception &e) {
124 storage = INvStorage::newStorage(config.storage, readonly);
127 if (!storage->loadDeviceId(&device_id)) {
128 std::cout <<
"Couldn't load device ID" << std::endl;
131 if (vm.count(
"name-only") != 0u) {
132 std::cout << device_id << std::endl;
137 registered = registered || storage->loadEcuRegistered();
138 has_metadata = has_metadata || storage->loadLatestRoot(&director_root, Uptane::RepositoryType::Director());
141 if (vm.count(
"tls-creds") != 0u) {
146 storage->loadTlsCreds(&ca, &cert, &pkey);
147 std::cout <<
"Root CA certificate:" << std::endl << ca << std::endl;
148 std::cout <<
"Client certificate:" << std::endl << cert << std::endl;
149 std::cout <<
"Client private key:" << std::endl << pkey << std::endl;
153 if (vm.count(
"tls-root-ca") != 0u) {
155 storage->loadTlsCa(&ca);
156 std::cout << ca << std::endl;
160 if (vm.count(
"tls-cert") != 0u) {
162 storage->loadTlsCert(&cert);
163 std::cout << cert << std::endl;
167 if (vm.count(
"tls-prv-key") != 0u) {
169 storage->loadTlsPkey(&key);
170 std::cout << key << std::endl;
175 if (vm.count(
"ecu-keys") != 0u) {
179 storage->loadPrimaryKeys(&pub, &priv);
180 std::cout <<
"Public key:" << std::endl << pub << std::endl;
181 std::cout <<
"Private key:" << std::endl << priv << std::endl;
185 if (vm.count(
"ecu-pub-key") != 0u) {
187 storage->loadPrimaryPublic(&key);
188 std::cout << key << std::endl;
192 if (vm.count(
"ecu-prv-key") != 0u) {
194 storage->loadPrimaryPrivate(&key);
195 std::cout << key << std::endl;
200 std::string msg_metadata_fail =
"Metadata is not available";
201 if (vm.count(
"images-root") != 0u) {
203 std::cout << msg_metadata_fail << std::endl;
205 std::string images_root;
206 storage->loadLatestRoot(&images_root, Uptane::RepositoryType::Image());
207 std::cout << images_root << std::endl;
212 if (vm.count(
"images-target") != 0u) {
214 std::cout << msg_metadata_fail << std::endl;
216 std::string images_targets;
217 storage->loadNonRoot(&images_targets, Uptane::RepositoryType::Image(), Uptane::Role::Targets());
218 std::cout << images_targets << std::endl;
223 if (vm.count(
"delegation") != 0u) {
225 std::cout << msg_metadata_fail << std::endl;
227 loadAndPrintDelegations(storage);
232 if (vm.count(
"director-root") != 0u) {
234 std::cout << msg_metadata_fail << std::endl;
236 std::cout << director_root << std::endl;
241 if (vm.count(
"director-target") != 0u) {
243 std::cout << msg_metadata_fail << std::endl;
245 std::string director_targets;
246 storage->loadNonRoot(&director_targets, Uptane::RepositoryType::Director(), Uptane::Role::Targets());
247 std::cout << director_targets << std::endl;
252 if (vm.count(
"images-snapshot") != 0u) {
254 std::cout << msg_metadata_fail << std::endl;
256 std::string snapshot;
257 storage->loadNonRoot(&snapshot, Uptane::RepositoryType::Image(), Uptane::Role::Snapshot());
258 std::cout << snapshot << std::endl;
263 if (vm.count(
"images-timestamp") != 0u) {
265 std::cout << msg_metadata_fail << std::endl;
267 std::string timestamp;
268 storage->loadNonRoot(×tamp, Uptane::RepositoryType::Image(), Uptane::Role::Timestamp());
269 std::cout << timestamp << std::endl;
279 std::cout <<
"Device ID: " << device_id << std::endl;
281 if (!storage->loadEcuSerials(&serials)) {
282 std::cout <<
"Couldn't load ECU serials" << std::endl;
283 }
else if (serials.size() == 0) {
284 std::cout <<
"Primary serial is not found" << std::endl;
286 std::cout <<
"Primary ecu serial ID: " << serials[0].first << std::endl;
287 std::cout <<
"Primary ecu hardware ID: " << serials[0].second << std::endl;
290 if (serials.size() > 1) {
291 auto it = serials.begin() + 1;
292 std::cout <<
"Secondaries:\n";
293 int secondary_number = 1;
294 for (; it != serials.end(); ++it) {
295 std::cout << secondary_number++ <<
") serial ID: " << it->first << std::endl;
296 std::cout <<
" hardware ID: " << it->second << std::endl;
298 boost::optional<Uptane::Target> current_version;
299 boost::optional<Uptane::Target> pending_version;
301 auto load_installed_version_res =
302 storage->loadInstalledVersions((it->first).ToString(), ¤t_version, &pending_version);
304 if (!load_installed_version_res || (!current_version && !pending_version)) {
305 std::cout <<
" no details about installed nor pending images\n";
307 if (!!current_version) {
308 std::cout <<
" installed image hash: " << current_version->sha256Hash() <<
"\n";
309 std::cout <<
" installed image filename: " << current_version->filename() <<
"\n";
311 if (!!pending_version) {
312 std::cout <<
" pending image hash: " << pending_version->sha256Hash() <<
"\n";
313 std::cout <<
" pending image filename: " << pending_version->filename() <<
"\n";
319 std::vector<MisconfiguredEcu> misconfigured_ecus;
320 storage->loadMisconfiguredEcus(&misconfigured_ecus);
321 if (misconfigured_ecus.size() != 0u) {
322 std::cout <<
"Removed or not registered ecus:" << std::endl;
323 std::vector<MisconfiguredEcu>::const_iterator it;
324 for (it = misconfigured_ecus.begin(); it != misconfigured_ecus.end(); ++it) {
325 std::cout <<
" '" << it->serial <<
"' with hardware_id '" << it->hardware_id <<
"' "
326 << (it->state == EcuState::kOld ?
"has been removed from config" :
"not registered yet") << std::endl;
330 std::cout <<
"Provisioned on server: " << (registered ?
"yes" :
"no") << std::endl;
331 std::cout <<
"Fetched metadata: " << (has_metadata ?
"yes" :
"no") << std::endl;
333 auto pacman = PackageManagerFactory::makePackageManager(config.pacman, config.bootloader, storage,
nullptr);
337 if (current_target.IsValid()) {
338 std::cout <<
"Current primary ecu running version: " << current_target.sha256Hash() << std::endl;
340 std::cout <<
"No currently running version on primary ecu" << std::endl;
343 std::vector<Uptane::Target> installed_versions;
344 boost::optional<Uptane::Target> pending;
345 storage->loadPrimaryInstalledVersions(
nullptr, &pending);
348 std::cout <<
"Pending primary ecu version: " << pending->sha256Hash() << std::endl;
350 }
catch (
const bpo::error &o) {
351 std::cout << o.what() << std::endl;
352 std::cout << description;
355 }
catch (
const std::exception &exc) {
356 std::cerr <<
"Error: " << exc.what() << std::endl;