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

Commit 100725b

Browse files
committed
Add Cluster singleton with global getter
1 parent 8bbf4d1 commit 100725b

10 files changed

Lines changed: 120 additions & 71 deletions

File tree

include/cloysterhpc/functions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CLOYSTERHPC_FUNCTIONS_H_
22
#define CLOYSTERHPC_FUNCTIONS_H_
33

4+
#include <cloysterhpc/models/cluster.h>
45
#include <cloysterhpc/services/log.h>
56
#include <boost/process/child.hpp>
67
#include <boost/process/pipe.hpp>
@@ -19,6 +20,9 @@ namespace cloyster {
1920
extern bool dryRun;
2021

2122
using OS = cloyster::models::OS;
23+
24+
void initClusterSingleton(std::unique_ptr<models::Cluster> cluster);
25+
models::Cluster& getClusterSingleton();
2226
std::shared_ptr<cloyster::services::BaseRunner> getRunner();
2327
std::shared_ptr<cloyster::services::repos::RepoManager> getRepoManager(
2428
const OS& osinfo);

include/cloysterhpc/models/queuesystem.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#include <fmt/format.h>
1010
#include <string>
1111

12-
#include <cloysterhpc/functions.h>
13-
1412
// Forward declaration of Cluster
1513
namespace cloyster::models {
1614

include/cloysterhpc/services/shell.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ using cloyster::models::Cluster;
2323
*/
2424
class Shell final : public Execution {
2525
private:
26-
const std::unique_ptr<Cluster> m_cluster;
2726

2827
/**
2928
* @brief Configures SELinux mode.
@@ -171,20 +170,14 @@ class Shell final : public Execution {
171170
static void disableSELinux();
172171

173172
public:
174-
/**
175-
* @brief Constructs a Shell object.
176-
*
177-
* Initializes the Shell object with a reference to a Cluster object.
178-
*
179-
* @param cluster A reference to a unique pointer managing a Cluster object.
180-
*/
181-
explicit Shell(const std::unique_ptr<Cluster> cluster);
182173
/**
183174
* @brief Installs and configures the system.
184175
*
185176
* This function performs the installation and configuration processes.
186177
*/
187178
void install() override;
179+
180+
Shell();
188181
};
189182

190183
};

include/cloysterhpc/services/xcat.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ class XCAT : public Provisioner {
4545
*/
4646
enum class NodeType { Compute, Service };
4747

48-
const std::unique_ptr<Cluster>& m_cluster;
49-
5048
struct {
5149
std::vector<std::string_view> otherpkgs = {};
5250
// @TODO: We need to support more than one osimage (:
@@ -189,6 +187,9 @@ class XCAT : public Provisioner {
189187
static void configureEL9();
190188

191189
public:
190+
XCAT();
191+
192+
192193
/**
193194
* @brief Download the repositories
194195
*/
@@ -262,8 +263,6 @@ class XCAT : public Provisioner {
262263
* This function resets the nodes.
263264
*/
264265
static void resetNodes();
265-
266-
explicit XCAT(const std::unique_ptr<Cluster>& cluster);
267266
};
268267

269268
};

src/functions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ std::shared_ptr<BaseRunner> getRunner()
6666
using cloyster::models::Cluster;
6767
using cloyster::services::repos::RepoManager;
6868

69+
static std::unique_ptr<Cluster> clusterSingleton;
70+
void initClusterSingleton(std::unique_ptr<Cluster> cluster)
71+
{
72+
assert(!clusterSingleton);
73+
clusterSingleton = std::move(cluster);
74+
}
75+
76+
Cluster& getClusterSingleton()
77+
{
78+
assert(clusterSingleton);
79+
return *clusterSingleton;
80+
}
81+
6982
std::shared_ptr<RepoManager> getRepoManager(const OS& osinfo)
7083
{
7184
static std::optional<std::shared_ptr<RepoManager>> repoManager

src/main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cloysterhpc/services/shell.h>
1818
#include <cloysterhpc/verification.h>
1919
#include <cloysterhpc/view/newt.h>
20+
#include <cloysterhpc/functions.h>
2021
#include <internal_use_only/config.hpp>
2122
#include <regex>
2223

@@ -190,8 +191,10 @@ int main(int argc, const char** argv)
190191
model->dumpData(dumped_answerfile);
191192
}
192193

194+
cloyster::initClusterSingleton(std::move(model));
195+
193196
std::unique_ptr<Execution> executionEngine
194-
= std::make_unique<cloyster::services::Shell>(std::move(model));
197+
= std::make_unique<cloyster::services::Shell>();
195198

196199
executionEngine->install();
197200

src/models/slurm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <cloysterhpc/models/cluster.h>
77
#include <cloysterhpc/models/slurm.h>
88
#include <cloysterhpc/services/log.h>
9+
#include <cloysterhpc/functions.h>
910
#include <filesystem>
1011

1112
using cloyster::runCommand;

src/ofed.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <cloysterhpc/functions.h>
77
#include <cloysterhpc/ofed.h>
8+
#include <utility>
89

910
using cloyster::runCommand;
1011

@@ -24,11 +25,39 @@ gpgkey=https://linux.mellanox.com/public/repo/doca/{0}/GPG-KEY-Mellanox
2425
return data;
2526
}
2627

28+
// Return distro to match repositories at
29+
// https://linux.mellanox.com/public/repo/doca/latest/
30+
std::string headnodeDistroName()
31+
{
32+
const auto& cluster = cloyster::getClusterSingleton();
33+
switch (cluster.getHeadnode().getOS().getDistro()) {
34+
// Assuming we'll be using the last distro version
35+
case cloyster::OS::Distro::RHEL:
36+
return "rhel9.5";
37+
case cloyster::OS::Distro::OL:
38+
return "ol9.4";
39+
case cloyster::OS::Distro::Rocky:
40+
return "rockylinux9.2";
41+
case cloyster::OS::Distro::AlmaLinux:
42+
return "alinux3.2";
43+
default:
44+
std::unreachable();
45+
};
46+
47+
std::unreachable();
48+
}
49+
2750
void installMellanoxDoca(cloyster::services::repos::RepoManager& repoManager, const OFED& ofed)
2851
{
2952
auto runner = cloyster::getRunner();
53+
54+
if (runner->executeCommand("modprobe mlx5_core") == 0) {
55+
LOG_WARN("mlx5_core module loaded, skiping DOCA setup");
56+
return;
57+
}
58+
3059
// @FIMXE deduce "rockylinux9.2"
31-
auto repoData = docaRepoTemplate(ofed.getVersion(), "rockylinux9.2");
60+
auto repoData = docaRepoTemplate(ofed.getVersion(), headnodeDistroName());
3261
std::filesystem::path path = "/etc/yum.repos.d/mlx-doca.repo";
3362

3463
// Install the repository and enable it

src/services/shell.cpp

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
#include <cloysterhpc/dbus_client.h>
2626
#include <ranges>
2727

28+
using cloyster::getClusterSingleton;
2829
using cloyster::OS;
2930
using cloyster::runCommand;
31+
using cloyster::models::Cluster;
3032

3133
namespace {
3234

@@ -49,12 +51,12 @@ auto getToEnableRepoNames(const OS& osinfo)
4951
}
5052
}
5153

54+
Cluster& cluster() { return getClusterSingleton(); }
5255
}
5356

5457
namespace cloyster::services {
5558

56-
Shell::Shell(std::unique_ptr<Cluster> cluster)
57-
: m_cluster(std::move(cluster))
59+
Shell::Shell()
5860
{
5961
// Initialize directory tree
6062
cloyster::createDirectory(installPath);
@@ -79,7 +81,7 @@ void Shell::configureSELinuxMode()
7981
{
8082
LOG_INFO("Setting up SELinux")
8183

82-
switch (m_cluster->getSELinux()) {
84+
switch (cluster().getSELinux()) {
8385
case Cluster::SELinuxMode::Permissive:
8486
runCommand("setenforce 0");
8587
/* Permissive mode */
@@ -104,22 +106,22 @@ void Shell::configureFirewall()
104106
{
105107
LOG_INFO("Setting up firewall")
106108

107-
if (m_cluster->isFirewall()) {
109+
if (cluster().isFirewall()) {
108110
runCommand("systemctl enable --now firewalld");
109111

110112
// Add the management interface as trusted
111113
runCommand(fmt::format(
112114
"firewall-cmd --permanent --zone=trusted --change-interface={}",
113-
m_cluster->getHeadnode()
115+
cluster().getHeadnode()
114116
.getConnection(Network::Profile::Management)
115117
.getInterface()
116118
.value()));
117119

118120
// If we have IB, also add its interface as trusted
119-
if (m_cluster->getOFED())
121+
if (cluster().getOFED())
120122
runCommand(fmt::format(
121123
"firewall-cmd --permanent --zone=trusted --change-interface={}",
122-
m_cluster->getHeadnode()
124+
cluster().getHeadnode()
123125
.getConnection(Network::Profile::Application)
124126
.getInterface()
125127
.value()));
@@ -137,15 +139,15 @@ void Shell::configureFQDN()
137139
LOG_INFO("Setting up hostname")
138140

139141
runCommand(fmt::format(
140-
"hostnamectl set-hostname {}", m_cluster->getHeadnode().getFQDN()));
142+
"hostnamectl set-hostname {}", cluster().getHeadnode().getFQDN()));
141143
}
142144

143145
// TODO: Proper file parsing
144146
void Shell::configureHostsFile()
145147
{
146148
LOG_INFO("Setting up additional entries on hosts file")
147149

148-
const auto& headnode = m_cluster->getHeadnode();
150+
const auto& headnode = cluster().getHeadnode();
149151

150152
const auto& ip = headnode.getConnection(Network::Profile::Management)
151153
.getAddress()
@@ -165,15 +167,15 @@ void Shell::configureTimezone()
165167
LOG_INFO("Setting up timezone")
166168

167169
runCommand(fmt::format(
168-
"timedatectl set-timezone {}", m_cluster->getTimezone().getTimezone()));
170+
"timedatectl set-timezone {}", cluster().getTimezone().getTimezone()));
169171
}
170172

171173
void Shell::configureLocale()
172174
{
173175
LOG_INFO("Setting up locale")
174176

175177
runCommand(fmt::format(
176-
"localectl set-locale {}", m_cluster->getLocale().getLocale()));
178+
"localectl set-locale {}", cluster().getLocale().getLocale()));
177179
}
178180

179181
void Shell::disableNetworkManagerDNSOverride()
@@ -271,7 +273,7 @@ void Shell::configureNetworks(const std::list<Connection>& connections)
271273

272274
void Shell::runSystemUpdate()
273275
{
274-
if (m_cluster->isUpdateSystem()) {
276+
if (cluster().isUpdateSystem()) {
275277
LOG_INFO("Checking if system updates are available")
276278
runCommand("dnf -y update");
277279
}
@@ -339,7 +341,7 @@ void Shell::configureQueueSystem()
339341
{
340342
LOG_INFO("Setting up the queue system")
341343

342-
if (const auto& queue = m_cluster->getQueueSystem()) {
344+
if (const auto& queue = cluster().getQueueSystem()) {
343345
switch (queue.value()->getKind()) {
344346
case QueueSystem::Kind::None: {
345347
__builtin_unreachable();
@@ -375,14 +377,14 @@ void Shell::configureMailSystem()
375377
{
376378
LOG_INFO("Setting up the mail system");
377379

378-
m_cluster->getMailSystem()->setup();
380+
cluster().getMailSystem()->setup();
379381
}
380382

381383
void Shell::configureInfiniband()
382384
{
383-
const auto& osinfo = m_cluster->getHeadnode().getOS();
385+
const auto& osinfo = cluster().getHeadnode().getOS();
384386
auto repos = cloyster::getRepoManager(osinfo);
385-
if (const auto& ofed = m_cluster->getOFED()) {
387+
if (const auto& ofed = cluster().getOFED()) {
386388
LOG_INFO("Setting up Infiniband support")
387389
ofed->install(*repos); // shared pointer
388390
}
@@ -421,7 +423,7 @@ void Shell::installDevelopmentComponents()
421423

422424
void Shell::configureRepositories()
423425
{
424-
const auto& osinfo = m_cluster->getHeadnode().getOS();
426+
const auto& osinfo = cluster().getHeadnode().getOS();
425427
auto repos = cloyster::getRepoManager(osinfo);
426428
// 1. Install files into /etc, these files are the templates
427429
// at include/cloysterhpc/repos/el*/*.repo
@@ -437,7 +439,7 @@ void Shell::configureRepositories()
437439
*/
438440
void Shell::install()
439441
{
440-
auto systemdBus = m_cluster->getDaemonBus();
442+
auto systemdBus = cluster().getDaemonBus();
441443

442444
configureSELinuxMode();
443445
configureFirewall();
@@ -448,17 +450,17 @@ void Shell::install()
448450
configureTimezone();
449451
configureLocale();
450452

451-
configureNetworks(m_cluster->getHeadnode().getConnections());
453+
configureNetworks(cluster().getHeadnode().getConnections());
452454
runSystemUpdate();
453-
configureTimeService(m_cluster->getHeadnode().getConnections());
455+
configureTimeService(cluster().getHeadnode().getConnections());
454456
installRequiredPackages();
455457
configureRepositories();
456458
installOpenHPCBase();
457459
configureInfiniband();
458460

459461
// BUG: Broken. Compute nodes does not mount anything.
460462
NFS networkFileSystem = NFS(systemdBus, "pub", "/opt/ohpc",
461-
m_cluster->getHeadnode()
463+
cluster().getHeadnode()
462464
.getConnection(Network::Profile::Management)
463465
.getAddress(),
464466
"ro,no_subtree_check");
@@ -467,21 +469,22 @@ void Shell::install()
467469
networkFileSystem.start();
468470

469471
configureQueueSystem();
470-
if (m_cluster->getMailSystem().has_value())
472+
if (cluster().getMailSystem().has_value()) {
471473
configureMailSystem();
474+
}
472475
removeMemlockLimits();
473476

474477
installDevelopmentComponents();
475478

476479
const auto& provisionerName { magic_enum::enum_name(
477-
m_cluster->getProvisioner()) };
480+
cluster().getProvisioner()) };
478481

479482
LOG_DEBUG("Setting up the provisioner: {}", provisionerName)
480483
// std::unique_ptr<Provisioner> provisioner;
481484
std::unique_ptr<XCAT> provisioner;
482-
switch (m_cluster->getProvisioner()) {
485+
switch (cluster().getProvisioner()) {
483486
case Cluster::Provisioner::xCAT:
484-
provisioner = std::make_unique<XCAT>(m_cluster);
487+
provisioner = std::make_unique<XCAT>();
485488
break;
486489
}
487490

0 commit comments

Comments
 (0)