13 #include <libssh/callbacks.h>
28 Node getNode(
const std::string& _nodeAsString)
30 std::regex noderegex(
"([^:@]+)(?::([^@]+))?@([^:@]+)(?::(\\d+))?(?:@(\\d+))?(?:#(\\d+))?");
32 if (std::regex_match(_nodeAsString, matches, noderegex)) {
33 std::string username = matches[1];
34 std::string password = matches[2];
35 std::string hostname = matches[3];
36 unsigned long port = 22;
37 unsigned long cores = 1;
38 std::size_t connections = 1;
40 if (matches[4] !=
"") port = std::stoul(matches[4]);
41 if (matches[5] !=
"") cores = std::stoul(matches[5]);
42 if (matches[6] !=
"") connections = std::stoul(matches[6]);
43 }
catch (
const std::out_of_range&) {
48 return {hostname, username, password, (
unsigned short)port, cores, connections};
50 BENCHMAX_LOG_ERROR(
"benchmax",
"Invalid format for node specification. Use the following format:");
51 BENCHMAX_LOG_ERROR(
"benchmax",
"\t<user>[:<password>]@<hostname>[:<port = 22>][@<cores = 1>][#<connections = 1>]");
57 std::lock_guard<std::mutex> lock(mMutex);
59 for (
auto& c: mConnections) {
65 std::this_thread::yield();
66 std::this_thread::sleep_for(std::chrono::milliseconds(100));
69 std::string SSHScheduler::tmpDirName(
const Tool* tool,
const fs::path& file)
const {
70 return "benchmax-" + std::to_string(
settings_core().start_time) +
"-" + std::to_string(std::size_t(tool)) +
"-" + std::to_string(std::hash<std::string>()(file.native()));
72 std::string SSHScheduler::tmpDirName(
const Tool* tool)
const {
73 return "benchmax-" + std::to_string(
settings_core().start_time) +
"-" + std::to_string(std::size_t(tool));
75 SSHScheduler::SSHScheduler(): mWorkerCount(0), mRunningJobs(0) {
76 ssh_threads_set_callbacks(ssh_threads_get_pthread());
80 for (std::size_t i = 0; i < n.connections; i++) {
81 mConnections.emplace_back(std::make_unique<SSHConnection>(n));
83 mWorkerCount += n.connections * n.cores;
87 void SSHScheduler::uploadTool(
const Tool* tool) {
88 std::lock_guard<std::mutex> lock(mMutex);
91 std::vector<std::filesystem::path> filesToUpload;
92 filesToUpload.emplace_back(tool->binary());
95 auto deps = tool->resolveDependencies();
96 for (
const auto& dep : deps) {
97 filesToUpload.emplace_back(dep);
101 std::set<std::string> nodes;
102 for (
const auto& c: mConnections) {
104 if (!nodes.insert(c->getNode().hostname).second)
continue;
105 while (!c->jobFree()) {
106 std::this_thread::sleep_for(std::chrono::milliseconds(10));
108 assert(mRemoteToolLocations.count(std::make_pair(tool, c->getNode().hostname)) == 0);
109 std::string folder = c->createTmpDir(tmpDirName(tool));
110 mRemoteToolLocations.emplace(std::make_pair(tool, c->getNode().hostname), folder);
111 for (
const auto& f : filesToUpload) {
112 c->uploadFile(f.native(), folder, f.filename().native(), S_IRWXU);
117 void SSHScheduler::cleanupTools() {
119 for (
const auto& c: mConnections) {
120 for (
auto it = mRemoteToolLocations.cbegin(); it != mRemoteToolLocations.cend(); ) {
121 if (it->first.second == c->getNode().hostname) {
122 c->removeDir(it->second);
123 it = mRemoteToolLocations.erase(it);
132 bool SSHScheduler::executeJob(
const Tool* tool,
const fs::path& file, Backend* backend) {
134 const auto& c =
get();
137 std::string folder = c->createTmpDir(tmpDirName(tool,file));
139 c->uploadFile(file, folder, file.filename().native());
142 assert(mRemoteToolLocations.find(std::make_pair(tool, c->getNode().hostname)) != mRemoteToolLocations.end());
143 std::string toolFolder = mRemoteToolLocations.at(std::make_pair(tool, c->getNode().hostname));
144 std::string cmdLine = tool->getCommandline(folder + file.filename().native(), toolFolder + tool->binary().filename().native());
146 cmdLine =
"LD_LIBRARY_PATH=. " + cmdLine;
148 if (!c->executeCommand(cmdLine,
result)) {
152 c->removeDir(folder);
154 backend->addResult(tool, file, std::move(
result));
#define BENCHMAX_LOG_DEBUG(channel, msg)
Log debug messages.
#define BENCHMAX_LOG_ERROR(channel, msg)
Log errors.
const auto & settings_ssh()
Return the SSH settings.
const auto & settings_core()
Retrieved core settings.
const auto & settings_benchmarks()
Return the benchmark settings.
std::filesystem::path remove_prefix(const std::filesystem::path &s, const std::filesystem::path &prefix)
Remove a prefix from a path.
auto get(const It &it, level)