Aktualizr
C++ SOTA Client
fetcher.cc
1 #include "fetcher.h"
2 
3 #ifdef BUILD_OSTREE
4 #include "package_manager/ostreemanager.h" // TODO: Hide behind PackageManagerInterface
5 #endif
6 
7 namespace Uptane {
8 
9 bool Fetcher::fetchRole(std::string* result, int64_t maxsize, RepositoryType repo, Uptane::Role role, Version version) {
10  // TODO: chain-loading root.json
11  std::string base_url = (repo == RepositoryType::Director) ? config.uptane.director_server : config.uptane.repo_server;
12  std::string url = base_url + "/" + version.RoleFileName(role);
13  HttpResponse response = http->get(url, maxsize);
14  if (!response.isOk()) {
15  return false;
16  }
17  *result = response.body;
18  return true;
19 }
20 
21 static size_t DownloadHandler(char* contents, size_t size, size_t nmemb, void* userp) {
22  assert(userp);
23  auto* ds = static_cast<Uptane::DownloadMetaStruct*>(userp);
24  uint64_t downloaded = size * nmemb;
25  auto expected = static_cast<uint64_t>(ds->target.length());
26  if ((ds->downloaded_length + downloaded) > expected) {
27  return ds->downloaded_length + downloaded; // curl will abort if return unexpected size;
28  }
29 
30  // incomplete writes will stop the download (written_size != nmemb*size)
31  size_t written_size = ds->fhandle->wfeed(reinterpret_cast<uint8_t*>(contents), downloaded);
32  ds->hasher().update(reinterpret_cast<const unsigned char*>(contents), written_size);
33  unsigned int calculated = 0;
34  if (loggerGetSeverity() <= boost::log::trivial::severity_level::trace) {
35  if (ds->downloaded_length > 0) {
36  std::cout << "\r";
37  }
38  }
39  ds->downloaded_length += downloaded;
40  calculated = static_cast<unsigned int>((ds->downloaded_length * 100) / expected);
41  if (loggerGetSeverity() <= boost::log::trivial::severity_level::trace) {
42  std::cout << "Downloading: " << calculated << "%";
43  if (ds->downloaded_length == expected) {
44  std::cout << "\n";
45  }
46  }
47 
48  if (ds->events_channel) {
49  auto event = std::make_shared<event::DownloadProgressReport>(ds->target, "Downloading", calculated);
50  (*(ds->events_channel))(event);
51  }
52  return written_size;
53 }
54 
55 bool Fetcher::fetchVerifyTarget(const Target& target) {
56  bool result = false;
57  try {
58  if (!target.IsOstree()) {
59  DownloadMetaStruct ds(target, events_channel);
60  std::unique_ptr<StorageTargetWHandle> fhandle =
61  storage->allocateTargetFile(false, target.filename(), static_cast<size_t>(target.length()));
62  ds.fhandle = fhandle.get();
63  ds.downloaded_length = 0;
64 
65  if (target.hashes().empty()) {
66  throw Exception("image", "No hash defined for the target");
67  }
68 
69  HttpResponse response =
70  http->download(config.uptane.repo_server + "/targets/" + target.filename(), DownloadHandler, &ds);
71  if (!response.isOk()) {
72  fhandle->wabort();
73  if (response.curl_code == CURLE_WRITE_ERROR) {
74  throw OversizedTarget(target.filename());
75  }
76  throw Exception("image", "Could not download file, error: " + response.error_message);
77  }
78  fhandle->wcommit();
79 
80  if (!target.MatchWith(Hash(ds.hash_type, ds.hasher().getHexDigest()))) {
81  throw TargetHashMismatch(target.filename());
82  }
83  result = true;
84  } else {
85 #ifdef BUILD_OSTREE
86  KeyManager keys(storage, config.keymanagerConfig());
87  keys.loadKeys();
88  data::InstallOutcome outcome =
89  OstreeManager::pull(config.pacman.sysroot, config.pacman.ostree_server, keys, target, events_channel);
90  result =
91  (outcome.first == data::UpdateResultCode::kOk || outcome.first == data::UpdateResultCode::kAlreadyProcessed);
92 #else
93  LOG_ERROR << "Could not pull OSTree target. Aktualizr was built without OSTree support!";
94 #endif
95  }
96  } catch (const Exception& e) {
97  LOG_WARNING << "Error while downloading a target: " << e.what();
98  }
99  return result;
100 }
101 
102 } // namespace Uptane
TUF Roles.
Definition: tuf.h:25
RepositoryType
This must match the repo_type table in sqlstorage.
Definition: tuf.h:18
Operation has already been processed.
Base data types that are used in The Update Framework (TUF), part of UPTANE.
Operation executed successfully.
Aktualizr status events.
Definition: events.cc:4