Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.

Commit 49c5382

Browse files
committed
Add RPMRepoManager sketch implementation
1 parent 9cefe91 commit 49c5382

2 files changed

Lines changed: 89 additions & 22 deletions

File tree

include/cloysterhpc/services/repos.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*/
55

66
/* This class is set to be reimplemented */
7-
#ifndef CLOYSTERHPC_REPOS_H_DEPRECATED_
8-
#define CLOYSTERHPC_REPOS_H_DEPRECATED_
7+
#ifndef CLOYSTERHPC_REPOS_H_
8+
#define CLOYSTERHPC_REPOS_H_
99

1010
#include <filesystem>
1111
#include <optional>
@@ -48,9 +48,9 @@ class IRepository {
4848
virtual void uri(std::optional<std::string> value) = 0;
4949
virtual void source(std::filesystem::path value) = 0;
5050

51-
IRepository(const IRepository&) = delete;
51+
IRepository(const IRepository&) = default;
5252
IRepository(IRepository&&) = default;
53-
IRepository& operator=(const IRepository&) = delete;
53+
IRepository& operator=(const IRepository&) = default;
5454
IRepository& operator=(IRepository&&) = default;
5555

5656
protected:
@@ -78,7 +78,6 @@ class RepoManager {
7878

7979
private:
8080
void loadFiles(const std::filesystem::path& basedir);
81-
void loadCustom(inifile& file, const std::filesystem::path& path);
8281
void loadRPMRepos(const std::filesystem::path& source);
8382
auto loadDefaults();
8483

@@ -101,4 +100,4 @@ class RepoManager {
101100
};
102101

103102
};
104-
#endif // CLOYSTERHPC_REPOS_H_DEPRECATED_
103+
#endif // CLOYSTERHPC_REPOS_H_

src/services/repos.cpp

Lines changed: 84 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <ranges>
1111
#include <sstream>
1212
#include <stdexcept>
13+
#include <unordered_map>
1314
#include <utility>
1415

1516
#include <boost/algorithm/string.hpp>
@@ -71,9 +72,9 @@ class RPMRepository final : public IRepository {
7172
public:
7273
RPMRepository() = default;
7374
~RPMRepository() override = default;
74-
RPMRepository(const RPMRepository&) = delete;
75+
RPMRepository(const RPMRepository&) = default;
7576
RPMRepository(RPMRepository&&) = default;
76-
RPMRepository& operator=(const RPMRepository&) = delete;
77+
RPMRepository& operator=(const RPMRepository&) = default;
7778
RPMRepository& operator=(RPMRepository&&) = default;
7879

7980
[[nodiscard]] std::string id() const override { return m_id; };
@@ -130,19 +131,88 @@ class RPMRepositoryParser final {
130131
static_assert(IsParser<RPMRepositoryParser, std::filesystem::path,
131132
std::vector<RPMRepository>>);
132133

134+
133135
class RPMRepositoryFile final {
136+
static constexpr auto m_parser = RPMRepositoryParser();
137+
std::filesystem::path m_path;
138+
std::unordered_map<std::string, RPMRepository> m_repos;
139+
public:
140+
RPMRepositoryFile(auto path, auto repos)
141+
: m_path(std::move(path))
142+
, m_repos(std::move(repos))
143+
{
144+
}
145+
146+
const auto& repos() const
147+
{
148+
return m_repos;
149+
}
150+
151+
auto& repo(const std::string& name) const
152+
{
153+
return repos().at(name);
154+
}
155+
156+
auto reposList() const
157+
{
158+
return repos()
159+
| std::views::transform([](const auto& pair)
160+
{ return pair.second; })
161+
| std::ranges::to<std::vector>();
162+
}
163+
164+
void save() const
165+
{
166+
m_parser.unparse(reposList(), m_path);
167+
}
168+
};
169+
170+
class RPMRepoManager final {
171+
static constexpr auto m_parser = RPMRepositoryParser();
172+
static constexpr auto m_basedir = "/etc/yum.repos.d/";
173+
std::unordered_map<std::string, std::shared_ptr<RPMRepositoryFile>> m_filesIdx;
174+
175+
void addRepoFile(auto&& repofile)
176+
{
177+
for (auto& [repo, _] : repofile.repos()) {
178+
m_filesIdx.insert({repo, std::make_shared<RPMRepositoryFile>(repofile)});
179+
}
180+
}
181+
182+
static auto vecToMap(std::vector<RPMRepository>&& repos)
183+
{
184+
std::unordered_map<std::string, RPMRepository> output;
185+
for (auto&& repo : std::move(repos))
186+
{
187+
output.insert({repo.id(), std::move(repo)});
188+
}
189+
return output;
190+
}
191+
134192
public:
135-
~RPMRepositoryFile() = default;
136-
RPMRepositoryFile() = default;
137-
RPMRepositoryFile(const RPMRepositoryFile&) = delete;
138-
RPMRepositoryFile& operator=(const RPMRepositoryFile&) = delete;
139-
RPMRepositoryFile(RPMRepositoryFile&&) = delete;
140-
RPMRepositoryFile& operator=(RPMRepositoryFile&&) = delete;
141-
void save();
142-
void load();
193+
194+
void install(const std::filesystem::path& source)
195+
{
196+
const auto& dest = m_basedir / source.filename();
197+
if (m_filesIdx.contains(dest)) {
198+
LOG_WARN("Repository already installed {}, skipping", dest.string());
199+
return;
200+
}
201+
cloyster::copyFile(source, dest);
202+
std::vector<RPMRepository> repos;
203+
m_parser.parse(dest, repos);
204+
auto&& reposMap = vecToMap(std::move(repos));
205+
auto&& repofile = RPMRepositoryFile(dest, reposMap);
206+
addRepoFile(repofile);
207+
}
208+
209+
void enable(const auto& repo, bool value)
210+
{
211+
auto& repofile = m_filesIdx.at(repo);
212+
repofile.repo(repo).enable(value);
213+
repofile.save();
214+
}
143215
};
144-
static_assert(cloyster::concepts::IsSaveable<RPMRepositoryFile>);
145-
static_assert(cloyster::concepts::NotCopiableNotMoveable<RPMRepositoryFile>);
146216

147217
}; // namespace cloyster::services::repos {
148218

@@ -164,7 +234,6 @@ constexpr std::string_view CLOYSTER_REPO_EL10 = {
164234
#include "cloysterhpc/repos/el10/cloyster.repo"
165235
};
166236

167-
// @TODO Make this a RPMRepositoryFile method
168237
void installFile(const std::filesystem::path& path, std::istream& data)
169238
{
170239
if (cloyster::dryRun) {
@@ -181,7 +250,7 @@ void installFile(const std::filesystem::path& path, std::istream& data)
181250
fil << data.rdbuf();
182251
}
183252

184-
constexpr auto getDefaultPath(const auto& osinfo)
253+
constexpr auto getCloysterRepoPath(const auto& osinfo)
185254
{
186255
switch (osinfo.getPlatform()) {
187256
case OS::Platform::el8:
@@ -276,7 +345,7 @@ namespace cloyster::services::repos {
276345

277346
auto RepoManager::loadDefaults()
278347
{
279-
const auto& path = getDefaultPath(m_os);
348+
const auto& path = getCloysterRepoPath(m_os);
280349
std::istringstream stream;
281350
switch (m_os.getPlatform()) {
282351
case OS::Platform::el8:
@@ -517,7 +586,6 @@ void RepoManager::install(const std::vector<std::filesystem::path>& paths)
517586
}
518587
}
519588

520-
/// Private API
521589

522590
std::vector<std::shared_ptr<const IRepository>> RepoManager::listRepos() const
523591
{

0 commit comments

Comments
 (0)