#include "kappa/config/eval.hpp" #include "kappa/service/types.hpp" #include namespace kappa::config { std::string resolve_field(const dsl::SystemConfig& cfg, std::string_view path) { auto dot = path.find('.'); auto ns = path.substr(0, dot); if (ns == "boot") { auto key = path.substr(dot + 1); if (key == "kernel") { return cfg.boot.kernel; } if (key == "init") { return cfg.boot.init; } if (key == "efi") { return cfg.boot.efi; } if (key == "swap") { return cfg.boot.swap; } if (key == "root") { return cfg.boot.root; } if (key == "bootloader") { return cfg.boot.bootloader; } auto it = cfg.boot.params.find(std::string(key)); if (it != cfg.boot.params.end()) { return it->second; } } if (ns == "system") { auto key = path.substr(dot + 1); if (key == "hostname") { return cfg.system.hostname; } if (key == "timezone") { return cfg.system.timezone; } } if (ns == "features") { auto key = path.substr(dot + 1); auto it = cfg.system.features.find(std::string(key)); if (it != cfg.system.features.end()) { return it->second.enabled ? "true" : "false"; } } return ""; } std::vector evaluate_assertions(const dsl::SystemConfig& cfg) { std::vector failures; for (auto& a : cfg.assertions) { auto actual = resolve_field(cfg, a.field); bool pass = false; if (a.op == "==") { pass = (actual == a.value); } else if (a.op == "!=") { pass = (actual != a.value); } if (!pass) { failures.push_back({a.message, a.field, a.value, actual}); } } return failures; } std::unordered_map resolve_services( const dsl::SystemConfig& cfg, const std::unordered_map& packages) { std::unordered_map resolved; auto init_system = cfg.boot.init; auto is = kappa::service::parse_init_system(init_system); if (is == kappa::service::InitSystem::Unknown) { std::cerr << "warning: unknown init system '" << init_system << "' — no services will be configured\n"; return {}; } for (auto& svc : cfg.services) { if (!svc.enable) { continue; } // svc.name can be "postgresql" or "postgresql.checkpointer" auto dot = svc.name.find('.'); auto pkg_name = (dot != std::string::npos) ? svc.name.substr(0, dot) : svc.name; auto svc_name = (dot != std::string::npos) ? svc.name.substr(dot + 1) : std::string("main"); auto pit = packages.find(std::string(pkg_name)); if (pit == packages.end()) { continue; } auto& pkg = pit->second; for (auto& ns : pkg.services) { if (ns.name == svc_name) { resolved[svc.name] = ns; break; } } } return resolved; } } // namespace kappa::config