diff --git a/include/cloysterhpc/concepts.h b/include/cloysterhpc/concepts.h index a70653a8..d4d54f03 100644 --- a/include/cloysterhpc/concepts.h +++ b/include/cloysterhpc/concepts.h @@ -18,11 +18,11 @@ concept IsMoveable template concept NotCopiableMoveable = !IsMoveable && !IsCopyable; /** - * @brief Parser means: P can parse and unparse Ts from streams. The + * @brief IsParser means: P can parse and unparse Ts from streams. The * parsers are allowed to throw exceptions */ template -concept Parser = requires(Parser_ parser, std::istream& parseInput, +concept IsParser = requires(Parser_ parser, std::istream& parseInput, std::ostream& unparseOutput, const T& unparseInput, T& parseOutput) { { parser.parse(parseInput, parseOutput) } -> std::same_as; { parser.unparse(unparseInput, unparseOutput) } -> std::same_as; diff --git a/include/cloysterhpc/connection.h b/include/cloysterhpc/connection.h index 17b917f7..20517c9b 100644 --- a/include/cloysterhpc/connection.h +++ b/include/cloysterhpc/connection.h @@ -6,17 +6,16 @@ #ifndef CLOYSTERHPC_CONNECTION_H_ #define CLOYSTERHPC_CONNECTION_H_ -#include - #include #include #include #include -#include #include #include +#include + /* Each server can have one and only one connection to a given network, although * it can have more than one address on the same interface. This may seem * incorrect, but it is standard TCP networking. diff --git a/include/cloysterhpc/functions.h b/include/cloysterhpc/functions.h index 2222b587..1fc8ace3 100644 --- a/include/cloysterhpc/functions.h +++ b/include/cloysterhpc/functions.h @@ -1,7 +1,7 @@ #ifndef CLOYSTERHPC_FUNCTIONS_H_ #define CLOYSTERHPC_FUNCTIONS_H_ -#include "repos.h" +#include #include #include #include @@ -9,18 +9,18 @@ #include #include #include -#include #include -#include -#include +#include namespace cloyster { // Globals extern bool dryRun; -std::shared_ptr getRunner(); -std::shared_ptr> getRepoManager(const OS& osinfo); +using OS = cloyster::models::OS; +std::shared_ptr getRunner(); +std::shared_ptr getRepoManager(const OS& osinfo); + /** * A command proxy, to us to be able to get the @@ -171,9 +171,6 @@ std::string findAndReplace(const std::string_view& source, */ void copyFile(std::filesystem::path source, std::filesystem::path destination); -std::optional readKeyfileString(Glib::RefPtr file, - const std::string_view group, const std::string_view key); - -} /* namespace cloyster */ +} // namespace cloyster #endif // CLOYSTERHPC_FUNCTIONS_H_ diff --git a/include/cloysterhpc/mailsystem/postfix.h b/include/cloysterhpc/mailsystem/postfix.h index 67091a46..e07cce33 100644 --- a/include/cloysterhpc/mailsystem/postfix.h +++ b/include/cloysterhpc/mailsystem/postfix.h @@ -6,7 +6,7 @@ #ifndef CLOYSTERHPC_POSTFIX_H_ #define CLOYSTERHPC_POSTFIX_H_ -#include +#include #include #include #include @@ -15,12 +15,13 @@ #include #include +// @TODO move this to its own namespace class Postfix : public IService { public: enum class Profile { Local, Relay, SASL }; private: - BaseRunner& m_runner; + cloyster::services::BaseRunner& m_runner; Profile m_profile; std::optional m_hostname {}; std::optional m_domain {}; @@ -75,7 +76,7 @@ class Postfix : public IService { void setup(const std::filesystem::path& basedir = "/etc/postfix"); explicit Postfix( - std::shared_ptr bus, BaseRunner& runner, Profile profile); + std::shared_ptr bus, cloyster::services::BaseRunner& runner, Profile profile); }; #endif // CLOYSTERHPC_POSTFIX_H_ diff --git a/include/cloysterhpc/answerfile.h b/include/cloysterhpc/models/answerfile.h similarity index 99% rename from include/cloysterhpc/answerfile.h rename to include/cloysterhpc/models/answerfile.h index 40aa06b9..1b7fa6c0 100644 --- a/include/cloysterhpc/answerfile.h +++ b/include/cloysterhpc/models/answerfile.h @@ -7,7 +7,7 @@ #define CLOYSTERHPC_ANSWERFILE_H_ #include -#include +#include #include #include #include @@ -16,6 +16,8 @@ using boost::asio::ip::address; +namespace cloyster::models { + /** * @struct AFNode * @brief Holds individual node settings. @@ -64,6 +66,7 @@ class AnswerFile { std::optional
gateway; std::optional domain_name; std::optional> nameservers; + std::optional con_interface; std::optional
con_ip_addr; std::optional con_mac_addr; @@ -374,4 +377,6 @@ class answerfile_validation_exception : public std::exception { const char* what() const noexcept override { return message.c_str(); } }; +}; + #endif // CLOYSTERHPC_ANSWERFILE_H_ diff --git a/include/cloysterhpc/cluster.h b/include/cloysterhpc/models/cluster.h similarity index 94% rename from include/cloysterhpc/cluster.h rename to include/cloysterhpc/models/cluster.h index a42096e5..03043306 100644 --- a/include/cloysterhpc/cluster.h +++ b/include/cloysterhpc/models/cluster.h @@ -13,19 +13,18 @@ #include #include -#include +#include +#include +#include #include #include -#include #include -#include -#include -#include -#include +#include #include +#include +#include #include -// @TODO: Shouldn't Cluster be below cloyster namespace? /** * @class Cluster @@ -35,13 +34,22 @@ * environment, including headnode, nodes, networks, provisioner, timezone, * locale, and more. */ + +namespace cloyster::models { + +/** + * @brief Represents the cluster state and configuration + */ class Cluster { public: /** * @enum SELinuxMode * @brief Enumeration for SELinux modes. + * */ enum class SELinuxMode { Permissive, Enforcing, Disabled }; + + // @TODO: This class should not know about DBusClient /** * @enum Provisioner @@ -74,9 +82,6 @@ class Cluster { bool m_updateSystem { false }; DiskImage m_diskImage; - // Relace repository with generic repository - std::optional> m_repos = std::nullopt; - public: Cluster(); @@ -186,7 +191,7 @@ class Cluster { void setQueueSystem(QueueSystem::Kind kind); std::optional& getMailSystem(); - void setMailSystem(Postfix::Profile profile, std::shared_ptr runner); + void setMailSystem(Postfix::Profile profile, std::shared_ptr runner); const std::filesystem::path& getDiskImage() const; void setDiskImage(const std::filesystem::path& diskImagePath); @@ -257,4 +262,6 @@ class Cluster { std::string nodeRootPassword; }; +}; // namespace cloyster::models + #endif // CLOYSTERHPC_CLUSTER_H_ diff --git a/include/cloysterhpc/cpu.h b/include/cloysterhpc/models/cpu.h similarity index 94% rename from include/cloysterhpc/cpu.h rename to include/cloysterhpc/models/cpu.h index 5388e818..6a72a76e 100644 --- a/include/cloysterhpc/cpu.h +++ b/include/cloysterhpc/models/cpu.h @@ -7,7 +7,8 @@ #define CLOYSTERHPC_CPU_H_ #include -#include + +namespace cloyster::models { class CPU { private: @@ -39,4 +40,6 @@ class CPU { void setThreadsPerCore(std::size_t threadsPerCore); }; +}; // namespace cloyster::models + #endif // CLOYSTERHPC_CPU_H_ diff --git a/include/cloysterhpc/headnode.h b/include/cloysterhpc/models/headnode.h similarity index 81% rename from include/cloysterhpc/headnode.h rename to include/cloysterhpc/models/headnode.h index 8698d5b9..08bc9407 100644 --- a/include/cloysterhpc/headnode.h +++ b/include/cloysterhpc/models/headnode.h @@ -12,9 +12,10 @@ #include #include -#include -#include +#include +#include +namespace cloyster::models { class Headnode : public Server { public: enum class BootTarget { Text, Graphical }; @@ -32,4 +33,7 @@ class Headnode : public Server { void setBootTarget(BootTarget bootTarget); }; + +}; // namespace cloyster::models + #endif // CLOYSTERHPC_HEADNODE_H_ diff --git a/include/cloysterhpc/node.h b/include/cloysterhpc/models/node.h similarity index 93% rename from include/cloysterhpc/node.h rename to include/cloysterhpc/models/node.h index 6543d4be..9d3561fb 100644 --- a/include/cloysterhpc/node.h +++ b/include/cloysterhpc/models/node.h @@ -11,9 +11,11 @@ #include #include -#include -#include +#include +#include + +namespace cloyster::models { /** * @class Node * @brief A class representing a node in a server cluster. @@ -59,4 +61,6 @@ class Node : public Server { const std::optional& nodeRootPassword); }; +}; // namespace cloyster::models { + #endif // CLOYSTERHPC_NODE_H_ diff --git a/include/cloysterhpc/os.h b/include/cloysterhpc/models/os.h similarity index 88% rename from include/cloysterhpc/os.h rename to include/cloysterhpc/models/os.h index b2f01203..2d090f5c 100644 --- a/include/cloysterhpc/os.h +++ b/include/cloysterhpc/models/os.h @@ -13,6 +13,8 @@ #include #include + +namespace cloyster::models { /** * @class OS * @brief A class representing an Operating System (OS). @@ -49,6 +51,12 @@ class OS { */ enum class Distro { RHEL, OL, Rocky, AlmaLinux }; + /** + * @enum PackageManager + * @brief What + */ + enum class PackageType { RPM, DEB }; + private: std::variant m_arch; std::variant m_family; @@ -124,6 +132,19 @@ class OS { gsl::not_null packageManager() const; + [[nodiscard]] constexpr PackageType getPackageType() const { + switch (getDistro()) { + case Distro::RHEL: + case Distro::OL: + case Distro::Rocky: + case Distro::AlmaLinux: + return PackageType::RPM; + default: + throw std::runtime_error("Unknonw distro type"); + }; + } + + #ifndef NDEBUG /** * @brief Prints the data of the OS. @@ -134,4 +155,5 @@ class OS { #endif }; +}; // namespace cloyster::models #endif // CLOYSTERHPC_OS_H_ diff --git a/include/cloysterhpc/queuesystem/pbs.h b/include/cloysterhpc/models/pbs.h similarity index 81% rename from include/cloysterhpc/queuesystem/pbs.h rename to include/cloysterhpc/models/pbs.h index d88a9189..eab9f84f 100644 --- a/include/cloysterhpc/queuesystem/pbs.h +++ b/include/cloysterhpc/models/pbs.h @@ -6,8 +6,10 @@ #ifndef CLOYSTERHPC_PBS_H_ #define CLOYSTERHPC_PBS_H_ -#include -#include +#include +#include + +namespace cloyster::models { class PBS : public QueueSystem { public: @@ -24,4 +26,6 @@ class PBS : public QueueSystem { explicit PBS(const Cluster& cluster); }; +}; + #endif // CLOYSTERHPC_PBS_H_ diff --git a/include/cloysterhpc/queuesystem/queuesystem.h b/include/cloysterhpc/models/queuesystem.h similarity index 95% rename from include/cloysterhpc/queuesystem/queuesystem.h rename to include/cloysterhpc/models/queuesystem.h index abb19b07..2b6e4787 100644 --- a/include/cloysterhpc/queuesystem/queuesystem.h +++ b/include/cloysterhpc/models/queuesystem.h @@ -12,6 +12,8 @@ #include // Forward declaration of Cluster +namespace cloyster::models { + class Cluster; class QueueSystem { @@ -36,4 +38,6 @@ class QueueSystem { virtual ~QueueSystem() = default; }; +}; + #endif // CLOYSTERHPC_QUEUESYSTEM_H_ diff --git a/include/cloysterhpc/server.h b/include/cloysterhpc/models/server.h similarity index 96% rename from include/cloysterhpc/server.h rename to include/cloysterhpc/models/server.h index 1f7fce7e..1a693e96 100644 --- a/include/cloysterhpc/server.h +++ b/include/cloysterhpc/models/server.h @@ -9,14 +9,14 @@ #include #include #include -#include #include #include -#include -#include +#include +#include #include +namespace cloyster::models { /** * @class Server * @brief Represents a server in a cluster. @@ -108,4 +108,6 @@ class Server { Server() = default; }; +}; // namespace cloyster::models + #endif // CLOYSTERHPC_SERVER_H_ diff --git a/include/cloysterhpc/queuesystem/slurm.h b/include/cloysterhpc/models/slurm.h similarity index 91% rename from include/cloysterhpc/queuesystem/slurm.h rename to include/cloysterhpc/models/slurm.h index c01b84ab..27b16d24 100644 --- a/include/cloysterhpc/queuesystem/slurm.h +++ b/include/cloysterhpc/models/slurm.h @@ -6,8 +6,9 @@ #ifndef CLOYSTERHPC_SLURM_H_ #define CLOYSTERHPC_SLURM_H_ -#include +#include +namespace cloyster::models { /** * @class SLURM * @brief Manages SLURM server installation and configuration. @@ -40,4 +41,5 @@ class SLURM : public QueueSystem { static void startServer(); }; +}; #endif // CLOYSTERHPC_SLURM_H_ diff --git a/include/cloysterhpc/presenter/Presenter.h b/include/cloysterhpc/presenter/Presenter.h index 566bb62d..4fa7b95e 100644 --- a/include/cloysterhpc/presenter/Presenter.h +++ b/include/cloysterhpc/presenter/Presenter.h @@ -6,13 +6,24 @@ #ifndef CLOYSTERHPC_PRESENTER_H_ #define CLOYSTERHPC_PRESENTER_H_ -#include -#include +#include +#include +#include +#include #include #include -#include -#include -#include + + +namespace cloyster::presenter { + +using BaseRunner = cloyster::services::BaseRunner; +using Cluster = cloyster::models::Cluster; +using QueueSystem = cloyster::models::QueueSystem; +using SLURM = cloyster::models::SLURM; +using PBS = cloyster::models::PBS; +using OS = cloyster::models::OS; +using CPU = cloyster::models::CPU; +using Node = cloyster::models::Node; class Presenter { protected: @@ -42,4 +53,6 @@ class Presenter { } }; +}; + #endif // CLOYSTERHPC_PRESENTER_H_ diff --git a/include/cloysterhpc/presenter/PresenterGeneralSettings.h b/include/cloysterhpc/presenter/PresenterGeneralSettings.h index 9a7c236e..d537f649 100644 --- a/include/cloysterhpc/presenter/PresenterGeneralSettings.h +++ b/include/cloysterhpc/presenter/PresenterGeneralSettings.h @@ -8,6 +8,7 @@ #include +namespace cloyster::presenter { class PresenterGeneralSettings : public Presenter { private: @@ -38,4 +39,6 @@ class PresenterGeneralSettings : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERGENERALSETTINGS_H_ diff --git a/include/cloysterhpc/presenter/PresenterHostId.h b/include/cloysterhpc/presenter/PresenterHostId.h index e3f2e66d..2bb210c5 100644 --- a/include/cloysterhpc/presenter/PresenterHostId.h +++ b/include/cloysterhpc/presenter/PresenterHostId.h @@ -9,6 +9,8 @@ #include +namespace cloyster::presenter { + class PresenterHostId : public Presenter { private: struct Messages { @@ -27,4 +29,6 @@ class PresenterHostId : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERHOSTID_H_ diff --git a/include/cloysterhpc/presenter/PresenterInfiniband.h b/include/cloysterhpc/presenter/PresenterInfiniband.h index 34587a0f..d040133d 100644 --- a/include/cloysterhpc/presenter/PresenterInfiniband.h +++ b/include/cloysterhpc/presenter/PresenterInfiniband.h @@ -9,6 +9,9 @@ #include #include + +namespace cloyster::presenter { + class PresenterInfiniband : public Presenter { private: struct Messages { @@ -28,7 +31,9 @@ class PresenterInfiniband : public Presenter { public: PresenterInfiniband(std::unique_ptr& model, - std::unique_ptr& view, NetworkCreator& nc); + std::unique_ptr& view, cloyster::presenter::NetworkCreator& nc); +}; + }; #endif // CLOYSTERHPC_PRESENTERINFINIBAND_H_ diff --git a/include/cloysterhpc/presenter/PresenterInstall.h b/include/cloysterhpc/presenter/PresenterInstall.h index c844b477..dcb91668 100644 --- a/include/cloysterhpc/presenter/PresenterInstall.h +++ b/include/cloysterhpc/presenter/PresenterInstall.h @@ -11,10 +11,12 @@ #include #include +namespace cloyster::presenter { class PresenterInstall : public Presenter { public: PresenterInstall( std::unique_ptr& model, std::unique_ptr& view); }; +} #endif // CLOYSTERHPC_PRESENTERINSTALL_H_ diff --git a/include/cloysterhpc/presenter/PresenterInstructions.h b/include/cloysterhpc/presenter/PresenterInstructions.h index bcf566e1..a69f3cd0 100644 --- a/include/cloysterhpc/presenter/PresenterInstructions.h +++ b/include/cloysterhpc/presenter/PresenterInstructions.h @@ -8,6 +8,8 @@ #include +namespace cloyster::presenter { + class PresenterInstructions : public Presenter { private: struct Messages { @@ -28,4 +30,6 @@ class PresenterInstructions : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERINSTRUCTIONS_H_ diff --git a/include/cloysterhpc/presenter/PresenterLocale.h b/include/cloysterhpc/presenter/PresenterLocale.h index 6c1108c7..e93c3760 100644 --- a/include/cloysterhpc/presenter/PresenterLocale.h +++ b/include/cloysterhpc/presenter/PresenterLocale.h @@ -8,6 +8,8 @@ #include +namespace cloyster::presenter { + class PresenterLocale : public Presenter { private: struct Messages { @@ -22,4 +24,6 @@ class PresenterLocale : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERLOCALE_H_ diff --git a/include/cloysterhpc/presenter/PresenterMailSystem.h b/include/cloysterhpc/presenter/PresenterMailSystem.h index 48269d1e..c91d269b 100644 --- a/include/cloysterhpc/presenter/PresenterMailSystem.h +++ b/include/cloysterhpc/presenter/PresenterMailSystem.h @@ -8,6 +8,7 @@ #include +namespace cloyster::presenter { class PresenterMailSystem : public Presenter { private: struct Messages { @@ -53,4 +54,6 @@ class PresenterMailSystem : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERMAILSYSTEM_H_ diff --git a/include/cloysterhpc/presenter/PresenterNetwork.h b/include/cloysterhpc/presenter/PresenterNetwork.h index a7e12422..da272488 100644 --- a/include/cloysterhpc/presenter/PresenterNetwork.h +++ b/include/cloysterhpc/presenter/PresenterNetwork.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -19,6 +19,8 @@ #include #include +namespace cloyster::presenter { + struct NetworkCreatorData { Network::Profile profile; Network::Type type; @@ -133,4 +135,6 @@ class PresenterNetwork : public Presenter { Network::Type type = Network::Type::Ethernet); }; +}; + #endif // CLOYSTERHPC_PRESENTERNETWORK_H_ diff --git a/include/cloysterhpc/presenter/PresenterNodes.h b/include/cloysterhpc/presenter/PresenterNodes.h index d8310ff5..529bc9b9 100644 --- a/include/cloysterhpc/presenter/PresenterNodes.h +++ b/include/cloysterhpc/presenter/PresenterNodes.h @@ -8,6 +8,8 @@ #include +namespace cloyster::presenter { + class PresenterNodes : public Presenter { private: struct Messages { @@ -63,4 +65,6 @@ class PresenterNodes : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERNODES_H_ diff --git a/include/cloysterhpc/presenter/PresenterNodesOperationalSystem.h b/include/cloysterhpc/presenter/PresenterNodesOperationalSystem.h index 743c621b..1a6328e4 100644 --- a/include/cloysterhpc/presenter/PresenterNodesOperationalSystem.h +++ b/include/cloysterhpc/presenter/PresenterNodesOperationalSystem.h @@ -9,6 +9,8 @@ #include #include +namespace cloyster::presenter { + using PresenterNodesVersionCombo = std::tuple; // major, minor @@ -84,4 +86,6 @@ class PresenterNodesOperationalSystem : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERNODESOPERATIONALSYSTEM_H_ diff --git a/include/cloysterhpc/presenter/PresenterQueueSystem.h b/include/cloysterhpc/presenter/PresenterQueueSystem.h index d86eca9d..f859f303 100644 --- a/include/cloysterhpc/presenter/PresenterQueueSystem.h +++ b/include/cloysterhpc/presenter/PresenterQueueSystem.h @@ -8,6 +8,7 @@ #include +namespace cloyster::presenter { class PresenterQueueSystem : public Presenter { private: struct Messages { @@ -42,4 +43,6 @@ class PresenterQueueSystem : public Presenter { std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERQUEUESYSTEM_H_ diff --git a/include/cloysterhpc/presenter/PresenterRepository.h b/include/cloysterhpc/presenter/PresenterRepository.h index 7362c8cf..12041f8b 100644 --- a/include/cloysterhpc/presenter/PresenterRepository.h +++ b/include/cloysterhpc/presenter/PresenterRepository.h @@ -6,6 +6,7 @@ #include +namespace cloyster::presenter { class PresenterRepository : public Presenter { private: struct Messages { @@ -24,3 +25,5 @@ class PresenterRepository : public Presenter { PresenterRepository( std::unique_ptr& model, std::unique_ptr& view); }; + +}; diff --git a/include/cloysterhpc/presenter/PresenterTime.h b/include/cloysterhpc/presenter/PresenterTime.h index 2305fb93..49930dae 100644 --- a/include/cloysterhpc/presenter/PresenterTime.h +++ b/include/cloysterhpc/presenter/PresenterTime.h @@ -8,6 +8,8 @@ #include +namespace cloyster::presenter { + class PresenterTime : public Presenter { private: struct Messages { @@ -38,4 +40,6 @@ class PresenterTime : public Presenter { PresenterTime(std::unique_ptr& model, std::unique_ptr& view); }; +}; + #endif // CLOYSTERHPC_PRESENTERTIMEZONE_H_ diff --git a/include/cloysterhpc/presenter/PresenterWelcome.h b/include/cloysterhpc/presenter/PresenterWelcome.h index d61dafae..b1598a66 100644 --- a/include/cloysterhpc/presenter/PresenterWelcome.h +++ b/include/cloysterhpc/presenter/PresenterWelcome.h @@ -9,6 +9,7 @@ #include #include +namespace cloyster::presenter { class PresenterWelcome : public Presenter { private: struct Messages { @@ -29,5 +30,6 @@ class PresenterWelcome : public Presenter { PresenterWelcome( std::unique_ptr& model, std::unique_ptr& view); }; +}; #endif // CLOYSTERHPC_PRESENTERWELCOME_H_ diff --git a/include/cloysterhpc/services/execution.h b/include/cloysterhpc/services/execution.h index b8058616..2b72819f 100644 --- a/include/cloysterhpc/services/execution.h +++ b/include/cloysterhpc/services/execution.h @@ -8,7 +8,7 @@ #include -#include +#include class Execution { public: diff --git a/include/cloysterhpc/services/files.h b/include/cloysterhpc/services/files.h index 5cc184d4..b1daf08a 100644 --- a/include/cloysterhpc/services/files.h +++ b/include/cloysterhpc/services/files.h @@ -27,6 +27,18 @@ concept IsKeyFileWriteable = requires(File& file, const std::string& group, cons file.setBoolean(group, key, bvalue); }; +/** + * @brief Wraps implementation exceptions + */ +class FileException : public std::runtime_error { +public: + explicit FileException(const std::string& msg) + : std::runtime_error(msg) + { + } +}; + + /** * @brief Represents a KeyFile hiding the implementation details behind Impl */ diff --git a/include/cloysterhpc/services/repo.h b/include/cloysterhpc/services/repo.h deleted file mode 100644 index f58b3b42..00000000 --- a/include/cloysterhpc/services/repo.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2025 Vinícius Ferrão - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef CLOYSTERHPC_REPO_H_ -#define CLOYSTERHPC_REPO_H_ - -#include -#include -#include -#include -#include -#include - -#include -#include - -/** - * @brief This class represents an EL .repo file as it's found in - * /etc/yum.repos.d/ - * @note This class is WIP, it was added as a PoC of glibmm integration - */ -class [[deprecated("RepoManager refactoring")]] repo { - -public: - std::string_view m_name {}; - std::string_view m_description(); - bool m_enabled = false; - std::string_view m_baseurl {}; - struct m_gpg { - bool check = false; - std::string_view key {}; - }; - struct m_ssl { - bool verify = false; - std::string_view cacert {}; - std::string_view clientkey {}; - std::string_view clientcert {}; - bool verify_status; - }; - std::uint32_t m_metadata_expire = 86400; - bool m_metadata_enabled = false; - - std::vector m_include_packages; - std::vector m_exclude_packages; - - std::string_view name() const; - void name(std::string_view name); -}; - -class RepositoryException : public std::runtime_error { -public: - explicit RepositoryException(const std::string& msg) - : std::runtime_error(msg) - { - } -}; - -#endif // CLOYSTERHPC_REPO_H_ diff --git a/include/cloysterhpc/services/repofile.h b/include/cloysterhpc/services/repofile.h index e710c839..b65f09d3 100644 --- a/include/cloysterhpc/services/repofile.h +++ b/include/cloysterhpc/services/repofile.h @@ -15,30 +15,110 @@ #include #include -#include // @TODO: Remove this header #include -namespace cloyster { +namespace cloyster::services::repos { + +template +concept IsRepository = requires(T repo, const T& crepo, + const std::string& str, bool bol, + const std::optional& optstr) +{ + { repo.id() } -> std::convertible_to; + { repo.enabled() } -> std::convertible_to; + { repo.name() } -> std::convertible_to; + { repo.baseurl() } -> std::convertible_to>; + { repo.metalink() } -> std::convertible_to>; + { repo.gpgcheck() } -> std::convertible_to; + { repo.gpgkey() } -> std::convertible_to; + { repo.source() } -> std::convertible_to; + + repo.id(str); + repo.enabled(bol); + repo.name(str); + repo.baseurl(optstr); + repo.metalink(str); + repo.gpgcheck(bol); + repo.gpgkey(str); + repo.source(str); +}; + /** - * @brief Represents a generic repository - * @TODO MERGE THIS WITH cloyterhpc/repos.h + * @brief Base class for repository + * + * @TODO: This is a shameless copy of RPM repository. + * It will require generalization to accomodate debian + * like repositories in future */ +class BaseRepository { +public: + BaseRepository() = default; + BaseRepository(const BaseRepository&) = delete; + BaseRepository(BaseRepository&&) = default; + BaseRepository& operator=(const BaseRepository&) = delete; + BaseRepository& operator=(BaseRepository&&) = default; + virtual ~BaseRepository() = default; + [[nodiscard]] virtual std::string id() const = 0; + [[nodiscard]] virtual bool enabled() const = 0; + [[nodiscard]] virtual std::string name() const = 0; + [[nodiscard]] virtual std::string group() const = 0; + [[nodiscard]] virtual std::optional baseurl() const = 0; + [[nodiscard]] virtual std::optional metalink() const = 0; + [[nodiscard]] virtual bool gpgcheck() const = 0; + [[nodiscard]] virtual std::string gpgkey() const = 0; + [[nodiscard]] virtual std::filesystem::path source() const = 0; -/* - * @TODO MERGE THIS WITH cloyterhpc/repos.h - */ -struct RPMRepository final { - std::string id; - bool enabled = true; - std::string name; - std::optional baseurl; - std::optional metalink; - bool gpgcheck = true; - std::string gpgkey; - std::filesystem::path source; - std::string group; + virtual void id(std::string) = 0; + virtual void enabled(bool) = 0; + virtual void name(std::string) = 0; + virtual void group(std::string) = 0; + virtual void baseurl(std::optional) = 0; + virtual void metalink(std::optional) = 0; + virtual void gpgcheck(bool) = 0; + virtual void gpgkey(std::string) = 0; + virtual void source(std::filesystem::path) = 0; +}; +static_assert(IsRepository); + + +class RPMRepository final : public BaseRepository { + std::string m_id; + bool m_enabled = true; + std::string m_name; + std::optional m_baseurl; + std::optional m_metalink; + bool m_gpgcheck = true; + std::string m_gpgkey; + std::filesystem::path m_source; + std::string m_group; +public: + RPMRepository() = default; + ~RPMRepository() override = default; + RPMRepository(const RPMRepository&) = delete; + RPMRepository(RPMRepository&&) = default; + RPMRepository& operator=(const RPMRepository&) = delete; + RPMRepository& operator=(RPMRepository&&) = default; + + [[nodiscard]] std::string id() const override { return m_id; }; + [[nodiscard]] bool enabled() const override { return m_enabled; }; + [[nodiscard]] std::string name() const override { return m_name; }; + [[nodiscard]] std::string group() const override { return m_group; }; + [[nodiscard]] std::optional baseurl() const override { return m_baseurl; }; + [[nodiscard]] std::optional metalink() const override { return m_metalink; }; + [[nodiscard]] bool gpgcheck() const override { return m_gpgcheck; }; + [[nodiscard]] std::string gpgkey() const override { return m_gpgkey; }; + [[nodiscard]] std::filesystem::path source() const override { return m_source; }; + + void id(std::string value) override { m_id = value; }; + void enabled(bool enabled) override { m_enabled = enabled; }; + void name(std::string name) override { m_name = name; }; + void group(std::string group) override { m_group = group; }; + void baseurl(std::optional baseurl) override { m_baseurl = baseurl; }; + void metalink(std::optional metalink) override { m_metalink = metalink; }; + void gpgcheck(bool gpgcheck) override { m_gpgcheck = gpgcheck; }; + void gpgkey(std::string gpgkey) override { m_gpgkey = gpgkey; }; + void source(std::filesystem::path source) override { m_source = source; }; }; -// static_assert(Repository); static_assert(IsRepository); // @TODO: Move this to its own file @@ -51,7 +131,7 @@ class RPMRepositoryParser final { static void unparse( const std::vector& repos, std::ostream& output); }; -static_assert(cloyster::concepts::Parser>); +static_assert(cloyster::concepts::IsParser>); // @TODO: Move this to its own file /** @@ -71,27 +151,6 @@ class RPMRepositoryFile final { static_assert(cloyster::concepts::IsSaveable); static_assert(cloyster::concepts::NotCopiableMoveable); -// @TODO WIP, rename to RepoManager and replace the old RepoManager -/** - * @brief Enable/disable, install/uninstall repositories to/from the filesystem - */ -template class NewRepoManager final { -public: - ~NewRepoManager() = default; - NewRepoManager() = default; - NewRepoManager(const NewRepoManager&) = delete; - NewRepoManager& operator=(const NewRepoManager&) = delete; - NewRepoManager(NewRepoManager&&) = delete; - NewRepoManager& operator=(NewRepoManager&&) = delete; - - void load(const std::filesystem::path& path); - void enable(const std::string& id); - void enable(std::vector ids); - void disable(const std::string& id); - void disable(std::vector ids); - const std::vector& listRepos() const; -}; - } // namespace cloyster; #endif diff --git a/include/cloysterhpc/repos.h b/include/cloysterhpc/services/repos.h similarity index 50% rename from include/cloysterhpc/repos.h rename to include/cloysterhpc/services/repos.h index a85f2007..e792ca1f 100644 --- a/include/cloysterhpc/repos.h +++ b/include/cloysterhpc/services/repos.h @@ -8,78 +8,60 @@ #ifndef CLOYSTERHPC_REPOS_H_DEPRECATED_ #define CLOYSTERHPC_REPOS_H_DEPRECATED_ -#include -#include -#include - -#include #include -#include -#include #include +#include +#include +#include +#include + namespace cloyster { extern std::string customRepofilePath; }; -template -concept IsRepository = requires(T repo) -{ - { repo.id } -> std::convertible_to; - { repo.enabled } -> std::convertible_to; - { repo.name } -> std::convertible_to; - { repo.baseurl } -> std::convertible_to>; - { repo.metalink } -> std::convertible_to>; - { repo.gpgcheck } -> std::convertible_to; - { repo.gpgkey } -> std::convertible_to; - { repo.source } -> std::convertible_to; -}; - -struct repository { - std::string id; - bool enabled = true; - std::string name; - std::string baseurl; - std::string metalink; - bool gpgcheck = true; - std::string gpgkey; - std::filesystem::path source; -}; -static_assert(IsRepository); +namespace cloyster::services::repos { -template -class /* [[deprecated("refactoring")]] */ RepoManager { +class RepoManager { + using OS = cloyster::models::OS; public: - RepoManager(Runner& runner, const OS& osinfo); + RepoManager(BaseRunner& runner, const OS& osinfo); void loadFiles(const std::filesystem::path& basedir = "/etc/yum.repos.d"); void commitStatus(); void enable(const std::string& repo); void enableMultiple(std::vector repos); void disable(const std::string& repo); - const std::vector& listRepos() const; + [[nodiscard]] const std::vector& listRepos() const; [[nodiscard]] std::vector getxCATOSImageRepos() const; private: void loadCustom(inifile& file, const std::filesystem::path& path); // BUG: Enable and EnableMultiple are the same method. Overload it. - std::vector m_repos; + std::vector m_repos; BaseRunner& m_runner; const OS& m_os; void createFileFor(std::filesystem::path path); - const std::vector buildCloysterTree( + // Repository type is required to be known here so + // it can be constructed by buildCloysterTree + template + + std::vector buildCloysterTree( const std::filesystem::path& basedir); - void loadSingleFile(std::filesystem::path source); + void loadSingleFile(const std::filesystem::path& source); + void saveRepositories(); void configureXCAT(const std::filesystem::path& repofile_dest); void configureEL(); void setEnableState(const std::string& id, bool value); + template void mergeWithCurrentList(std::vector&& repo); }; +}; #endif // CLOYSTERHPC_REPOS_H_DEPRECATED_ diff --git a/include/cloysterhpc/runner.h b/include/cloysterhpc/services/runner.h similarity index 93% rename from include/cloysterhpc/runner.h rename to include/cloysterhpc/services/runner.h index 5110a247..15e26169 100644 --- a/include/cloysterhpc/runner.h +++ b/include/cloysterhpc/services/runner.h @@ -9,6 +9,8 @@ #include #include +namespace cloyster::services { + /** * Works as an abstraction for command execution. */ @@ -47,4 +49,6 @@ class MockRunner : public BaseRunner { std::vector m_cmds; }; +} // namespace cloyster::services + #endif // CLOYSTERHPC_RUNNER_H_ diff --git a/include/cloysterhpc/services/shell.h b/include/cloysterhpc/services/shell.h index abba471e..a972ceef 100644 --- a/include/cloysterhpc/services/shell.h +++ b/include/cloysterhpc/services/shell.h @@ -8,9 +8,12 @@ #include -#include +#include #include +namespace cloyster::services { + +using cloyster::models::Cluster; /** * @class Shell * @brief Manages the configuration and installation processes on a cluster. @@ -187,4 +190,6 @@ class Shell : public Execution { void install() override; }; +}; + #endif // CLOYSTERHPC_SHELL_H_ diff --git a/include/cloysterhpc/services/xcat.h b/include/cloysterhpc/services/xcat.h index 5fd36937..f72ae64d 100644 --- a/include/cloysterhpc/services/xcat.h +++ b/include/cloysterhpc/services/xcat.h @@ -18,6 +18,8 @@ #include #include +namespace cloyster::services { + /** * @class XCAT * @brief Manages the provisioning of nodes using the xCAT tool. @@ -161,7 +163,7 @@ class XCAT : public Provisioner { * * @param node The node to add. */ - static void addNode(const Node& node); + static void addNode(const cloyster::models::Node& node); /** * @brief Generates the OS image name based on type and node. @@ -254,4 +256,6 @@ class XCAT : public Provisioner { explicit XCAT(const std::unique_ptr& cluster); }; +}; + #endif // CLOYSTERHPC_XCAT_H_ diff --git a/src/diskImage.cpp b/src/diskImage.cpp index 738b0e24..88217cb9 100644 --- a/src/diskImage.cpp +++ b/src/diskImage.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/src/functions.cpp b/src/functions.cpp index ba983737..98ee8380 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -19,33 +19,40 @@ #include #include #include +#include #include namespace cloyster { +using cloyster::services::BaseRunner; +using cloyster::services::Runner; +using cloyster::services::DryRunner; + namespace { -std::tuple> retrieveLine( - boost::process::ipstream& pipe_stream, - const std::function& linecheck) -{ - if (pipe_stream.good()) { - return make_tuple(true, make_optional(linecheck(pipe_stream))); + std::tuple> retrieveLine( + boost::process::ipstream& pipe_stream, + const std::function& linecheck) + { + if (pipe_stream.good()) { + return make_tuple(true, make_optional(linecheck(pipe_stream))); + } + + return make_tuple(pipe_stream.good(), std::nullopt); } - return make_tuple(pipe_stream.good(), std::nullopt); -} + std::shared_ptr makeRunner(const bool dryRun) + { + if (dryRun) { + return std::make_shared(); + } -std::shared_ptr makeRunner(const bool dryRun) { - if (dryRun) { - return std::make_shared(); + return std::make_shared(); } - return std::make_shared(); -} - } // anonymous namespace -std::shared_ptr getRunner() { +std::shared_ptr getRunner() +{ static std::optional> runner = std::nullopt; if (!runner) { runner = makeRunner(cloyster::dryRun); @@ -54,16 +61,30 @@ std::shared_ptr getRunner() { return runner.value(); } -std::shared_ptr> getRepoManager(const OS& osinfo) { - static std::optional>> repoManager = std::nullopt; +using cloyster::services::repos::IsRepository; +using cloyster::services::repos::RepoManager; + +std::shared_ptr getRepoManager( + const OS& osinfo) +{ + static std::optional> repoManager = std::nullopt; if (!repoManager) { - repoManager = std::make_shared>(*getRunner(), osinfo); + switch (osinfo.getPackageType()) { + case OS::PackageType::RPM: + repoManager + = std::make_shared( + *getRunner(), osinfo); + break; + case OS::PackageType::DEB: + // @TODO Implement + throw std::logic_error("Not implemented"); + break; + } } return repoManager.value(); } - std::optional CommandProxy::getline() { @@ -381,12 +402,4 @@ void copyFile(std::filesystem::path source, std::filesystem::path destination) } } -std::optional readKeyfileString(Glib::RefPtr file, - const std::string_view group, const std::string_view key) -{ - return file->has_key(group.data(), key.data()) - ? std::make_optional(file->get_string(group.data(), key.data())) - : std::nullopt; -} - } // namespace cloyster diff --git a/src/mailsystem/postfix.cpp b/src/mailsystem/postfix.cpp index f3678efa..26282b8a 100644 --- a/src/mailsystem/postfix.cpp +++ b/src/mailsystem/postfix.cpp @@ -10,10 +10,11 @@ #include #include #include -#include +#include #include using cloyster::runCommand; +using cloyster::services::BaseRunner; Postfix::Postfix( std::shared_ptr bus, BaseRunner& runner, Profile profile) @@ -291,6 +292,8 @@ void Postfix::configureRelay(const std::filesystem::path& basedir) #include #include +#ifdef BUILD_TESTING + TEST_SUITE("Test repository file read and write") { TEST_CASE( @@ -355,3 +358,5 @@ TEST_SUITE("Test repository file read and write") == 1); } } + +#endif diff --git a/src/main.cpp b/src/main.cpp index aa1f5379..e6b97289 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,16 +8,16 @@ #include #include -#include +#include #include #include #include #include -#include #include #include #include #include +#include #ifdef _CLOYSTER_I18N #include "include/i18n-cpp.hpp" @@ -150,7 +150,7 @@ int main(int argc, const char** argv) return EXIT_FAILURE; } - auto model = std::make_unique(); + auto model = std::make_unique(); if (!cloyster::answerfile.empty()) { LOG_TRACE("Answerfile: {}", cloyster::answerfile) model->fillData(cloyster::answerfile); @@ -166,7 +166,7 @@ int main(int argc, const char** argv) if (cloyster::enableTUI) { // Entrypoint; if the view is constructed it will start the TUI. auto view = std::make_unique(); - auto presenter = std::make_unique(model, view); + auto presenter = std::make_unique(model, view); } LOG_TRACE("Starting execution engine"); @@ -176,7 +176,7 @@ int main(int argc, const char** argv) } std::unique_ptr executionEngine - = std::make_unique(model); + = std::make_unique(model); executionEngine->install(); diff --git a/src/answerfile.cpp b/src/models/answerfile.cpp similarity index 99% rename from src/answerfile.cpp rename to src/models/answerfile.cpp index 4906b64f..12d28d4f 100644 --- a/src/answerfile.cpp +++ b/src/models/answerfile.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -16,6 +16,8 @@ #include #include +namespace cloyster::models { + AnswerFile::AnswerFile(const std::filesystem::path& path) : m_path(path) { @@ -605,6 +607,8 @@ void AnswerFile::loadPostfix() postfix.key_file = m_ini.getValue("postfix", "smtpd_tls_key_file", false); } +}; + #ifdef BUILD_TESTING #include diff --git a/src/cluster.cpp b/src/models/cluster.cpp similarity index 98% rename from src/cluster.cpp rename to src/models/cluster.cpp index 33910673..238124e5 100644 --- a/src/cluster.cpp +++ b/src/models/cluster.cpp @@ -3,35 +3,39 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include #include -#include #include -#include -#include -#include #ifndef NDEBUG #include #endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #if __cpp_lib_starts_ends_with < 201711L #include #endif +using cloyster::services::BaseRunner; +using cloyster::services::DryRunner; +using cloyster::services::Runner; + static constexpr std::unique_ptr makeRunner(const bool option) { if (option) { @@ -41,6 +45,8 @@ static constexpr std::unique_ptr makeRunner(const bool option) } } +namespace cloyster::models { + Cluster::Cluster() : m_systemdBus(std::make_shared( "org.freedesktop.systemd1", "/org/freedesktop/systemd1")) @@ -935,3 +941,5 @@ void Cluster::fillData(const std::filesystem::path& answerfilePath) nodeStartIP = answerfile.nodes.generic->start_ip.value(); nodeRootPassword = answerfile.nodes.generic->root_password.value(); } + + }; // namespace cloyster::models { diff --git a/src/cpu.cpp b/src/models/cpu.cpp similarity index 95% rename from src/cpu.cpp rename to src/models/cpu.cpp index a09893ce..5c42f4b1 100644 --- a/src/cpu.cpp +++ b/src/models/cpu.cpp @@ -3,7 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include + +#include + +namespace cloyster::models { CPU::CPU() : m_sockets(0) @@ -66,3 +70,5 @@ void CPU::setThreadsPerCore(size_t threadsPerCore) { m_threadsPerCore = threadsPerCore; } + +} diff --git a/src/headnode.cpp b/src/models/headnode.cpp similarity index 94% rename from src/headnode.cpp rename to src/models/headnode.cpp index 5c839075..f79d36b2 100644 --- a/src/headnode.cpp +++ b/src/models/headnode.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include /* std::remove */ @@ -18,12 +18,15 @@ #include #include +namespace cloyster::models { + /* The constructor should discover everything we need from the machine that is * running the software. We always consider that the software runs from the * server that will become the cluster headnode. */ // Headnode::Headnode () = default; + Headnode::Headnode() : m_bootTarget(BootTarget::Text) { @@ -54,3 +57,5 @@ void Headnode::setBootTarget(Headnode::BootTarget bootTarget) { m_bootTarget = bootTarget; } + +}; diff --git a/src/node.cpp b/src/models/node.cpp similarity index 94% rename from src/node.cpp rename to src/models/node.cpp index 6a775523..4c804766 100644 --- a/src/node.cpp +++ b/src/models/node.cpp @@ -3,7 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include + +namespace cloyster::models { Node::Node(std::string_view hostname, OS& os, CPU& cpu, std::list&& connections, std::optional bmc) @@ -46,3 +48,5 @@ void Node::setNodeRootPassword( { m_node_root_password = nodeRootPassword; } + +} diff --git a/src/os.cpp b/src/models/os.cpp similarity index 99% rename from src/os.cpp rename to src/models/os.cpp index 471894d3..2915de45 100644 --- a/src/os.cpp +++ b/src/models/os.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include @@ -22,6 +22,8 @@ #include #include +namespace cloyster::models { + OS::OS() { struct utsname system {}; @@ -267,4 +269,6 @@ void OS::printData() const LOG_DEBUG("Major Version: {}", m_majorVersion) LOG_DEBUG("Minor Version: {}", m_minorVersion) } + +}; #endif diff --git a/src/queuesystem/pbs.cpp b/src/models/pbs.cpp similarity index 85% rename from src/queuesystem/pbs.cpp rename to src/models/pbs.cpp index 8fab7937..a712ce19 100644 --- a/src/queuesystem/pbs.cpp +++ b/src/models/pbs.cpp @@ -3,7 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include + +namespace cloyster::models { PBS::PBS(const Cluster& cluster) : QueueSystem(cluster) @@ -17,3 +19,5 @@ void PBS::setExecutionPlace(ExecutionPlace executionPlace) } PBS::ExecutionPlace PBS::getExecutionPlace(void) { return m_executionPlace; } + +} diff --git a/src/queuesystem/queuesystem.cpp b/src/models/queuesystem.cpp similarity index 80% rename from src/queuesystem/queuesystem.cpp rename to src/models/queuesystem.cpp index 28db9aed..ed91d5aa 100644 --- a/src/queuesystem/queuesystem.cpp +++ b/src/models/queuesystem.cpp @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include +#include +#include +namespace cloyster::models { QueueSystem::QueueSystem(const Cluster& cluster) : m_cluster(cluster) { @@ -21,3 +22,5 @@ void QueueSystem::setDefaultQueue(std::string_view defaultQueue) } std::string_view QueueSystem::getDefaultQueue(void) { return m_defaultQueue; } + +}; diff --git a/src/server.cpp b/src/models/server.cpp similarity index 98% rename from src/server.cpp rename to src/models/server.cpp index cad0787d..c7210119 100644 --- a/src/server.cpp +++ b/src/models/server.cpp @@ -1,12 +1,15 @@ /* + * o * Copyright 2021 Vinícius Ferrão * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include +#include #include +namespace cloyster::models { Server::Server(std::string_view hostname, OS& os, CPU& cpu, std::list&& connections, std::optional bmc) : m_os(os) @@ -173,3 +176,5 @@ TEST_SUITE("Test FQDN") } } } + +} diff --git a/src/queuesystem/slurm.cpp b/src/models/slurm.cpp similarity index 94% rename from src/queuesystem/slurm.cpp rename to src/models/slurm.cpp index fbd299f3..54244d0b 100644 --- a/src/queuesystem/slurm.cpp +++ b/src/models/slurm.cpp @@ -3,13 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include +#include +#include #include #include using cloyster::runCommand; +namespace cloyster::models { SLURM::SLURM(const Cluster& cluster) : QueueSystem(cluster) { @@ -59,3 +60,5 @@ void SLURM::startServer() runCommand("systemctl start munge"); runCommand("systemctl start slurmctld"); } + +} diff --git a/src/presenter/PresenterGeneralSettings.cpp b/src/presenter/PresenterGeneralSettings.cpp index 00b8036c..f04a38f5 100644 --- a/src/presenter/PresenterGeneralSettings.cpp +++ b/src/presenter/PresenterGeneralSettings.cpp @@ -5,6 +5,10 @@ #include +namespace cloyster::presenter { + +using cloyster::models::Headnode; + PresenterGeneralSettings::PresenterGeneralSettings( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -40,3 +44,5 @@ PresenterGeneralSettings::PresenterGeneralSettings( magic_enum::enum_name( m_model->getHeadnode().getBootTarget())); } + +}; diff --git a/src/presenter/PresenterHostId.cpp b/src/presenter/PresenterHostId.cpp index d1e62dda..f542bacd 100644 --- a/src/presenter/PresenterHostId.cpp +++ b/src/presenter/PresenterHostId.cpp @@ -5,6 +5,8 @@ #include +namespace cloyster::presenter { + PresenterHostId::PresenterHostId( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -52,3 +54,5 @@ PresenterHostId::PresenterHostId( LOG_DEBUG("Domain name set to: {}", m_model->getDomainName()) LOG_DEBUG("FQDN: {}", m_model->getHeadnode().getFQDN()) } + +}; diff --git a/src/presenter/PresenterInfiniband.cpp b/src/presenter/PresenterInfiniband.cpp index f2d47d65..cffa5596 100644 --- a/src/presenter/PresenterInfiniband.cpp +++ b/src/presenter/PresenterInfiniband.cpp @@ -7,6 +7,8 @@ #include +namespace cloyster::presenter { + PresenterInfiniband::PresenterInfiniband(std::unique_ptr& model, std::unique_ptr& view, NetworkCreator& nc) : Presenter(model, view) @@ -40,3 +42,5 @@ PresenterInfiniband::PresenterInfiniband(std::unique_ptr& model, } } } + +} diff --git a/src/presenter/PresenterInstall.cpp b/src/presenter/PresenterInstall.cpp index c7dcc8e9..c0d8b096 100644 --- a/src/presenter/PresenterInstall.cpp +++ b/src/presenter/PresenterInstall.cpp @@ -18,6 +18,7 @@ #include #include +namespace cloyster::presenter { PresenterInstall::PresenterInstall( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -89,3 +90,5 @@ PresenterInstall::PresenterInstall( // Destroy the view since we don't need it anymore m_view.reset(); } + +} diff --git a/src/presenter/PresenterInstructions.cpp b/src/presenter/PresenterInstructions.cpp index bc20600c..d19dc1df 100644 --- a/src/presenter/PresenterInstructions.cpp +++ b/src/presenter/PresenterInstructions.cpp @@ -5,6 +5,8 @@ #include +namespace cloyster::presenter { + PresenterInstructions::PresenterInstructions( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -13,3 +15,5 @@ PresenterInstructions::PresenterInstructions( m_view->message(Messages::Instructions::message); LOG_DEBUG("Install instructions displayed") } + +} diff --git a/src/presenter/PresenterLocale.cpp b/src/presenter/PresenterLocale.cpp index 8ae8e6da..dcafaba3 100644 --- a/src/presenter/PresenterLocale.cpp +++ b/src/presenter/PresenterLocale.cpp @@ -5,6 +5,8 @@ #include +namespace cloyster::presenter { + PresenterLocale::PresenterLocale( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -17,3 +19,5 @@ PresenterLocale::PresenterLocale( m_model->setLocale(selectedLocale); LOG_DEBUG("Locale set to: {}", m_model->getLocale().getLocale()) } + +}; diff --git a/src/presenter/PresenterMailSystem.cpp b/src/presenter/PresenterMailSystem.cpp index 9b709496..ff467596 100644 --- a/src/presenter/PresenterMailSystem.cpp +++ b/src/presenter/PresenterMailSystem.cpp @@ -6,6 +6,7 @@ #include #include +namespace cloyster::presenter { PresenterMailSystem::PresenterMailSystem( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -84,3 +85,5 @@ PresenterMailSystem::PresenterMailSystem( LOG_DEBUG("Postfix wasn't enabled") } } + +}; diff --git a/src/presenter/PresenterNetwork.cpp b/src/presenter/PresenterNetwork.cpp index 711e0cdd..8b23f54f 100644 --- a/src/presenter/PresenterNetwork.cpp +++ b/src/presenter/PresenterNetwork.cpp @@ -13,6 +13,8 @@ #include +namespace cloyster::presenter { + bool NetworkCreator::checkIfProfileExists(Network::Profile profile) { namespace ranges = std::ranges; @@ -194,3 +196,5 @@ void PresenterNetwork::createNetwork( ncd.name = networkDetails[i++].second; ncd.domains = nameservers; } + +} diff --git a/src/presenter/PresenterNodes.cpp b/src/presenter/PresenterNodes.cpp index 351479bc..1f24e8dc 100644 --- a/src/presenter/PresenterNodes.cpp +++ b/src/presenter/PresenterNodes.cpp @@ -5,6 +5,8 @@ #include +namespace cloyster::presenter { + PresenterNodes::PresenterNodes( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -107,3 +109,5 @@ PresenterNodes::PresenterNodes( ); } } + +}; diff --git a/src/presenter/PresenterNodesOperationalSystem.cpp b/src/presenter/PresenterNodesOperationalSystem.cpp index a4fa95b8..5b4db77e 100644 --- a/src/presenter/PresenterNodesOperationalSystem.cpp +++ b/src/presenter/PresenterNodesOperationalSystem.cpp @@ -19,6 +19,8 @@ namespace fs = std::filesystem; +namespace cloyster::presenter { + std::string PresenterNodesOperationalSystem::getDownloadURL( OS::Distro distro, PresenterNodesVersionCombo version) { @@ -297,3 +299,5 @@ PresenterNodesOperationalSystem::PresenterNodesOperationalSystem( fmt::format("{}/{}", isoDirectoryPath.data()->second, selectedIso)); } } + +}; diff --git a/src/presenter/PresenterQueueSystem.cpp b/src/presenter/PresenterQueueSystem.cpp index 5dbb0bad..b5aec9f9 100644 --- a/src/presenter/PresenterQueueSystem.cpp +++ b/src/presenter/PresenterQueueSystem.cpp @@ -5,6 +5,10 @@ #include +namespace cloyster::presenter { + +using cloyster::models::SLURM; + PresenterQueueSystem::PresenterQueueSystem( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -57,3 +61,4 @@ PresenterQueueSystem::PresenterQueueSystem( } } } +} diff --git a/src/presenter/PresenterRepository.cpp b/src/presenter/PresenterRepository.cpp index ee5fcc4e..f43b38bd 100644 --- a/src/presenter/PresenterRepository.cpp +++ b/src/presenter/PresenterRepository.cpp @@ -5,23 +5,32 @@ #include #include +#include + +namespace cloyster::presenter { + +using cloyster::services::repos::RPMRepository; PresenterRepository::PresenterRepository( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) { - auto manager = *cloyster::getRepoManager(model->getHeadnode().getOS()); + // @TODO generalize getRepoManager, client must need to know the underliying repository + // type + auto manager = cloyster::getRepoManager(model->getHeadnode().getOS()); + + manager->loadFiles(); - manager.loadFiles(); + const std::vector& repo_names = manager->listRepos(); - auto repo_names = manager.listRepos(); std::vector> repo_strings; std::transform(repo_names.begin(), repo_names.end(), - std::back_inserter(repo_strings), [](auto entry) { - return std::make_tuple(std::string { entry.id }, - std::string { entry.name }, entry.enabled); + std::back_inserter(repo_strings), [](auto& entry) { + return std::make_tuple(std::string { entry.id() }, + std::string { entry.name() }, entry.enabled() ); }); + assert(repo_strings.size() > 0); // reminder to fix this const auto& [ret, selectedRepositories] = m_view->multipleSelectionMenu(Messages::title, @@ -31,11 +40,13 @@ PresenterRepository::PresenterRepository( if (ret == 1) { for (const auto& [id, _name, _state] : repo_strings) { - manager.disable(id); + manager->disable(id); } for (const auto& repo : selectedRepositories) { - manager.enable(repo); + manager->enable(repo); } } } + +} diff --git a/src/presenter/PresenterTime.cpp b/src/presenter/PresenterTime.cpp index 95b52970..aee3f830 100644 --- a/src/presenter/PresenterTime.cpp +++ b/src/presenter/PresenterTime.cpp @@ -6,6 +6,8 @@ #include #include +namespace cloyster::presenter { + PresenterTime::PresenterTime( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -73,3 +75,5 @@ PresenterTime::PresenterTime( LOG_DEBUG("Timeservers set to {}", fmt::join(m_model->getTimezone().getTimeservers(), ", ")); } + +}; diff --git a/src/presenter/PresenterWelcome.cpp b/src/presenter/PresenterWelcome.cpp index 91433186..ff7429e4 100644 --- a/src/presenter/PresenterWelcome.cpp +++ b/src/presenter/PresenterWelcome.cpp @@ -5,6 +5,8 @@ #include +namespace cloyster::presenter { + PresenterWelcome::PresenterWelcome( std::unique_ptr& model, std::unique_ptr& view) : Presenter(model, view) @@ -13,3 +15,5 @@ PresenterWelcome::PresenterWelcome( m_view->message(Messages::Welcome::message); LOG_DEBUG("Welcome message displayed") } + +}; diff --git a/src/services/files.cpp b/src/services/files.cpp index 0e213f8e..e6429e93 100644 --- a/src/services/files.cpp +++ b/src/services/files.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -18,6 +19,30 @@ struct KeyFile::Impl { , m_keyfile(std::move(keyfile)) { }; + + void safeToFile(const std::filesystem::path& path) { + try { + m_keyfile->save_to_file(path); + } catch (std::runtime_error& e) { + throw FileException(e.what()); + } + } + + void loadFromFile(const std::filesystem::path& path) { + try { + m_keyfile->load_from_file(path); + } catch (std::runtime_error& e) { + throw FileException(e.what()); + } + } + + void loadFromData(const std::string& data) { + try { + m_keyfile->load_from_data(data); + } catch (std::runtime_error& e) { + throw FileException(e.what()); + } + } }; KeyFile::KeyFile(KeyFile::Impl&& impl) @@ -28,7 +53,7 @@ KeyFile::KeyFile(KeyFile::Impl&& impl) KeyFile::KeyFile(const std::filesystem::path& path) { m_impl = std::make_unique(Glib::KeyFile::create(), path); - m_impl->m_keyfile->load_from_file(path); + m_impl->loadFromFile(path); m_impl->m_path = path; } @@ -38,7 +63,7 @@ KeyFile::KeyFile(std::istream& istream) std::istreambuf_iterator begin(istream); std::istreambuf_iterator end; std::string data(begin, end); - m_impl->m_keyfile->load_from_data(data); + m_impl->loadFromData(data); } KeyFile::~KeyFile() = default; @@ -94,12 +119,12 @@ void KeyFile::setBoolean(const std::string& group, const std::string& key, const void KeyFile::save() { - m_impl->m_keyfile->save_to_file(m_impl->m_path); + m_impl->safeToFile(m_impl->m_path); } void KeyFile::load() { - m_impl->m_keyfile->load_from_file(m_impl->m_path); + m_impl->loadFromFile(m_impl->m_path); } } // namespace cloyster::services::files diff --git a/src/services/repo.cpp b/src/services/repo.cpp deleted file mode 100644 index 38603eda..00000000 --- a/src/services/repo.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2025 Vinícius Ferrão - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -// TEST CODE: Load a repository file and dump it on the terminal -// Call it in main(): -// repo::load_repository(std::string { "/etc/yum.repos.d/redhat.repo" }); - diff --git a/src/services/repofile.cpp b/src/services/repofile.cpp index 51388e09..75b9fff9 100644 --- a/src/services/repofile.cpp +++ b/src/services/repofile.cpp @@ -4,13 +4,14 @@ #include -namespace cloyster { +namespace cloyster::services::repos { namespace { using cloyster::services::files::IsKeyFileReadable; -template -void parseData(KeyFile& file, std::vector repositories) + +template +void parseDataRPM(KeyFile& file, std::vector& repositories) { auto reponames = file.getGroups(); repositories.reserve(reponames.size()); @@ -31,30 +32,28 @@ void parseData(KeyFile& file, std::vector repositories) auto gpgkey = file.getString(repogroup, "gpgkey"); RPMRepository repo; - repo.group = repogroup; - repo.name = name; - repo.metalink = metalink; - repo.baseurl = baseurl; - repo.enabled = enabled; - repo.gpgcheck = gpgcheck; - repo.gpgkey = gpgkey; + repo.group(repogroup); + repo.name(name); + repo.metalink(metalink); + repo.baseurl(baseurl); + repo.enabled(enabled); + repo.gpgcheck(gpgcheck); + repo.gpgkey(gpgkey); repositories.emplace_back(std::move(repo)); } } using cloyster::services::files::IsKeyFileWriteable; template -void unparseData(const std::vector& repositories, KeyFile& file) +void unparseDataRPM(const std::vector& repositories, KeyFile& file) { for (const auto& repo : repositories) { - file.setString(repo.group, "name", repo.name); - file.setBoolean(repo.group, "enabled", repo.enabled); - file.setBoolean(repo.group, "gpgcheck", repo.gpgcheck); - file.setString(repo.group, "gpgkey", repo.gpgkey); - // uhh spooky, setString over optional only write if the - // optional has a value - file.setString(repo.group, "metalink", repo.metalink); - file.setString(repo.group, "baseurl", repo.metalink); + file.setString(repo.group(), "name", repo.name()); + file.setBoolean(repo.group(), "enabled", repo.enabled()); + file.setBoolean(repo.group(), "gpgcheck", repo.gpgcheck()); + file.setString(repo.group(), "gpgkey", repo.gpgkey()); + file.setString(repo.group(), "metalink", repo.metalink()); + file.setString(repo.group(), "baseurl", repo.metalink()); } } }; @@ -62,14 +61,15 @@ void unparseData(const std::vector& repositories, KeyFile& file) void RPMRepositoryParser::parse(std::istream& input, std::vector& output) { auto keyfile = cloyster::services::files::KeyFile(input); - parseData(keyfile, output); + parseDataRPM(keyfile, output); } void RPMRepositoryParser::unparse(const std::vector& repos, std::ostream& output) { std::istringstream input(""); auto keyfile = cloyster::services::files::KeyFile(input); - unparseData(repos, keyfile); + unparseDataRPM(repos, keyfile); } + /* void ELRepoFile::read() { diff --git a/src/repos.cpp b/src/services/repos.cpp similarity index 75% rename from src/repos.cpp rename to src/services/repos.cpp index 4264da14..ccf960a3 100644 --- a/src/repos.cpp +++ b/src/services/repos.cpp @@ -7,10 +7,9 @@ #include #include #include -#include -#include +#include #include -#include +#include #include #include #include @@ -38,6 +37,8 @@ constexpr std::string_view CLOYSTER_REPO_EL10 = { }; +using cloyster::services::repos::IsRepository; + template [[deprecated("RepoManager refactoring")]] Repository loadSection(const std::filesystem::path& source, @@ -73,6 +74,7 @@ template [[deprecated("RepoManager refactoring")]] void writeSection(inifile& file, const Repository& repo) { + /* std::string section = repo.id; file.setValue(section, "name", repo.name); @@ -83,23 +85,11 @@ void writeSection(inifile& file, const Repository& repo) LOG_INFO("writing repo <{}> (id {}) at {}", repo.name, section, repo.source.string()); + */ } -template -[[deprecated("RepoManager refactoring")]] -void loadFromINI(const std::filesystem::path& source, inifile& file, - std::vector& out) -{ - auto sections = file.listAllSections(); - - for (const auto& reponame : sections) { - auto r = loadSection(source, file, reponame); - out.push_back(r); - } -} - -template Parser> -void loadFromConf(const std::filesystem::path& source, std::vector& out, const Parser& parser) +template Parser> +void loadFromConf(const std::filesystem::path& source, std::vector& out, const Parser& parser) { std::ifstream input(source); parser.parse(input, out); @@ -108,60 +98,25 @@ void loadFromConf(const std::filesystem::path& source, std::vector& out, c } // anonymous namespace -// BUG: Why? -#define NOSONAR(code) code - -template -RepoManager::RepoManager(Runner& runner, const OS& osinfo) - : m_runner(runner) - , m_os(osinfo) -{ -} +namespace cloyster::services::repos { -template <> -RepoManager::RepoManager(DryRunner& runner, const OS& osinfo) - : m_runner(runner) - , m_os(osinfo) -{ -} -template <> -RepoManager::RepoManager(Runner& runner, const OS& osinfo) +RepoManager::RepoManager(BaseRunner& runner, const OS& osinfo) : m_runner(runner) , m_os(osinfo) { } -template <> -RepoManager::RepoManager(BaseRunner& runner, const OS& osinfo) - : m_runner(runner) - , m_os(osinfo) -{ -} - -template -[[deprecated("RepoManager refactoring")]] -void RepoManager::loadSingleFile(std::filesystem::path source) -{ - // inifile file; - // file.loadFile(source); - //loadFromINI(source, file, m_repos); - // const auto parser = cloyster::RPMRepositoryParser(); - // loadFromConf(source, m_repos, parser); - throw std::runtime_error("Not implemented"); -} - -template <> -void RepoManager::loadSingleFile(std::filesystem::path source) +void RepoManager::loadSingleFile(const std::filesystem::path& source) { LOG_DEBUG("New repo manager bootstraping"); - constexpr auto parser = cloyster::RPMRepositoryParser(); + constexpr auto parser = cloyster::services::repos::RPMRepositoryParser(); std::ifstream input(source); - parser.parse(input, m_repos); + // @FIXME: Fix parser dynamic dispatch!? + //parser.parse(input, m_repos); } -template <> -void RepoManager::loadFiles(const std::filesystem::path& basedir) +void RepoManager::loadFiles(const std::filesystem::path& basedir) { for (auto const& dir_entry : std::filesystem::directory_iterator { basedir }) { @@ -172,11 +127,20 @@ void RepoManager::loadFiles(const std::filesystem::path& } - auto cloyster_repos = buildCloysterTree(basedir); + std::vector cloyster_repos; + + switch (m_os.getPackageType()) { + case OS::PackageType::RPM: + cloyster_repos = buildCloysterTree(basedir); + break; + case OS::PackageType::DEB: + throw std::logic_error("Not implemented deb packages"); + break; + } mergeWithCurrentList(std::move(cloyster_repos)); auto destparent - = NOSONAR(std::filesystem::temp_directory_path()) / "cloyster0"; + = std::filesystem::temp_directory_path() / "cloyster0"; auto destination = destparent / "yum.repos.d"; cloyster::createDirectory(destparent); cloyster::createDirectory(destination); @@ -193,37 +157,33 @@ void RepoManager::loadFiles(const std::filesystem::path& } } -template -void RepoManager::loadCustom(inifile& file, const std::filesystem::path& path) +void RepoManager::loadCustom(inifile& file, const std::filesystem::path& path) { - std::vector data; - loadFromINI(path, file, data); - mergeWithCurrentList(std::move(data)); + std::vector data; + //loadFromINI(path, file, data); + //mergeWithCurrentList(std::move(data)); + // @TODO call loadFromConf } -template -void RepoManager::setEnableState(const std::string& id, bool value) +void RepoManager::setEnableState(const std::string& id, bool value) { for (auto& repo : m_repos) { - if (repo.id == id) { - repo.enabled = value; + if (repo.id() == id) { + repo.enabled(value); return; } } } -template <> -void RepoManager::enable(const std::string& id) { setEnableState(id, true); } +void RepoManager::enable(const std::string& id) { setEnableState(id, true); } -template <> -void RepoManager::enableMultiple(std::vector ids) +void RepoManager::enableMultiple(std::vector ids) { std::ranges::for_each(ids, [&](const auto& id) { this->enable(id); }); } -template <> -void RepoManager::disable(const std::string& id) { setEnableState(id, false); } +void RepoManager::disable(const std::string& id) { setEnableState(id, false); } static std::string buildPackageName(std::string stem) { @@ -266,8 +226,7 @@ static std::vector getDependenciesEL( return dependencies; } -template -void RepoManager::configureEL() +void RepoManager::configureEL() { std::vector deps = getDependenciesEL(m_os); @@ -277,15 +236,13 @@ void RepoManager::configureEL() }); } -template <> -void RepoManager::commitStatus() +void RepoManager::commitStatus() { // @TODO IS THIS CORRECT? BaseRunner should be upcasted here? // is m_runner dynamic dipatching m_runner.executeCommand("dnf -y install initscripts"); createFileFor("/etc/yum.repos.d/cloyster.repo"); - auto tmpdir = NOSONAR(std::filesystem::temp_directory_path()) - / "cloyster0/yum.repos.d"; + auto tmpdir = std::filesystem::temp_directory_path() / "cloyster0/yum.repos.d"; for (auto const& dir_entry : std::filesystem::directory_iterator { tmpdir }) { @@ -296,10 +253,10 @@ void RepoManager::commitStatus() std::vector to_disable; for (const auto& repo : m_repos) { - if (repo.enabled) { - to_enable.push_back(repo.id); + if (repo.enabled()) { + to_enable.push_back(repo.id()); } else { - to_disable.push_back(repo.id); + to_disable.push_back(repo.id()); } } @@ -316,28 +273,25 @@ void RepoManager::commitStatus() } } -// BUG: No... -#define FORMAT_TEMPLATE(src) fmt::format(src, cloyster::productName) - -template -const std::vector RepoManager::buildCloysterTree( +template +std::vector RepoManager::buildCloysterTree( const std::filesystem::path& basedir) { - std::vector cloyster_repos; + std::vector cloyster_repos; inifile file; // BUG: Implement a better way to handle this. if (cloyster::customRepofilePath.empty()) { switch (m_os.getPlatform()) { case OS::Platform::el8: - file.loadData(FORMAT_TEMPLATE(CLOYSTER_REPO_EL8)); + file.loadData(fmt::format(CLOYSTER_REPO_EL8, cloyster::productName)); break; case OS::Platform::el9: - file.loadData(FORMAT_TEMPLATE(CLOYSTER_REPO_EL9)); + file.loadData(fmt::format(CLOYSTER_REPO_EL9, cloyster::productName)); break; case OS::Platform::el10: - file.loadData(FORMAT_TEMPLATE(CLOYSTER_REPO_EL10)); + file.loadData(fmt::format(CLOYSTER_REPO_EL10, cloyster::productName)); break; default: throw std::runtime_error(fmt::format("Unsupported platform {}", @@ -349,14 +303,26 @@ const std::vector RepoManager::buildCloysterTree file.loadFile(cloyster::customRepofilePath); } - auto outpath = basedir / "cloyster.repo"; - loadFromINI(outpath, file, cloyster_repos); + + switch (m_os.getPackageType()) { + case OS::PackageType::RPM: + { + const auto parser = RPMRepositoryParser(); + auto outpath = basedir / "cloyster.repo"; + // @FIXME: FIx call to load conf + // loadFromConf(outpath, cloyster_repos, parser); + } + break; + case OS::PackageType::DEB: + throw std::logic_error("Not implemented"); + break; + } + return cloyster_repos; } -template -void RepoManager::createFileFor(std::filesystem::path path) +void RepoManager::createFileFor(std::filesystem::path path) { if (cloyster::dryRun) { LOG_INFO("Would create file {}", path.string()); @@ -371,7 +337,7 @@ void RepoManager::createFileFor(std::filesystem::path path) inifile file; auto filtered = m_repos | std::views::filter([&path](const auto& r) { - return path == r.source; + return path == r.source(); }); for (const auto& repo : filtered) { @@ -381,15 +347,13 @@ void RepoManager::createFileFor(std::filesystem::path path) file.saveFile(path); } - -template -void RepoManager::mergeWithCurrentList(std::vector&& repo) -{ - for (auto&& r : repo) { +template +void RepoManager::mergeWithCurrentList(std::vector&& repo) { + for (auto&& rep : repo) { if (std::find_if(m_repos.begin(), m_repos.end(), - [&](auto& v) { return v.id == r.id; }) - == m_repos.end()) { - m_repos.push_back(r); + [&](auto& v) { return v.id() == rep.id(); }) == m_repos.end()) { + // @FIXME: No constructor + // m_repos.push_back(rep); } } } @@ -408,8 +372,7 @@ static void createGPGKey( } -template -void RepoManager::configureXCAT(const std::filesystem::path& repofile_dest) +void RepoManager::configureXCAT(const std::filesystem::path& repofile_dest) { LOG_INFO("Setting up XCAT repositories"); @@ -440,8 +403,7 @@ void RepoManager::configureXCAT(const std::filesystem::path& } } -template <> -std::vector RepoManager::getxCATOSImageRepos() const +std::vector RepoManager::getxCATOSImageRepos() const { const auto osArch = magic_enum::enum_name(m_os.getArch()); const auto osMajorVersion = m_os.getMajorVersion(); @@ -545,17 +507,12 @@ std::vector RepoManager::getxCATOSImageRepos() return repos; } -template -const std::vector& RepoManager::listRepos() const +const std::vector& RepoManager::listRepos() const { return m_repos; } -template <> -const std::vector& RepoManager::listRepos() const -{ - return m_repos; -} +} // namespace cloyster::services::repos #ifdef BUILD_TESTING #include @@ -567,6 +524,7 @@ const std::vector& RepoManager::listRepos() #include #include +#ifdef BUILD_TESTING TEST_SUITE("Test repository file read and write") { TEST_CASE( @@ -628,3 +586,4 @@ TEST_SUITE("Test repository file read and write") */ } } +#endif diff --git a/src/runner.cpp b/src/services/runner.cpp similarity index 86% rename from src/runner.cpp rename to src/services/runner.cpp index fb5d90e5..daad4f38 100644 --- a/src/runner.cpp +++ b/src/services/runner.cpp @@ -1,9 +1,12 @@ #include #include -#include +#include #include + #include +namespace cloyster::services { + int BaseRunner::downloadFile(const std::string& url, const std::string& file) { auto cmd = fmt::format("wget -NP {} {}", file, url); @@ -31,3 +34,5 @@ const std::vector& MockRunner::listCommands() const { return m_cmds; } + +} // namespace cloyster::services diff --git a/src/services/shell.cpp b/src/services/shell.cpp index ed361c53..b46c8f80 100644 --- a/src/services/shell.cpp +++ b/src/services/shell.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include @@ -15,14 +18,17 @@ #include #include -#include -#include -#include +#include +#include +#include +#include #include using cloyster::runCommand; +namespace cloyster::services { + Shell::Shell(const std::unique_ptr& cluster) : m_cluster(cluster) { @@ -292,6 +298,11 @@ void Shell::configureTimeService(const std::list& connections) runCommand("systemctl enable --now chronyd"); } +using cloyster::models::QueueSystem; +using cloyster::models::SLURM; +using cloyster::models::PBS; +using cloyster::services::repos::RPMRepository; + void Shell::configureQueueSystem() { LOG_INFO("Setting up the queue system") @@ -401,18 +412,19 @@ void Shell::install() installRequiredPackages(); // TODO: This is the repos entrypoint. It should be replaced. - auto repos = *cloyster::getRepoManager(m_cluster->getHeadnode().getOS()); - repos.loadFiles(); - - const auto toEnable = - std::vector({ "-beegfs", "-elrepo", "-epel", "-openhpc", "-openhpc-updates", "-rpmfusion-free-updates" }) - | std::views::transform([&](const std::string& pkg) { - return cloyster::productName + pkg; - }) - | std::ranges::to>(); - - repos.enableMultiple(toEnable); - repos.commitStatus(); + auto repos = cloyster::getRepoManager(m_cluster->getHeadnode().getOS()); + repos->loadFiles(); + + const auto toEnable = std::vector(); + // @TODO Fix this + // std::vector({ "-beegfs", "-elrepo", "-epel", "-openhpc", "-openhpc-updates", "-rpmfusion-free-updates" }) + // | std::views::transform([&](const std::string& pkg) { + // return cloyster::productName + pkg; + // }) + // | std::ranges::to>(); + + repos->enableMultiple(toEnable); + repos->commitStatus(); // End of Repos entrypoint runSystemUpdate(); @@ -475,3 +487,5 @@ void Shell::install() provisioner->setNodesBoot(); provisioner->resetNodes(); } + +} diff --git a/src/services/xcat.cpp b/src/services/xcat.cpp index a89edf70..8bbd1d9a 100644 --- a/src/services/xcat.cpp +++ b/src/services/xcat.cpp @@ -3,15 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include // setenv / getenv + +#include + #include +#include #include #include #include +#include +#include -#include -#include -#include // setenv / getenv -#include + +namespace cloyster::services { + +using cloyster::models::Node; XCAT::XCAT(const std::unique_ptr& cluster) : m_cluster(cluster) @@ -256,7 +263,6 @@ void XCAT::generateSynclistsFile() void XCAT::configureOSImageDefinition() { // @TODO Fix this after finishing the repository refactoring - using RepoManager = RepoManager; Runner r; r.executeCommand(fmt::format("chdef -t osimage {} --plus otherpkglist=" "/install/custom/netboot/compute.otherpkglist", @@ -272,7 +278,7 @@ void XCAT::configureOSImageDefinition() /* Add external repositories to otherpkgdir */ - RepoManager repoManager(r, m_cluster->getNodes()[0].getOS()); + repos::RepoManager repoManager(r, m_cluster->getNodes()[0].getOS()); std::vector repos = repoManager.getxCATOSImageRepos(); r.executeCommand(fmt::format("chdef -t osimage {} --plus otherpkgdir={}", @@ -283,7 +289,7 @@ void XCAT::customizeImage() { // Permission fixes for munge if (m_cluster->getQueueSystem().value()->getKind() - == QueueSystem::Kind::SLURM) { + == models::QueueSystem::Kind::SLURM) { // @TODO This is using the Runner above and cloyster::runCommand here // choose only one! cloyster::runCommand( @@ -561,3 +567,5 @@ void XCAT::generateOSImagePath(ImageType imageType, NodeType nodeType) chroot += "/compute/rootimg"; m_stateless.chroot = chroot; } + +};