1 #include "aktualizr_secondary.h" 3 #include "crypto/keymanager.h" 4 #include "logging/logging.h" 5 #include "update_agent.h" 6 #include "uptane/manifest.h" 7 #include "utilities/utils.h" 13 std::shared_ptr<KeyManager> key_mngr, std::shared_ptr<UpdateAgent> update_agent)
14 : config_(
std::move(config)),
15 storage_(
std::move(storage)),
16 keys_(
std::move(key_mngr)),
17 update_agent_(
std::move(update_agent)),
20 manifest_issuer_ = std::make_shared<Uptane::ManifestIssuer>(keys_, ecu_serial_);
21 initPendingTargetIfAny();
23 if (hasPendingUpdate()) {
24 LOG_INFO <<
"Found a pending target to be applied.";
27 std::vector<Uptane::Target> installed_versions;
28 boost::optional<Uptane::Target> pending_target;
29 storage_->loadInstalledVersions(ecu_serial_.ToString(),
nullptr, &pending_target);
31 if (!!pending_target) {
34 LOG_INFO <<
"Pending update found; attempting to apply it. Target hash: " << pending_target->sha256Hash();
36 install_res = update_agent_->applyPendingInstall(*pending_target);
38 if (install_res.result_code != data::ResultCode::Numeric::kNeedCompletion) {
39 storage_->saveEcuInstallationResult(ecu_serial_, install_res);
41 if (install_res.success) {
42 LOG_INFO <<
"Pending update has been successfully applied: " << pending_target->sha256Hash();
43 storage_->saveInstalledVersion(ecu_serial_.ToString(), *pending_target, InstalledVersionUpdateMode::kCurrent);
45 LOG_ERROR <<
"Application of the pending update has failed: (" << install_res.result_code.toString() <<
")" 46 << install_res.description;
47 storage_->saveInstalledVersion(ecu_serial_.ToString(), *pending_target, InstalledVersionUpdateMode::kNone);
50 director_repo_.dropTargets(*storage_);
52 LOG_INFO <<
"Pending update hasn't been applied because a reboot hasn't been detected";
62 PublicKey AktualizrSecondary::getPublicKey()
const {
return keys_->UptanePublicKey(); }
64 std::tuple<Uptane::EcuSerial, Uptane::HardwareIdentifier, PublicKey> AktualizrSecondary::getInfo()
const {
65 return std::tuple<Uptane::EcuSerial, Uptane::HardwareIdentifier, PublicKey>{getSerial(), getHwId(), getPublicKey()};
71 if (update_agent_->getInstalledImageInfo(installed_image_info)) {
72 manifest = manifest_issuer_->assembleAndSignManifest(installed_image_info);
78 bool AktualizrSecondary::putMetadata(
const Metadata& metadata) {
return doFullVerification(metadata); }
80 bool AktualizrSecondary::sendFirmware(
const std::string& firmware) {
81 if (!pending_target_.IsValid()) {
82 LOG_ERROR <<
"Aborting image download/receiving; no valid target found.";
86 if (!update_agent_->download(pending_target_, firmware)) {
87 LOG_ERROR <<
"Failed to pull/store an update data";
88 pending_target_ = Uptane::Target::Unknown();
92 LOG_INFO <<
"Download firmware " << pending_target_.filename() <<
" successful.";
97 if (!pending_target_.IsValid()) {
98 LOG_ERROR <<
"Aborting target image installation; no valid target found.";
102 if (pending_target_.filename() != target_name) {
103 LOG_ERROR <<
"name of the target to install and a name of the pending target do not match";
107 auto install_result = update_agent_->install(pending_target_);
109 switch (install_result) {
110 case data::ResultCode::Numeric::kOk: {
111 storage_->saveInstalledVersion(ecu_serial_.ToString(), pending_target_, InstalledVersionUpdateMode::kCurrent);
112 pending_target_ = Uptane::Target::Unknown();
113 LOG_INFO <<
"The target has been successfully installed: " << target_name;
116 case data::ResultCode::Numeric::kNeedCompletion: {
117 storage_->saveInstalledVersion(ecu_serial_.ToString(), pending_target_, InstalledVersionUpdateMode::kPending);
118 LOG_INFO <<
"The target has been successfully installed, but a reboot is required to be applied: " << target_name;
122 LOG_INFO <<
"Failed to install the target: " << target_name;
126 return install_result;
129 void AktualizrSecondary::completeInstall() { update_agent_->completeInstall(); }
131 bool AktualizrSecondary::doFullVerification(
const Metadata& metadata) {
156 director_repo_.updateMeta(*storage_, metadata);
157 }
catch (
const std::exception& e) {
158 LOG_ERROR <<
"Failed to update Director metadata: " << e.what();
170 image_repo_.updateMeta(*storage_, metadata);
171 }
catch (
const std::exception& e) {
172 LOG_ERROR <<
"Failed to update Image repo metadata: " << e.what();
177 if (!director_repo_.matchTargetsWithImageTargets(*(image_repo_.getTargets()))) {
178 LOG_ERROR <<
"Targets metadata from the Director and Image repositories DOES NOT match ";
182 auto targetsForThisEcu = director_repo_.getTargets(getSerial(), getHwId());
184 if (targetsForThisEcu.size() != 1) {
185 LOG_ERROR <<
"Invalid number of targets (should be 1): " << targetsForThisEcu.size();
189 if (!update_agent_->isTargetSupported(targetsForThisEcu[0])) {
190 LOG_ERROR <<
"The given target type is not supported: " << targetsForThisEcu[0].type();
194 pending_target_ = targetsForThisEcu[0];
196 LOG_DEBUG <<
"Metadata verified, new update found.";
200 void AktualizrSecondary::uptaneInitialize() {
201 if (keys_->generateUptaneKeyPair().size() == 0) {
202 throw std::runtime_error(
"Failed to generate uptane key pair");
206 EcuSerials ecu_serials;
208 if (storage_->loadEcuSerials(&ecu_serials)) {
209 ecu_serial_ = ecu_serials[0].first;
210 hardware_id_ = ecu_serials[0].second;
214 std::string ecu_serial_local = config_.uptane.ecu_serial;
215 if (ecu_serial_local.empty()) {
216 ecu_serial_local = keys_->UptanePublicKey().KeyId();
219 std::string ecu_hardware_id = config_.uptane.ecu_hardware_id;
220 if (ecu_hardware_id.empty()) {
221 ecu_hardware_id = Utils::getHostname();
222 if (ecu_hardware_id ==
"") {
223 throw std::runtime_error(
"Failed to define ECU hardware ID");
228 storage_->storeEcuSerials(ecu_serials);
229 ecu_serial_ = ecu_serials[0].first;
230 hardware_id_ = ecu_serials[0].second;
240 storage_->importInstalledVersions(config_.import.base_path);
243 void AktualizrSecondary::initPendingTargetIfAny() {
245 director_repo_.checkMetaOffline(*storage_);
246 }
catch (
const std::exception& e) {
247 LOG_INFO <<
"No valid metadata found in storage.";
251 auto targetsForThisEcu = director_repo_.getTargets(ecu_serial_, hardware_id_);
253 if (targetsForThisEcu.size() != 1) {
254 LOG_ERROR <<
"Invalid number of targets (should be 1): " << targetsForThisEcu.size();
258 if (!update_agent_->isTargetSupported(targetsForThisEcu[0])) {
259 LOG_ERROR <<
"The given target type is not supported: " << targetsForThisEcu[0].type();
263 pending_target_ = targetsForThisEcu[0];
SWM Internal integrity error.