3 #include <boost/filesystem.hpp>
4 #include <boost/program_options.hpp>
5 #include <boost/property_tree/ini_parser.hpp>
6 #include <boost/signals2.hpp>
8 #include "config/config.h"
9 #include "logging/logging.h"
10 #include "primary/aktualizr.h"
11 #include "primary/aktualizr_helpers.h"
12 #include "secondary.h"
13 #include "utilities/aktualizr_version.h"
14 #include "utilities/sig_handler.h"
15 #include "utilities/utils.h"
17 namespace bpo = boost::program_options;
19 void checkInfoOptions(
const bpo::options_description &description,
const bpo::variables_map &vm) {
20 if (vm.count(
"help") != 0) {
21 std::cout << description <<
'\n';
24 if (vm.count(
"version") != 0) {
25 std::cout <<
"Current aktualizr version is: " << aktualizr_version() <<
"\n";
30 bpo::variables_map parseOptions(
int argc,
char *argv[]) {
31 bpo::options_description description(
"aktualizr command line options");
35 description.add_options()
36 (
"help,h",
"print usage")
37 (
"version,v",
"Current aktualizr version")
38 (
"config,c", bpo::value<std::vector<boost::filesystem::path> >()->composing(),
"configuration file or directory")
39 (
"loglevel", bpo::value<int>(),
"set log level 0-5 (trace, debug, info, warning, error, fatal)")
40 (
"run-mode", bpo::value<std::string>(),
"run mode of aktualizr: full, once, campaign_check, campaign_accept, campaign_decline, campaign_postpone, check, download, or install")
41 (
"tls-server", bpo::value<std::string>(),
"URL of device gateway")
42 (
"repo-server", bpo::value<std::string>(),
"URL of the Uptane Image repository")
43 (
"director-server", bpo::value<std::string>(),
"URL of the Uptane Director repository")
44 (
"primary-ecu-serial", bpo::value<std::string>(),
"serial number of Primary ECU")
45 (
"primary-ecu-hardware-id", bpo::value<std::string>(),
"hardware ID of Primary ECU")
46 (
"secondary-config-file", bpo::value<boost::filesystem::path>(),
"Secondary ECUs configuration file")
47 (
"campaign-id", bpo::value<std::string>(),
"ID of the campaign to act on")
48 (
"hwinfo-file", bpo::value<boost::filesystem::path>(),
"custom hardware information JSON file");
52 bpo::positional_options_description pos;
53 pos.add(
"run-mode", 1);
55 bpo::variables_map vm;
56 std::vector<std::string> unregistered_options;
58 bpo::basic_parsed_options<char> parsed_options =
59 bpo::command_line_parser(argc, argv).options(description).positional(pos).allow_unregistered().run();
60 bpo::store(parsed_options, vm);
61 checkInfoOptions(description, vm);
63 unregistered_options = bpo::collect_unrecognized(parsed_options.options, bpo::exclude_positional);
64 if (vm.count(
"help") == 0 && !unregistered_options.empty()) {
65 std::cout << description <<
"\n";
68 }
catch (
const bpo::required_option &ex) {
70 std::cout << ex.what() << std::endl << description;
72 }
catch (
const bpo::error &ex) {
73 checkInfoOptions(description, vm);
76 LOG_ERROR <<
"boost command line option error: " << ex.what();
80 std::cout << ex.what() <<
'\n';
90 void processEvent(
const std::shared_ptr<event::BaseEvent> &
event) {
93 }
else if (
event->variant ==
"UpdateCheckComplete") {
95 }
else if (
event->variant ==
"AllDownloadsComplete") {
96 const auto downloads_complete = dynamic_cast<event::AllDownloadsComplete *>(
event.get());
97 LOG_INFO <<
"got " <<
event->variant <<
" event with status: " << downloads_complete->result.status;
98 }
else if (
event->variant ==
"AllInstallsComplete") {
99 const auto installs_complete = dynamic_cast<event::AllInstallsComplete *>(
event.get());
100 LOG_INFO <<
"got " <<
event->variant <<
" event with status: " << installs_complete->result.dev_report.result_code;
102 LOG_INFO <<
"got " <<
event->variant <<
" event";
106 int main(
int argc,
char *argv[]) {
108 logger_set_threshold(boost::log::trivial::info);
110 bpo::variables_map commandline_map = parseOptions(argc, argv);
112 LOG_INFO <<
"Aktualizr version " << aktualizr_version() <<
" starting";
114 int r = EXIT_FAILURE;
117 if (geteuid() != 0) {
118 LOG_WARNING <<
"\033[31mAktualizr is currently running as non-root and may not work as expected! Aktualizr "
119 "should be run as root for proper functionality.\033[0m\n";
121 Config config(commandline_map);
122 LOG_DEBUG <<
"Current directory: " << boost::filesystem::current_path().string();
125 std::function<void(std::shared_ptr<event::BaseEvent>
event)> f_cb = processEvent;
126 boost::signals2::scoped_connection conn;
128 conn = aktualizr.SetSignalHandler(f_cb);
130 if (!config.uptane.secondary_config_file.empty()) {
132 Primary::initSecondaries(aktualizr, config.uptane.secondary_config_file);
133 }
catch (
const std::exception &e) {
134 LOG_ERROR <<
"Failed to initialize Secondaries :" << e.what();
135 LOG_ERROR <<
"Exiting...";
140 aktualizr.Initialize();
143 SigHandler::get().start([&aktualizr]() {
145 aktualizr.Shutdown();
147 SigHandler::signal(SIGHUP);
148 SigHandler::signal(SIGINT);
149 SigHandler::signal(SIGTERM);
152 if (commandline_map.count(
"hwinfo-file") != 0) {
153 auto file = commandline_map[
"hwinfo-file"].as<boost::filesystem::path>();
154 hwinfo = Utils::parseJSONFile(file);
155 if (hwinfo.empty()) {
156 LOG_ERROR << file <<
" is not a valid JSON file";
161 std::string run_mode;
162 if (commandline_map.count(
"run-mode") != 0) {
163 run_mode = commandline_map[
"run-mode"].as<std::string>();
166 if (run_mode ==
"campaign_check") {
167 aktualizr.CampaignCheck().get();
168 }
else if (run_mode ==
"campaign_accept" || run_mode ==
"campaign_decline" || run_mode ==
"campaign_postpone") {
169 if (commandline_map.count(
"campaign-id") == 0) {
170 throw std::runtime_error(run_mode +
" requires a campaign ID");
172 aktualizr.CampaignControl(commandline_map[
"campaign-id"].as<std::string>(), campaign::cmdFromName(run_mode))
174 }
else if (run_mode ==
"check") {
175 aktualizr.SendDeviceData(hwinfo).get();
176 aktualizr.CheckUpdates().get();
177 }
else if (run_mode ==
"download") {
179 aktualizr.Download(update_result.updates).get();
180 }
else if (run_mode ==
"install") {
182 aktualizr.Install(update_result.updates).get();
183 }
else if (run_mode ==
"once") {
184 aktualizr.SendDeviceData(hwinfo).get();
185 aktualizr.UptaneCycle();
187 boost::signals2::connection ac_conn =
188 aktualizr.SetSignalHandler(std::bind(targets_autoclean_cb, std::ref(aktualizr), std::placeholders::_1));
191 aktualizr.RunForever(hwinfo).get();
192 }
catch (
const std::exception &ex) {
193 LOG_ERROR << ex.what();
196 LOG_DEBUG <<
"Aktualizr daemon exiting...";
199 }
catch (
const std::exception &ex) {
200 LOG_ERROR << ex.what();