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