Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
treehub.cc
1 #include "treehub.h"
2 #include <gio/gio.h>
3 #include <glib.h>
4 #include <ostree.h>
5 #include <package_manager/ostreemanager.h>
6 #include <random>
7 #include <vector>
8 #include "context.h"
9 #include "executor.h"
10 
11 namespace fs = boost::filesystem;
12 
13 class FetchTask {
14  const Config &config;
15  std::shared_ptr<INvStorage> storage;
16  std::shared_ptr<KeyManager> keys;
17  const fs::path repoDir;
18  const std::string branchName;
19  const std::string remoteUrl;
20 
21  GObjectUniquePtr<OstreeRepo> repo;
22 
23  void initRepo() {
24  GFile *gRepoFile = g_file_new_for_path(repoDir.native().c_str());
25  repo.reset(ostree_repo_new(gRepoFile));
26  g_object_unref(gRepoFile);
27  if (!repo) {
28  throw std::runtime_error("Repo initialization failed");
29  }
30 
31  if (!ostree_repo_create(repo.get(), OSTREE_REPO_MODE_ARCHIVE_Z2, NULL, NULL)) {
32  throw std::runtime_error("Unable to init repository");
33  };
34 
35  if (!OstreeManager::addRemote(repo.get(), remoteUrl, *keys)) {
36  throw std::runtime_error("Unable to add remote to the repository");
37  };
38  }
39 
40  public:
41  FetchTask(const Config &cfg, const fs::path rd, const std::string &bn, const std::string &rurl)
42  : config{cfg},
43  storage{INvStorage::newStorage(config.storage)},
44  keys{new KeyManager{storage, config.keymanagerConfig()}},
45  repoDir{rd},
46  branchName{bn},
47  remoteUrl{rurl} {
48  keys->loadKeys();
49  initRepo();
50  }
51 
52  void operator()() {
53  GVariantBuilder builder;
54  GVariant *options;
55  const char *const refs[] = {branchName.c_str()};
56  g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
57  g_variant_builder_add(&builder, "{s@v}", "flags", g_variant_new_variant(g_variant_new_int32(0)));
58  g_variant_builder_add(&builder, "{s@v}", "refs", g_variant_new_variant(g_variant_new_strv(refs, 1)));
59  options = g_variant_builder_end(&builder);
60  GError *error = NULL;
61  if (!ostree_repo_pull_with_options(repo.get(), remote, options, NULL, NULL, &error)) {
62  LOG_ERROR << "Failed to pull repo " << repoDir << ": " << error->message;
63  g_error_free(error);
64  error = NULL;
65  }
66  g_variant_unref(options);
67  }
68 };
69 
71  std::vector<Config> configs;
72  const fs::path outputDir;
73  const std::string &branchName;
74  const std::string &remoteUrl;
75  std::mt19937 rng;
76  std::uniform_int_distribution<size_t> gen;
77 
78  public:
79  FetchFromOstreeTasks(const fs::path &baseDir, const fs::path &od, const std::string &bn, const std::string &ru)
80  : configs{loadDeviceConfigurations(baseDir)},
81  outputDir{od},
82  branchName{bn},
83  remoteUrl{ru},
84  gen(0UL, configs.size() - 1) {
85  std::random_device seedGen;
86  rng.seed(seedGen());
87  }
88 
89  FetchTask nextTask() {
90  auto dstName = Utils::randomUuid();
91  const fs::path repoDir = outputDir / dstName;
92  return FetchTask{configs[gen(rng)], repoDir, branchName, remoteUrl};
93  }
94 };
95 
96 void fetchFromOstree(const fs::path &baseDir, const fs::path &outputDir, const std::string &branchName,
97  const std::string &remoteUrl, const unsigned int rate, const unsigned int nr,
98  const unsigned int parallelism) {
99  std::vector<FetchFromOstreeTasks> feeds(parallelism, FetchFromOstreeTasks{baseDir, outputDir, branchName, remoteUrl});
100  std::unique_ptr<FixedExecutionController> execController = std_::make_unique<FixedExecutionController>(nr);
101  Executor<FetchFromOstreeTasks> exec{feeds, rate, std::move(execController), "Fetch"};
102  exec.run();
103 }
KeyManager
Definition: keymanager.h:13
Executor
Definition: executor.h:98
Config
Configuration object for an aktualizr instance running on a primary ECU.
Definition: config.h:74
FetchFromOstreeTasks
Definition: treehub.cc:70
FetchTask
Definition: treehub.cc:13