// ---------------------------------------------------------------------- // File: ConfigParsing.cc // Author: Georgios Bitzes - CERN // ---------------------------------------------------------------------- /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2019 CERN/Switzerland * * * * This program 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. * * * * This program 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 this program. If not, see .* ************************************************************************/ #include "common/config/ConfigParsing.hh" #include "common/StringConversion.hh" #include "common/Logging.hh" #include "common/Locators.hh" EOSCOMMONNAMESPACE_BEGIN //------------------------------------------------------------------------------ //! Parse filesystem configuration into a map. We should have a dedicated //! object that represents filesystem configuration ideally, but this will //! do for now.. //! //! Returns if parsing was successful or not. //------------------------------------------------------------------------------ bool ConfigParsing::parseFilesystemConfig(const std::string& config, std::map& out) { using eos::common::StringConversion; if (config.empty()) { return false; } out.clear(); // Tokenize std::vector tokens; eos::common::StringConversion::Tokenize(config, tokens); for (size_t i = 0; i < tokens.size(); i++) { std::vector keyval; // Split based on "=" eos::common::StringConversion::Tokenize(tokens[i], keyval, "="); if (keyval.size() != 2) { eos_static_err("msg=\"failed to parse expected key=val pair\" " "input=\"%s\"", tokens[i].c_str()); continue; } std::string sval = keyval[1]; // Curl decode string literal value if (sval[0] == '"' && sval[sval.length() - 1] == '"') { std::string to_decode = sval.substr(1, sval.length() - 2); std::string decoded = StringConversion::curl_default_unescaped(to_decode); if (!decoded.empty()) { keyval[1] = '"'; keyval[1] += decoded; keyval[1] += '"'; } } out[keyval[0]] = keyval[1]; } if ((!out.count("queuepath")) || (!out.count("queue")) || (!out.count("id"))) { eos_static_err("%s", "msg=\"could not parse configuration entry: %s\"", config.c_str()); return false; } // All clear, configuration is valid return true; } //------------------------------------------------------------------------------ // Relocate a filesystem to a different FST //------------------------------------------------------------------------------ Status ConfigParsing::relocateFilesystem(const std::string& newFstHost, int newFstPort, std::map& configEntry) { eos::common::FileSystemLocator locator; if (!common::FileSystemLocator::fromQueuePath(configEntry["queuepath"], locator)) { return Status(EINVAL, SSTR("could not parse queuepath: " << configEntry["queuepath"])); } locator = eos::common::FileSystemLocator(newFstHost, newFstPort, locator.getStoragePath()); configEntry["host"] = newFstHost; configEntry["port"] = SSTR(newFstPort); configEntry["hostport"] = SSTR(newFstHost << ":" << newFstPort); configEntry["queue"] = locator.getFSTQueue(); configEntry["queuepath"] = locator.getQueuePath(); return Status(); } //------------------------------------------------------------------------------ // Parse configuration file // // Returns if parsing was successful or not. //------------------------------------------------------------------------------ bool ConfigParsing::parseConfigurationFile(const std::string& contents, std::map& out, std::string& err) { int line_num = 0; std::string s; std::istringstream streamconfig(contents); out.clear(); while ((getline(streamconfig, s, '\n'))) { line_num++; if (s.length()) { XrdOucString key = s.c_str(); int seppos = key.find(" => "); if (seppos == STR_NPOS) { err = SSTR("parsing error in configuration file line " << line_num << ":" << s.c_str()); return false; } XrdOucString value; value.assign(key, seppos + 4); key.erase(seppos); // Add entry only if key and value are not empty if (key.length() && value.length()) { eos_static_notice("setting config key=%s value=%s", key.c_str(), value.c_str()); out[key.c_str()] = value.c_str(); } else { eos_static_notice("skipping empty config key=%s value=%s", key.c_str(), value.c_str()); } } } return true; } EOSCOMMONNAMESPACE_END