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");
51 bpo::positional_options_description pos;
52 pos.add(
"run-mode", 1);
54 bpo::variables_map vm;
55 std::vector<std::string> unregistered_options;
57 bpo::basic_parsed_options<char> parsed_options =
58 bpo::command_line_parser(argc, argv).options(description).positional(pos).allow_unregistered().run();
59 bpo::store(parsed_options, vm);
60 checkInfoOptions(description, vm);
62 unregistered_options = bpo::collect_unrecognized(parsed_options.options, bpo::exclude_positional);
63 if (vm.count(
"help") == 0 && !unregistered_options.empty()) {
64 std::cout << description <<
"\n";
67 }
catch (
const bpo::required_option &ex) {
69 std::cout << ex.what() << std::endl << description;
71 }
catch (
const bpo::error &ex) {
72 checkInfoOptions(description, vm);
75 LOG_ERROR <<
"boost command line option error: " << ex.what();
79 std::cout << ex.what() <<
'\n';
89 void processEvent(
const std::shared_ptr<event::BaseEvent> &
event) {
92 }
else if (
event->variant ==
"UpdateCheckComplete") {
94 }
else if (
event->variant ==
"AllDownloadsComplete") {
95 const auto downloads_complete = dynamic_cast<event::AllDownloadsComplete *>(
event.get());
96 LOG_INFO <<
"got " <<
event->variant <<
" event with status: " << downloads_complete->result.status;
97 }
else if (
event->variant ==
"AllInstallsComplete") {
98 const auto installs_complete = dynamic_cast<event::AllInstallsComplete *>(
event.get());
99 LOG_INFO <<
"got " <<
event->variant <<
" event with status: " << installs_complete->result.dev_report.result_code;
101 LOG_INFO <<
"got " <<
event->variant <<
" event";
105 int main(
int argc,
char *argv[]) {
107 logger_set_threshold(boost::log::trivial::info);
109 bpo::variables_map commandline_map = parseOptions(argc, argv);
111 LOG_INFO <<
"Aktualizr version " << aktualizr_version() <<
" starting";
113 int r = EXIT_FAILURE;
116 if (geteuid() != 0) {
117 LOG_WARNING <<
"\033[31mAktualizr is currently running as non-root and may not work as expected! Aktualizr "
118 "should be run as root for proper functionality.\033[0m\n";
120 Config config(commandline_map);
121 LOG_DEBUG <<
"Current directory: " << boost::filesystem::current_path().string();
124 std::function<void(std::shared_ptr<event::BaseEvent>
event)> f_cb = processEvent;
125 boost::signals2::scoped_connection conn;
127 conn = aktualizr.SetSignalHandler(f_cb);
129 if (!config.uptane.secondary_config_file.empty()) {
131 Primary::initSecondaries(aktualizr, config.uptane.secondary_config_file);
132 }
catch (
const std::exception &e) {
133 LOG_ERROR <<
"Failed to init secondaries :" << e.what();
134 LOG_ERROR <<
"Exiting...";
139 aktualizr.Initialize();
142 SigHandler::get().start([&aktualizr]() {
144 aktualizr.Shutdown();
146 SigHandler::signal(SIGHUP);
147 SigHandler::signal(SIGINT);
148 SigHandler::signal(SIGTERM);
150 std::string run_mode;
151 if (commandline_map.count(
"run-mode") != 0) {
152 run_mode = commandline_map[
"run-mode"].as<std::string>();
155 if (run_mode ==
"campaign_check") {
156 aktualizr.CampaignCheck().get();
157 }
else if (run_mode ==
"campaign_accept" || run_mode ==
"campaign_decline" || run_mode ==
"campaign_postpone") {
158 if (commandline_map.count(
"campaign-id") == 0) {
159 throw std::runtime_error(run_mode +
" requires a campaign ID");
161 aktualizr.CampaignControl(commandline_map[
"campaign-id"].as<std::string>(), campaign::cmdFromName(run_mode))
163 }
else if (run_mode ==
"check") {
164 aktualizr.SendDeviceData().get();
165 aktualizr.CheckUpdates().get();
166 }
else if (run_mode ==
"download") {
168 aktualizr.Download(update_result.updates).get();
169 }
else if (run_mode ==
"install") {
171 aktualizr.Install(update_result.updates).get();
172 }
else if (run_mode ==
"once") {
173 aktualizr.SendDeviceData().get();
174 aktualizr.UptaneCycle();
176 boost::signals2::connection ac_conn =
177 aktualizr.SetSignalHandler(std::bind(targets_autoclean_cb, std::ref(aktualizr), std::placeholders::_1));
180 aktualizr.RunForever().get();
181 }
catch (
const std::exception &ex) {
182 LOG_ERROR << ex.what();
185 LOG_DEBUG <<
"Aktualizr daemon exiting...";
188 }
catch (
const std::exception &ex) {
189 LOG_ERROR << ex.what();