Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
aktualizr_secondary_ostree.cc
1 #include "aktualizr_secondary_ostree.h"
2 #include "package_manager/ostreemanager.h"
3 #include "update_agent_ostree.h"
4 
5 AktualizrSecondaryOstree::AktualizrSecondaryOstree(const AktualizrSecondaryConfig& config)
6  : AktualizrSecondaryOstree(config, INvStorage::newStorage(config.storage)) {}
7 
8 AktualizrSecondaryOstree::AktualizrSecondaryOstree(const AktualizrSecondaryConfig& config,
9  const std::shared_ptr<INvStorage>& storage)
10  : AktualizrSecondary(config, storage) {
11  registerHandler(AKIpUptaneMes_PR_downloadOstreeRevReq, std::bind(&AktualizrSecondaryOstree::downloadOstreeRev, this,
12  std::placeholders::_1, std::placeholders::_2));
13 
14  std::shared_ptr<OstreeManager> pack_man =
15  std::make_shared<OstreeManager>(config.pacman, config.bootloader, AktualizrSecondary::storagePtr(), nullptr);
16  update_agent_ =
17  std::make_shared<OstreeUpdateAgent>(config.pacman.sysroot, keyMngr(), pack_man, config.uptane.ecu_hardware_id);
18 }
19 
20 void AktualizrSecondaryOstree::initialize() {
21  initPendingTargetIfAny();
22 
23  if (hasPendingUpdate()) {
24  LOG_INFO << "Found a pending target to be applied.";
25  // TODO(OTA-4545): refactor this to make it simpler as we don't need to persist/store
26  // an installation status of each ECU but store it just for a given secondary ECU
27  std::vector<Uptane::Target> installed_versions;
28  boost::optional<Uptane::Target> pending_target;
29  AktualizrSecondary::storage().loadInstalledVersions(serial().ToString(), nullptr, &pending_target);
30 
31  if (!!pending_target) {
32  data::InstallationResult install_res =
33  data::InstallationResult(data::ResultCode::Numeric::kUnknown, "Unknown installation error");
34  LOG_INFO << "Pending update found; attempting to apply it. Target hash: " << pending_target->sha256Hash();
35 
36  install_res = applyPendingInstall(*pending_target);
37 
38  if (install_res.result_code != data::ResultCode::Numeric::kNeedCompletion) {
39  AktualizrSecondary::storage().saveEcuInstallationResult(serial(), install_res);
40 
41  if (install_res.isSuccess()) {
42  LOG_INFO << "Pending update has been successfully applied: " << pending_target->sha256Hash();
43  AktualizrSecondary::storage().saveInstalledVersion(serial().ToString(), *pending_target,
44  InstalledVersionUpdateMode::kCurrent);
45  } else {
46  LOG_ERROR << "Application of the pending update has failed: (" << install_res.result_code.toString() << ")"
47  << install_res.description;
48  AktualizrSecondary::storage().saveInstalledVersion(serial().ToString(), *pending_target,
49  InstalledVersionUpdateMode::kNone);
50  }
51 
52  directorRepo().dropTargets(AktualizrSecondary::storage());
53  } else {
54  LOG_INFO << "Pending update hasn't been applied because a reboot hasn't been detected";
55  }
56  }
57  }
58 }
59 
60 MsgHandler::ReturnCode AktualizrSecondaryOstree::downloadOstreeRev(Asn1Message& in_msg, Asn1Message& out_msg) {
61  LOG_INFO << "Received an OSTree download request; attempting download...";
62  auto result = downloadOstreeUpdate(ToString(in_msg.downloadOstreeRevReq()->tlsCred));
63 
64  auto m = out_msg.present(AKIpUptaneMes_PR_downloadOstreeRevResp).downloadOstreeRevResp();
65  m->result = static_cast<AKInstallationResultCode_t>(result.result_code.num_code);
66  SetString(&m->description, result.description);
67 
68  return ReturnCode::kOk;
69 }
70 
71 data::InstallationResult AktualizrSecondaryOstree::downloadOstreeUpdate(const std::string& packed_tls_creds) {
72  if (!pendingTarget().IsValid()) {
73  LOG_ERROR << "Aborting image download; no valid target found.";
75  "Aborting image download; no valid target found.");
76  }
77 
78  auto result = update_agent_->downloadTargetRev(pendingTarget(), packed_tls_creds);
79  if (!result.isSuccess()) {
80  pendingTarget() = Uptane::Target::Unknown();
81  }
82  return result;
83 }
84 
85 bool AktualizrSecondaryOstree::isTargetSupported(const Uptane::Target& target) const {
86  return update_agent_->isTargetSupported(target);
87 }
88 
89 data::InstallationResult AktualizrSecondaryOstree::applyPendingInstall(const Uptane::Target& target) {
90  return update_agent_->applyPendingInstall(target);
91 }
92 
93 bool AktualizrSecondaryOstree::getInstalledImageInfo(Uptane::InstalledImageInfo& installed_image_info) const {
94  return update_agent_->getInstalledImageInfo(installed_image_info);
95 }
96 
97 data::InstallationResult AktualizrSecondaryOstree::installPendingTarget(const Uptane::Target& target) {
98  return update_agent_->install(target);
99 }
100 
101 void AktualizrSecondaryOstree::completeInstall() { return update_agent_->completeInstall(); }
data::ResultCode::Numeric::kGeneralError
@ kGeneralError
Other error.
data::InstallationResult
Definition: types.h:277
AktualizrSecondaryConfig
Definition: aktualizr_secondary_config.h:35
Uptane::InstalledImageInfo
Definition: types.h:306
AktualizrSecondary
Definition: aktualizr_secondary.h:16
AktualizrSecondaryOstree
Definition: aktualizr_secondary_ostree.h:8
result
Results of libaktualizr API calls.
Definition: results.h:12
Asn1Message
Reference counted holder for the top-level ASN1 message structure.
Definition: asn1_message.h:34
Uptane::Target
Definition: types.h:379
INvStorage
Definition: invstorage.h:43