/* * Copyright (C) 2015 ScyllaDB * */ /* * This file is part of Scylla. * * Scylla is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scylla 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 Scylla. If not, see . */ #include #include #include #include #include #include #include #include "config.hh" #include "log.hh" #include "utils/config_file_impl.hh" namespace YAML { // yaml-cpp conversion would do well to have some enable_if-stuff to make it possible // to do more broad spectrum converters. template<> struct convert { static bool decode(const Node& node, seastar::log_level& rhs) { std::string tmp; if (!convert::decode(node, tmp)) { return false; } rhs = boost::lexical_cast(tmp); return true; } }; template<> struct convert { static bool decode(const Node& node, db::config::seed_provider_type& rhs) { if (!node.IsSequence()) { return false; } rhs = db::config::seed_provider_type(); for (auto& n : node) { if (!n.IsMap()) { continue; } for (auto& n2 : n) { if (n2.first.as() == "class_name") { rhs.class_name = n2.second.as(); } if (n2.first.as() == "parameters") { auto v = n2.second.as>(); if (!v.empty()) { rhs.parameters = v.front(); } } } } return true; } }; } #define _mk_name(name, ...) name, #define str(x) #x #define _mk_init(name, type, deflt, status, desc, ...) , name(str(name), type(deflt), desc) db::config::config() : utils::config_file({ _make_config_values(_mk_name) default_log_level, logger_log_level, log_to_stdout, log_to_syslog }) _make_config_values(_mk_init) , default_log_level("default_log_level") , logger_log_level("logger_log_level") , log_to_stdout("log_to_stdout") , log_to_syslog("log_to_syslog") {} namespace utils { template<> void config_file::named_value::add_command_line_option( boost::program_options::options_description_easy_init& init, const stdx::string_view& name, const stdx::string_view& desc) { init((hyphenate(name) + "-class-name").data(), value_ex(&_value.class_name)->notifier( [this](auto&&) {_source = config_source::CommandLine;}), desc.data()); init((hyphenate(name) + "-parameters").data(), value_ex(&_value.parameters)->notifier( [this](auto&&) {_source = config_source::CommandLine;}), desc.data()); } } boost::program_options::options_description_easy_init& db::config::add_options(boost::program_options::options_description_easy_init& init) { config_file::add_options(init); data_file_directories.add_command_line_option(init, "datadir", "alias for 'data-file-directories'"); rpc_port.add_command_line_option(init, "thrift-port", "alias for 'rpc-port'"); native_transport_port.add_command_line_option(init, "cql-port", "alias for 'native-transport-port'"); return init; } boost::filesystem::path db::config::get_conf_dir() { using namespace boost::filesystem; path confdir; auto* cd = std::getenv("SCYLLA_CONF"); if (cd != nullptr) { confdir = path(cd); } else { auto* p = std::getenv("SCYLLA_HOME"); if (p != nullptr) { confdir = path(p); } confdir /= "conf"; } return confdir; } void db::config::check_experimental(const sstring& what) const { if (!experimental()) { throw std::runtime_error(sprint("%s is currently disabled. Start Scylla with --experimental=on to enable.", what)); } } namespace bpo = boost::program_options; logging::settings db::config::logging_settings(const bpo::variables_map& map) const { struct convert { std::unordered_map operator()(const seastar::program_options::string_map& map) const { std::unordered_map res; for (auto& p : map) { res.emplace(p.first, (*this)(p.second)); }; return res; } seastar::log_level operator()(const sstring& s) const { return boost::lexical_cast(s); } bool operator()(bool b) const { return b; } }; auto value = [&map](auto v, auto dummy) { auto name = utils::hyphenate(v.name()); const bpo::variable_value& opt = map[name]; if (opt.defaulted() && v.is_set()) { return v(); } using expected = std::decay_t; return convert()(opt.as()); }; return logging::settings{ value(logger_log_level, seastar::program_options::string_map()) , value(default_log_level, sstring()) , value(log_to_stdout, bool()) , value(log_to_syslog, bool()) }; }