From f260b7813c33fc849cef2336cc4a5a682fc74b6d Mon Sep 17 00:00:00 2001 From: Oliver Giles Date: Sat, 19 Sep 2015 14:36:03 +0200 Subject: [PATCH] remove iniparser, laminar.conf must be sourced --- CMakeLists.txt | 4 ++-- src/conf.cpp | 39 +++++++++++++++++++++++++++++++++++++ src/conf.h | 44 ++++++++++++++++++++++++++++++++++++++++++ src/laminar.cpp | 51 ++++++++++++++++++++----------------------------- src/laminar.h | 4 +--- src/main.cpp | 6 +----- 6 files changed, 108 insertions(+), 40 deletions(-) create mode 100644 src/conf.cpp create mode 100644 src/conf.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a30a07d..c5826ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,9 +81,9 @@ generate_compressed_bins(${CMAKE_BINARY_DIR} js/angular.min.js js/angular-route. ## Server add_executable(laminard src/database.cpp src/main.cpp src/server.cpp src/laminar.cpp - src/resources.cpp src/run.cpp src/node.cpp laminar.capnp.c++ ${COMPRESSED_BINS}) + src/conf.cpp src/resources.cpp src/run.cpp src/node.cpp laminar.capnp.c++ ${COMPRESSED_BINS}) # TODO: some alternative to boost::filesystem? -target_link_libraries(laminard capnp capnp-rpc kj-async kj boost_filesystem boost_system sqlite3 iniparser) +target_link_libraries(laminard capnp capnp-rpc kj-async kj boost_filesystem boost_system sqlite3) ## Client add_executable(laminarc src/client.cpp laminar.capnp.c++) diff --git a/src/conf.cpp b/src/conf.cpp new file mode 100644 index 0000000..4fa58ad --- /dev/null +++ b/src/conf.cpp @@ -0,0 +1,39 @@ +/// +/// Copyright 2015 Oliver Giles +/// +/// This file is part of Laminar +/// +/// Laminar is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// Laminar is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with Laminar. If not, see +/// +#include "conf.h" + +#include + +template <> +int StringMap::convert(std::string e) { return atoi(e.c_str()); } + +StringMap parseConfFile(const char* path) { + StringMap result; + std::fstream f(path); + std::string line; + while(std::getline(f, line)) { + if(line[0] == '#') + continue; + int p = line.find('='); + if(p > 0) { + result.emplace(line.substr(0, p), line.substr(p+1)); + } + } + return result; +} diff --git a/src/conf.h b/src/conf.h new file mode 100644 index 0000000..152a908 --- /dev/null +++ b/src/conf.h @@ -0,0 +1,44 @@ +/// +/// Copyright 2015 Oliver Giles +/// +/// This file is part of Laminar +/// +/// Laminar is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// Laminar is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with Laminar. If not, see +/// +#ifndef _LAMINAR_CONF_H_ +#define _LAMINAR_CONF_H_ + +#include + +class StringMap : public std::unordered_map { +public: + template + T get(std::string key, T fallback = T()) { + auto it = find(key); + return it != end() ? convert(it->second) : fallback; + } +private: + template + T convert(std::string e) { return e; } +}; +template <> +int StringMap::convert(std::string e); + +// Reads a file by line into a list of key/value pairs +// separated by the first '=' character. Discards lines +// beginning with '#' +StringMap parseConfFile(const char* path); + + +#endif // _LAMINAR_CONF_H_ diff --git a/src/laminar.cpp b/src/laminar.cpp index 9cf1fc9..0860afe 100644 --- a/src/laminar.cpp +++ b/src/laminar.cpp @@ -18,9 +18,9 @@ /// #include "laminar.h" #include "server.h" +#include "conf.h" #include -#include #include #include @@ -61,11 +61,8 @@ constexpr const char* BASE_CFG_DIR = "/home/og/dev/laminar/cfg"; typedef std::string str; -Laminar::Laminar(const char* configFile) { - // read params from config file - conf = iniparser_load(configFile); - KJ_REQUIRE(conf != nullptr, "Could not parse", configFile); - homeDir = iniparser_getstring(conf, ":LAMINAR_HOME", "/var/lib/laminar"); +Laminar::Laminar() { + homeDir = getenv("LAMINAR_HOME") ?: "/var/lib/laminar"; db = new Database((fs::path(homeDir)/"laminar.sqlite").string().c_str()); // Prepare database for first use @@ -253,14 +250,13 @@ void Laminar::sendStatus(LaminarClient* client) { } Laminar::~Laminar() { - iniparser_freedict(conf); delete db; delete srv; } void Laminar::run() { - const char* listen_rpc = iniparser_getstring(conf, ":LAMINAR_BIND_RPC", INTADDR_RPC_DEFAULT); - const char* listen_http = iniparser_getstring(conf, ":LAMINAR_BIND_HTTP", INTADDR_HTTP_DEFAULT); + const char* listen_rpc = getenv("LAMINAR_BIND_RPC") ?: INTADDR_RPC_DEFAULT; + const char* listen_http = getenv("LAMINAR_BIND_HTTP") ?: INTADDR_HTTP_DEFAULT; srv = new Server(*this, listen_rpc, listen_http); @@ -275,30 +271,25 @@ void Laminar::stop() { bool Laminar::loadConfiguration() { NodeMap nm; - fs::directory_iterator dit(fs::path(homeDir)/"cfg"/"nodes"); - for(fs::directory_entry& it : dit) { - if(!fs::is_directory(it.status())) - continue; + fs::path nodeCfg = fs::path(homeDir)/"cfg"/"nodes"; - fs::directory_entry config(it.path()/"config"); - if(!fs::is_regular_file(config.status())) - continue; + if(fs::is_directory(nodeCfg)) { + fs::directory_iterator dit(nodeCfg); + for(fs::directory_entry& it : dit) { + if(!fs::is_directory(it.status())) + continue; - dictionary* ini = iniparser_load(config.path().string().c_str()); - if(!ini) { - KJ_LOG(ERROR, "Could not parse node config", config.path().string()); - continue; + fs::directory_entry config(it.path()/"config"); + if(!fs::is_regular_file(config.status())) + continue; + + StringMap conf = parseConfFile(config.path().string().c_str()); + + Node node; + node.name = it.path().filename().string(); + node.numExecutors = conf.get("EXECUTORS", 6); + nm.emplace(node.name, std::move(node)); } - - int executors = iniparser_getint(ini, ":EXECUTORS", 6); - - Node node; - node.name = it.path().filename().string(); - node.numExecutors = executors; - nm.emplace(node.name, std::move(node)); - - iniparser_freedict(ini); - } if(nm.empty()) { diff --git a/src/laminar.h b/src/laminar.h index a0e175b..28dc9fa 100644 --- a/src/laminar.h +++ b/src/laminar.h @@ -30,7 +30,6 @@ typedef std::unordered_map NodeMap; struct Server; -struct _dictionary_; // from iniparser // The main class implementing the application's business logic. // It owns a Server to manage the HTTP/websocket and Cap'n Proto RPC @@ -38,7 +37,7 @@ struct _dictionary_; // from iniparser // the LaminarClient objects (see interface.h) class Laminar : public LaminarInterface { public: - Laminar(const char* configFile); + Laminar(); ~Laminar(); // Runs the application forever @@ -81,7 +80,6 @@ private: RunSet activeJobs; Database* db; Server* srv; - _dictionary_* conf; NodeMap nodes; std::string homeDir; std::set clients; diff --git a/src/main.cpp b/src/main.cpp index 0d0e427..b42385f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,12 +31,8 @@ int main(int argc, char** argv) { } } - const char* configFile = getenv("LAMINAR_CONF_FILE"); - if(!configFile || !*configFile) - configFile = "/etc/laminar.conf"; - do { - Laminar laminar(configFile); + Laminar laminar; sigHandler = [&](){ KJ_LOG(INFO, "Received SIGINT"); laminar.stop();