Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
aktualizr.h
1 #ifndef AKTUALIZR_H_
2 #define AKTUALIZR_H_
3 
4 #include <future>
5 #include <memory>
6 
7 #include <boost/signals2.hpp>
8 
9 #include "libaktualizr/config.h"
10 #include "libaktualizr/events.h"
11 #include "libaktualizr/secondaryinterface.h"
12 
13 class SotaUptaneClient;
14 class INvStorage;
15 
16 namespace api {
17 class CommandQueue;
18 }
19 
20 /**
21  * This class provides the main APIs necessary for launching and controlling
22  * libaktualizr.
23  */
24 class Aktualizr {
25  public:
26  /** Aktualizr requires a configuration object. Examples can be found in the
27  * config directory.
28  *
29  * @throw SQLException
30  * @throw boost::filesystem::filesystem_error
31  * @throw std::bad_alloc
32  * @throw std::runtime_error (filesystem and json parsing failures; libsodium initialization failure)
33  */
34  explicit Aktualizr(const Config& config);
35 
36  Aktualizr(const Aktualizr&) = delete;
37  Aktualizr& operator=(const Aktualizr&) = delete;
38  ~Aktualizr();
39 
40  /**
41  * Initialize aktualizr. Any Secondaries should be added before making this
42  * call. This will provision with the server if required. This must be called
43  * before using any other aktualizr functions except AddSecondary.
44  *
45  * @throw Initializer::Error and subclasses
46  * @throw Uptane::Exception and subclasses
47  * @throw SQLException
48  * @throw boost::filesystem::filesystem_error
49  * @throw std::system_error (failure to lock a mutex)
50  * @throw std::bad_alloc (memory allocation failure)
51  * @throw std::runtime_error (curl, P11, SQL, filesystem, credentials archive
52  * parsing, certificate parsing, json parsing
53  * failures; missing ECU serials or device ID;
54  * database inconsistency with pending updates;
55  * invalid OSTree deployment)
56  */
57  void Initialize();
58 
59  /**
60  * Asynchronously run aktualizr indefinitely until Shutdown is called.
61  * @param custom_hwinfo if not empty will be sent to the backend instead of `lshw` output
62  * @return Empty std::future object
63  *
64  * @throw SQLException
65  * @throw boost::filesystem::filesystem_error
66  * @throw std::system_error (failure to lock a mutex)
67  * @throw std::bad_alloc
68  * @throw std::runtime_error (curl, SQL, filesystem, and json parsing failures;
69  * database inconsistency with pending updates;
70  * error getting metadata from database or filesystem)
71  */
72  std::future<void> RunForever(const Json::Value& custom_hwinfo = Json::nullValue);
73 
74  /**
75  * Shuts down currently running `RunForever()` method
76  *
77  * @throw std::system_error (failure to lock a mutex)
78  */
79  void Shutdown();
80 
81  /**
82  * Check for campaigns.
83  * Campaigns are a concept outside of Uptane, and allow for user approval of
84  * updates before the contents of the update are known.
85  * @return std::future object with data about available campaigns.
86  *
87  * @throw std::runtime_error (curl and json parsing failures)
88  */
89  std::future<result::CampaignCheck> CampaignCheck();
90 
91  /**
92  * Act on campaign: accept, decline or postpone.
93  * Accepted campaign will be removed from the campaign list but no guarantee
94  * is made for declined or postponed items. Applications are responsible for
95  * tracking their state but this method will notify the server for device
96  * state monitoring purposes.
97  * @param campaign_id Campaign ID as provided by CampaignCheck.
98  * @param cmd action to apply on the campaign: accept, decline or postpone
99  * @return Empty std::future object
100  *
101  * @throw std::bad_alloc (memory allocation failure)
102  */
103  std::future<void> CampaignControl(const std::string& campaign_id, campaign::Cmd cmd);
104 
105  /**
106  * Send local device data to the server.
107  * This includes network status, installed packages, hardware etc.
108  * @param custom_hwinfo if not empty will be sent to the backend instead of `lshw` output
109  * @return Empty std::future object
110  *
111  * @throw SQLException
112  * @throw boost::filesystem::filesystem_error
113  * @throw std::bad_alloc
114  * @throw std::runtime_error (curl, filesystem, and json parsing failures)
115  */
116  std::future<void> SendDeviceData(const Json::Value& custom_hwinfo = Json::nullValue);
117 
118  /**
119  * Fetch Uptane metadata and check for updates.
120  * This collects a client manifest, PUTs it to the director, updates the
121  * Uptane metadata (including root and targets), and then checks the metadata
122  * for target updates.
123  * @return Information about available updates.
124  *
125  * @throw SQLException
126  * @throw boost::filesystem::filesystem_error
127  * @throw std::bad_alloc
128  * @throw std::runtime_error (curl, SQL, filesystem, and json parsing failures;
129  * database inconsistency with pending updates)
130  */
131  std::future<result::UpdateCheck> CheckUpdates();
132 
133  /**
134  * Download targets.
135  * @param updates Vector of targets to download as provided by CheckUpdates.
136  * @return std::future object with information about download results.
137  *
138  * @throw SQLException
139  * @throw std::system_error (failure to lock a mutex)
140  */
141  std::future<result::Download> Download(const std::vector<Uptane::Target>& updates);
142 
144  Uptane::EcuSerial ecu;
145  std::vector<Uptane::Target> installs;
146  };
147  using InstallationLog = std::vector<InstallationLogEntry>;
148 
149  /**
150  * Get log of installations. The log is indexed for every ECU and contains
151  * every change of versions ordered by time. It may contain duplicates in
152  * case of rollbacks.
153  * @return installation log
154  *
155  * @throw SQLException
156  * @throw std::bad_alloc (memory allocation failure)
157  * @throw std::runtime_error (failure to load ECU serials)
158  */
159  InstallationLog GetInstallationLog();
160 
161  /**
162  * Get list of targets currently in storage. This is intended to be used with
163  * DeleteStoredTarget and targets are not guaranteed to be verified and
164  * up-to-date with current metadata.
165  * @return std::vector of target objects
166  *
167  * @throw SQLException
168  * @throw std::bad_alloc (memory allocation failure)
169  * @throw std::runtime_error (error getting targets from database)
170  */
171  std::vector<Uptane::Target> GetStoredTargets();
172 
173  /**
174  * Delete a stored target from storage. This only affects storage of the
175  * actual binary data and does not preclude a re-download if a target matches
176  * current metadata.
177  * @param target Target object matching the desired target in the storage
178  * @return true if successful
179  *
180  * @throw SQLException
181  * @throw std::runtime_error (error getting targets from database or filesystem)
182  */
183  void DeleteStoredTarget(const Uptane::Target& target);
184 
185  /**
186  * Get target downloaded in Download call. Returned target is guaranteed to be verified and up-to-date
187  * according to the Uptane metadata downloaded in CheckUpdates call.
188  * @param target Target object matching the desired target in the storage.
189  * @return Handle to the stored binary. nullptr if none is found.
190  *
191  * @throw SQLException
192  * @throw std::runtime_error (error getting targets from database or filesystem)
193  */
194  std::ifstream OpenStoredTarget(const Uptane::Target& target);
195 
196  /**
197  * Install targets.
198  * @param updates Vector of targets to install as provided by CheckUpdates or
199  * Download.
200  * @return std::future object with information about installation results.
201  *
202  * @throw SQLException
203  * @throw std::runtime_error (error getting metadata from database or filesystem)
204  */
205  std::future<result::Install> Install(const std::vector<Uptane::Target>& updates);
206 
207  /**
208  * SetInstallationRawReport allows setting a custom raw report field in the device installation result.
209  *
210  * @note An invocation of this method will have effect only after call of Aktualizr::Install and before calling
211  * Aktualizr::SendManifest member function.
212  * @param custom_raw_report is intended to replace a default value in the device installation report.
213  * @return true if the custom raw report was successfully applied to the device installation result.
214  * If there is no installation report in the storage the function will always return false.
215  *
216  * @throw SQLException
217  */
218  bool SetInstallationRawReport(const std::string& custom_raw_report);
219 
220  /**
221  * Send installation report to the backend.
222  *
223  * @note The device manifest is also sent as a part of CheckUpdates and
224  * SendDeviceData calls, as well as after a reboot if it was initiated
225  * by Aktualizr as a part of an installation process.
226  * All these manifests will not include the custom data provided in this call.
227  *
228  * @param custom Project-specific data to put in the custom field of Uptane manifest
229  * @return std::future object with manifest update result (true on success).
230  *
231  * @throw SQLException
232  * @throw std::runtime_error (curl failures; database inconsistency with pending updates)
233  */
234  std::future<bool> SendManifest(const Json::Value& custom = Json::nullValue);
235 
236  /**
237  * Pause the library operations.
238  * In progress target downloads will be paused and API calls will be deferred.
239  *
240  * @return Information about pause results.
241  *
242  * @throw std::system_error (failure to lock a mutex)
243  * @throw std::bad_alloc
244  */
246 
247  /**
248  * Resume the library operations.
249  * Target downloads will resume and API calls issued during the pause will
250  * execute in fifo order.
251  *
252  * @return Information about resume results.
253  *
254  * @throw std::system_error (failure to lock a mutex)
255  * @throw std::bad_alloc
256  */
258 
259  /**
260  * Aborts the currently running command, if it can be aborted, or waits for it
261  * to finish; then removes all other queued calls.
262  * This doesn't reset the `Paused` state, i.e. if the queue was previously
263  * paused, it will remain paused, but with an emptied queue.
264  * The call is blocking.
265  *
266  * @throw std::system_error (failure to lock a mutex)
267  */
268  void Abort();
269 
270  /**
271  * Synchronously run an Uptane cycle: check for updates, download any new
272  * targets, install them, and send a manifest back to the server.
273  *
274  * @return `false`, if the restart is required to continue, `true` otherwise
275  *
276  * @throw SQLException
277  * @throw boost::filesystem::filesystem_error
278  * @throw std::system_error (failure to lock a mutex)
279  * @throw std::bad_alloc
280  * @throw std::runtime_error (curl, SQL, filesystem, and json parsing failures;
281  * database inconsistency with pending updates;
282  * error getting metadata from database or filesystem)
283  */
284  bool UptaneCycle();
285 
286  /**
287  * Add new Secondary to aktualizr. Must be called before Initialize.
288  * @param secondary An object to perform installation on a Secondary ECU.
289  *
290  * @throw std::bad_alloc (memory allocation failure)
291  * @throw std::runtime_error (multiple Secondaries with the same serial)
292  */
293  void AddSecondary(const std::shared_ptr<SecondaryInterface>& secondary);
294 
295  /**
296  * Store some free-form data to be associated with a particular Secondary, to
297  * be retrieved later through `GetSecondaries`
298  *
299  * @throw SQLException
300  * @throw std::runtime_error (SQL failure)
301  */
302  void SetSecondaryData(const Uptane::EcuSerial& ecu, const std::string& data);
303 
304  /**
305  * Returns a list of the registered Secondaries, along with some associated
306  * metadata
307  *
308  * @return vector of SecondaryInfo objects
309  *
310  * @throw SQLException
311  * @throw std::bad_alloc (memory allocation failure)
312  */
313  std::vector<SecondaryInfo> GetSecondaries() const;
314 
315  // The type proxy is needed in doxygen 1.8.16 because of this bug
316  // https://github.com/doxygen/doxygen/issues/7236
317  using SigHandler = std::function<void(std::shared_ptr<event::BaseEvent>)>;
318 
319  /**
320  * Provide a function to receive event notifications.
321  * @param handler a function that can receive event objects.
322  * @return a signal connection object, which can be disconnected if desired.
323  */
324  boost::signals2::connection SetSignalHandler(const SigHandler& handler);
325 
326  private:
327  // Make sure this is declared before SotaUptaneClient to prevent Valgrind
328  // complaints with destructors.
329  Config config_;
330 
331  protected:
332  Aktualizr(Config config, std::shared_ptr<INvStorage> storage_in, const std::shared_ptr<HttpInterface>& http_in);
333 
334  std::shared_ptr<SotaUptaneClient> uptane_client_;
335 
336  private:
337  struct {
338  std::mutex m;
339  std::condition_variable cv;
340  bool flag = false;
341  } exit_cond_;
342 
343  std::shared_ptr<INvStorage> storage_;
344  std::shared_ptr<event::Channel> sig_;
345  std::unique_ptr<api::CommandQueue> api_queue_;
346 };
347 
348 #endif // AKTUALIZR_H_
Aktualizr::Resume
result::Pause Resume()
Resume the library operations.
Definition: aktualizr.cc:181
Aktualizr::Install
std::future< result::Install > Install(const std::vector< Uptane::Target > &updates)
Install targets.
Definition: aktualizr.cc:158
Aktualizr::SendDeviceData
std::future< void > SendDeviceData(const Json::Value &custom_hwinfo=Json::nullValue)
Send local device data to the server.
Definition: aktualizr.cc:142
Aktualizr::OpenStoredTarget
std::ifstream OpenStoredTarget(const Uptane::Target &target)
Get target downloaded in Download call.
Definition: aktualizr.cc:223
Aktualizr::Aktualizr
Aktualizr(const Config &config)
Aktualizr requires a configuration object.
Definition: aktualizr.cc:15
Aktualizr::DeleteStoredTarget
void DeleteStoredTarget(const Uptane::Target &target)
Delete a stored target from storage.
Definition: aktualizr.cc:221
SotaUptaneClient
Definition: sotauptaneclient.h:35
Aktualizr::RunForever
std::future< void > RunForever(const Json::Value &custom_hwinfo=Json::nullValue)
Asynchronously run aktualizr indefinitely until Shutdown is called.
Definition: aktualizr.cc:75
Aktualizr::SendManifest
std::future< bool > SendManifest(const Json::Value &custom=Json::nullValue)
Send installation report to the backend.
Definition: aktualizr.cc:167
Aktualizr::CampaignControl
std::future< void > CampaignControl(const std::string &campaign_id, campaign::Cmd cmd)
Act on campaign: accept, decline or postpone.
Definition: aktualizr.cc:123
Aktualizr::SetInstallationRawReport
bool SetInstallationRawReport(const std::string &custom_raw_report)
SetInstallationRawReport allows setting a custom raw report field in the device installation result.
Definition: aktualizr.cc:163
Aktualizr::Shutdown
void Shutdown()
Shuts down currently running RunForever() method.
Definition: aktualizr.cc:95
Aktualizr::Initialize
void Initialize()
Initialize aktualizr.
Definition: aktualizr.cc:33
Aktualizr::CheckUpdates
std::future< result::UpdateCheck > CheckUpdates()
Fetch Uptane metadata and check for updates.
Definition: aktualizr.cc:147
data
General data structures.
Definition: types.h:217
Aktualizr::CampaignCheck
std::future< result::CampaignCheck > CampaignCheck()
Check for campaigns.
Definition: aktualizr.cc:118
Config
Configuration object for an aktualizr instance running on a Primary ECU.
Definition: config.h:208
events.h
Uptane::EcuSerial
Definition: types.h:354
Aktualizr
This class provides the main APIs necessary for launching and controlling libaktualizr.
Definition: aktualizr.h:24
Aktualizr::AddSecondary
void AddSecondary(const std::shared_ptr< SecondaryInterface > &secondary)
Add new Secondary to aktualizr.
Definition: aktualizr.cc:103
Aktualizr::Abort
void Abort()
Aborts the currently running command, if it can be aborted, or waits for it to finish; then removes a...
Definition: aktualizr.cc:190
Aktualizr::GetStoredTargets
std::vector< Uptane::Target > GetStoredTargets()
Get list of targets currently in storage.
Definition: aktualizr.cc:219
Aktualizr::InstallationLogEntry
Definition: aktualizr.h:143
result::Pause
Definition: results.h:68
Aktualizr::SetSignalHandler
boost::signals2::connection SetSignalHandler(const SigHandler &handler)
Provide a function to receive event notifications.
Definition: aktualizr.cc:192
SigHandler
Definition: sig_handler.h:13
Aktualizr::GetSecondaries
std::vector< SecondaryInfo > GetSecondaries() const
Returns a list of the registered Secondaries, along with some associated metadata.
Definition: aktualizr.cc:111
Aktualizr::GetInstallationLog
InstallationLog GetInstallationLog()
Get log of installations.
Definition: aktualizr.cc:197
Aktualizr::UptaneCycle
bool UptaneCycle()
Synchronously run an Uptane cycle: check for updates, download any new targets, install them,...
Definition: aktualizr.cc:38
Uptane::Target
Definition: types.h:387
Aktualizr::SetSecondaryData
void SetSecondaryData(const Uptane::EcuSerial &ecu, const std::string &data)
Store some free-form data to be associated with a particular Secondary, to be retrieved later through...
Definition: aktualizr.cc:107
INvStorage
Definition: invstorage.h:43
Aktualizr::Download
std::future< result::Download > Download(const std::vector< Uptane::Target > &updates)
Download targets.
Definition: aktualizr.cc:152
Aktualizr::Pause
result::Pause Pause()
Pause the library operations.
Definition: aktualizr.cc:172