Update to the new config format
continuous-integration/drone/push Build is passing Details

pull/4/head
Clément FRÉVILLE 2 years ago
parent 34335045ca
commit 3f4588f44a

@ -15,7 +15,7 @@ FetchContent_MakeAvailable(tomlplusplus)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config)
find_package(ZeroMQ QUIET) find_package(ZeroMQ QUIET)
add_executable(planificador src/host.cpp src/runner.cpp src/network.cpp src/config.cpp src/main.cpp) add_executable(planificador src/runner.cpp src/network.cpp src/config.cpp src/main.cpp)
if (NOT ZeroMQ_FOUND) if (NOT ZeroMQ_FOUND)
message(STATUS "ZeroMQ not found, using bundled version") message(STATUS "ZeroMQ not found, using bundled version")
FetchContent_Declare( FetchContent_Declare(

@ -0,0 +1,6 @@
planificador
===========
A sandbox execution environment for untrusted code. It acts as a front-end in front of Docker+Bubblewrap.
Tasks are submitted using a ZeroMQ message queue, allowing quick scaling of the system.

@ -1,12 +0,0 @@
[serveurs]
[serveurs.serveur1]
ip = '100.000.000.000'
nbContainerMax = 10
[serveurs.serveur2]
ip = '200.000.000.000'
nbContainerMax = 20
[serveurs.serveur3]
ip = '300.000.000.000'
nbContainerMax = 30

@ -0,0 +1,7 @@
[queue]
pull = "tcp://localhost:5557"
push = "tcp://localhost:5558"
threads = 1
[runner]
timeout = 2

@ -1,29 +1,33 @@
#include "config.hpp" #include "config.hpp"
std::vector<sk::host> sk::config::loadHostsFromToml(const fs::path &confFile) { #include <iostream>
std::vector<sk::host> hosts; #include <toml++/toml.h>
auto config = toml::parse_file(confFile.string()); static sk::config read(const toml::table &config) {
toml::table *serverSection = config.get_as<toml::table>("serveurs"); return sk::config{
if (serverSection == nullptr) { sk::queue_config{
return hosts; config["queue"]["pull"].value_or("tcp://localhost:5557"),
} config["queue"]["push"].value_or("tcp://localhost:5558"),
config["queue"]["threads"].value_or(1u),
// Parcourir les serveurs },
for (const auto &[serverNameKey, serverInfoValue] : *serverSection) { sk::runner_config{
std::string serverName{serverNameKey}; config["runner"]["timeout"].value_or(2u),
toml::table *serverInfoPtr = serverInfoValue.as_table(); },
if (serverInfoPtr == nullptr) { };
} }
toml::table &serverInfo = *serverInfoPtr;
if (serverInfo.get_as<std::string>("ip") && serverInfo.get_as<int64_t>("nbContainerMax")) {
std::string serverIp = serverInfo.get_as<std::string>("ip")->get();
int serverMaxContainers = serverInfo.get_as<int64_t>("nbContainerMax")->get();
hosts.push_back(sk::host(serverIp, serverMaxContainers)); sk::config sk::config::read_or_default(const std::filesystem::path &path, bool expect_present) {
std::ifstream t(path);
if (!t) {
if (errno == ENOENT && !expect_present) {
std::cout << "Using default config\n";
} else {
std::cerr << "Failed to open config file " << path << ": " << strerror(errno) << "\n";
} }
return read(toml::table{});
} }
std::stringstream buffer;
return hosts; buffer << t.rdbuf();
auto config = toml::parse(buffer.str(), path);
return read(config);
} }

@ -1,15 +1,23 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
#include <toml++/toml.h> #include <string>
#include <vector>
#include "host.hpp"
namespace fs = std::filesystem;
namespace sk { namespace sk {
class config { struct queue_config {
public: std::string pull_addr;
static std::vector<sk::host> loadHostsFromToml(const fs::path &confFile); std::string push_addr;
unsigned int nb_threads;
};
struct runner_config {
unsigned int timeout;
};
struct config {
queue_config queue;
runner_config runner;
static config read_or_default(const std::filesystem::path &path, bool expect_present = false);
}; };
} }

@ -1,16 +0,0 @@
#include "host.hpp"
namespace sk {
host::host(const std::string &ip, unsigned int connectionsMax) : ip{ip}, connections{0}, connectionsMax{connectionsMax}, runners{} {}
void host::addConnection(sk::runner &runner) {
runners.push(&runner);
connections += 1;
}
const std::string &host::getIp() const { return ip; }
unsigned int host::getNbConnections() const { return connections; }
unsigned int host::getNbConnectionsMax() const { return connectionsMax; }
}

@ -1,27 +0,0 @@
#pragma once
#include "runner.hpp"
#include <queue>
#include <string>
namespace sk {
class host {
std::string ip;
unsigned int connections;
unsigned int connectionsMax;
std::queue<sk::runner *> runners;
public:
host(const std::string &ip, unsigned int connectionsMax);
void addConnection(sk::runner &runner);
const std::string &getIp() const;
unsigned int getNbConnections() const;
unsigned int getNbConnectionsMax() const;
bool operator<(const host &other) const { return (connectionsMax - connections) < other.getNbConnectionsMax() - other.getNbConnections(); }
};
}

@ -9,6 +9,7 @@
#include <unistd.h> #include <unistd.h>
#include <wait.h> #include <wait.h>
#include "config.hpp"
#include "zmq_addon.hpp" #include "zmq_addon.hpp"
static constexpr uint32_t JOB_ID_LEN = 32; static constexpr uint32_t JOB_ID_LEN = 32;
@ -34,12 +35,18 @@ sk::runner *global_runner = nullptr;
int main(int argc, char **argv) { int main(int argc, char **argv) {
int opt; int opt;
std::optional<sk::runner_backend> selected_backend; std::optional<sk::runner_backend> selected_backend;
while ((opt = getopt(argc, argv, "bc")) != -1) { std::filesystem::path config_path("config.toml");
bool may_use_default_config = true;
while ((opt = getopt(argc, argv, "bc:d")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
selected_backend = sk::runner_backend::BubbleWrap; selected_backend = sk::runner_backend::BubbleWrap;
break; break;
case 'c': case 'c':
config_path = optarg;
may_use_default_config = false;
break;
case 'd':
selected_backend = sk::runner_backend::Docker; selected_backend = sk::runner_backend::Docker;
break; break;
default: default:
@ -48,7 +55,8 @@ int main(int argc, char **argv) {
} }
} }
sk::runner runner(selected_backend.has_value() ? selected_backend.value() : detect_backend()); sk::config config = sk::config::read_or_default(config_path, !may_use_default_config);
sk::runner runner(selected_backend.has_value() ? selected_backend.value() : detect_backend(), config.runner);
global_runner = &runner; global_runner = &runner;
struct sigaction action {}; struct sigaction action {};
action.sa_handler = [](int) { action.sa_handler = [](int) {
@ -76,11 +84,11 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
zmq::context_t context(1); zmq::context_t context(static_cast<int>(config.queue.nb_threads));
zmq::socket_t receiver(context, zmq::socket_type::pull); zmq::socket_t receiver(context, zmq::socket_type::pull);
receiver.connect("tcp://localhost:5557"); receiver.connect(config.queue.pull_addr);
zmq::socket_t sender(context, zmq::socket_type::push); zmq::socket_t sender(context, zmq::socket_type::push);
sender.connect("tcp://localhost:5558"); sender.connect(config.queue.push_addr);
while (true) { while (true) {
zmq::message_t request; zmq::message_t request;

@ -11,8 +11,6 @@
#include <unistd.h> #include <unistd.h>
#include <wait.h> #include <wait.h>
static constexpr int TIMEOUT_SECONDS = 2;
// Define a helper to throw a system error if a syscall fails // Define a helper to throw a system error if a syscall fails
static auto ensure = [](int res) -> void { static auto ensure = [](int res) -> void {
if (res == -1) { if (res == -1) {
@ -21,7 +19,7 @@ static auto ensure = [](int res) -> void {
}; };
namespace sk { namespace sk {
runner::runner(runner_backend backend) : backend{backend} {} runner::runner(runner_backend backend, const runner_config &config) : backend{backend}, timeout{static_cast<int>(config.timeout)} {}
run_result runner::run_blocking(const program &program) { run_result runner::run_blocking(const program &program) {
// Open file descriptors ahead of time // Open file descriptors ahead of time
@ -38,7 +36,7 @@ run_result runner::run_blocking(const program &program) {
throw std::system_error{errno, std::generic_category()}; throw std::system_error{errno, std::generic_category()};
} }
itimerspec timer{}; itimerspec timer{};
timer.it_value.tv_sec = TIMEOUT_SECONDS; timer.it_value.tv_sec = timeout;
if (timerfd_settime(timerfd, 0, &timer, nullptr) == -1) { if (timerfd_settime(timerfd, 0, &timer, nullptr) == -1) {
throw std::system_error{errno, std::generic_category()}; throw std::system_error{errno, std::generic_category()};
} }

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "config.hpp"
#include "program.hpp" #include "program.hpp"
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -21,11 +22,12 @@ enum class runner_backend { BubbleWrap, Docker };
class runner { class runner {
runner_backend backend; runner_backend backend;
int timeout;
std::vector<active_job> active_jobs; std::vector<active_job> active_jobs;
std::mutex active_jobs_mutex; std::mutex active_jobs_mutex;
public: public:
explicit runner(runner_backend backend); runner(runner_backend backend, const runner_config &config);
run_result run_blocking(const program &program); run_result run_blocking(const program &program);
void exit_active_jobs(); void exit_active_jobs();

Loading…
Cancel
Save