Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
packagemanagerfake.cc
1 #include "libaktualizr/packagemanagerfactory.h"
2 
3 #include "logging/logging.h"
4 #include "packagemanagerfake.h"
5 #include "storage/invstorage.h"
6 #include "utilities/fault_injection.h"
7 
8 AUTO_REGISTER_PACKAGE_MANAGER(PACKAGE_MANAGER_NONE, PackageManagerFake);
9 
10 Json::Value PackageManagerFake::getInstalledPackages() const {
11  Json::Value packages(Json::arrayValue);
12  Json::Value package;
13  package["name"] = "fake-package";
14  package["version"] = "1.0";
15  packages.append(package);
16  return packages;
17 }
18 
19 Uptane::Target PackageManagerFake::getCurrent() const {
20  boost::optional<Uptane::Target> current_version;
21  storage_->loadPrimaryInstalledVersions(&current_version, nullptr);
22 
23  if (!!current_version) {
24  return *current_version;
25  }
26 
27  return Uptane::Target::Unknown();
28 }
29 
30 data::InstallationResult PackageManagerFake::install(const Uptane::Target& target) const {
31  (void)target;
32 
33  // fault injection: only enabled with FIU_ENABLE defined
34  if (fiu_fail("fake_package_install") != 0) {
35  std::string failure_cause = fault_injection_last_info();
36  if (failure_cause.empty()) {
38  }
39  LOG_DEBUG << "Causing installation failure with message: " << failure_cause;
41  }
42 
43  if (config.fake_need_reboot) {
44  // set reboot flag to be notified later
45  if (bootloader_ != nullptr) {
46  bootloader_->rebootFlagSet();
47  }
48  return data::InstallationResult(data::ResultCode::Numeric::kNeedCompletion, "Application successful, need reboot");
49  }
50 
51  return data::InstallationResult(data::ResultCode::Numeric::kOk, "Installing package was successful");
52 }
53 
54 void PackageManagerFake::completeInstall() const {
55  LOG_INFO << "Emulating a system reboot";
56  bootloader_->reboot(true);
57 }
58 
59 data::InstallationResult PackageManagerFake::finalizeInstall(const Uptane::Target& target) {
60  if (config.fake_need_reboot && !bootloader_->rebootDetected()) {
61  return data::InstallationResult(data::ResultCode::Numeric::kNeedCompletion,
62  "Reboot is required for the pending update application");
63  }
64 
65  boost::optional<Uptane::Target> pending_version;
66  storage_->loadPrimaryInstalledVersions(nullptr, &pending_version);
67 
68  if (!pending_version) {
69  throw std::runtime_error("No pending update, nothing to finalize");
70  }
71 
72  data::InstallationResult install_res;
73 
74  if (target.MatchTarget(*pending_version)) {
75  if (fiu_fail("fake_install_finalization_failure") != 0) {
76  const std::string failure_cause = fault_injection_last_info();
77  if (failure_cause.empty()) {
79  } else {
80  install_res =
82  "Failed to finalize the pending update installation");
83  }
84  } else {
85  install_res = data::InstallationResult(data::ResultCode::Numeric::kOk, "Installing fake package was successful");
86  }
87 
88  } else {
89  install_res =
90  data::InstallationResult(data::ResultCode::Numeric::kInternalError, "Pending and new target do not match");
91  }
92 
93  if (config.fake_need_reboot) {
94  bootloader_->rebootFlagClear();
95  }
96  return install_res;
97 }
98 
99 bool PackageManagerFake::fetchTarget(const Uptane::Target& target, Uptane::Fetcher& fetcher, const KeyManager& keys,
100  const FetcherProgressCb& progress_cb, const api::FlowControlToken* token) {
101  // fault injection: only enabled with FIU_ENABLE defined. Note that all
102  // exceptions thrown in PackageManagerInterface::fetchTarget are caught by a
103  // try in the same function, so we can only emulate the warning and return
104  // value.
105  if (fiu_fail("fake_package_download") != 0) {
106  const std::string failure_cause = fault_injection_last_info();
107  if (!failure_cause.empty()) {
108  LOG_WARNING << "Error while downloading a target: " << failure_cause;
109  } else {
110  LOG_WARNING << "Error while downloading a target: forced failure";
111  }
112  return false;
113  }
114 
115  // TODO(OTA-4939): Unify this with the check in
116  // SotaUptaneClient::getNewTargets() and make it more generic.
117  if (target.IsOstree()) {
118  LOG_ERROR << "Cannot download OSTree target " << target.filename() << " with the fake package manager!";
119  return false;
120  }
121 
122  return PackageManagerInterface::fetchTarget(target, fetcher, keys, progress_cb, token);
123 }
Uptane::Fetcher
Definition: fetcher.h:33
data::ResultCode
Definition: types.h:219
KeyManager
Definition: keymanager.h:13
data::InstallationResult
Definition: types.h:277
api::FlowControlToken
Provides a thread-safe way to pause and terminate task execution.
Definition: apiqueue.h:19
PackageManagerFake
Definition: packagemanagerfake.h:11
Uptane::Target::IsOstree
bool IsOstree() const
Is this an OSTree target? OSTree targets need special treatment because the hash doesn't represent th...
Definition: tuf.cc:179
data::ResultCode::Numeric::kInternalError
@ kInternalError
SWM Internal integrity error.
Uptane::Target
Definition: types.h:379
data::ResultCode::Numeric::kInstallFailed
@ kInstallFailed
Package installation failed.