//------------------------------------------------------------------------------ // @file: com_proto_config.cc // @author: Fabio Luchetti - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2018 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 token) 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 "console/commands/ICmdHelper.hh" #include "common/StringTokenizer.hh" #include "console/ConsoleMain.hh" extern int com_config(char*); void com_config_help(); //------------------------------------------------------------------------------ //! Class ConfigHelper //------------------------------------------------------------------------------ class ConfigHelper : public ICmdHelper { public: //---------------------------------------------------------------------------- //! Constructor //! //! @param opts global options //---------------------------------------------------------------------------- ConfigHelper(const GlobalOptions& opts): ICmdHelper(opts) {} //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- ~ConfigHelper() override = default; //---------------------------------------------------------------------------- //! Parse command line input //! //! @param arg input //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool ParseCommand(const char* arg) override; }; //------------------------------------------------------------------------------ // Parse command line input //------------------------------------------------------------------------------ bool ConfigHelper::ParseCommand(const char* arg) { eos::console::ConfigProto* config = mReq.mutable_config(); eos::common::StringTokenizer tokenizer(arg); tokenizer.GetLine(); std::string token; if (!tokenizer.NextToken(token)) { return false; } if (token == "ls") { eos::console::ConfigProto_LsProto* ls = config->mutable_ls(); if (tokenizer.NextToken(token)) { if (token == "--backup" || token == "-b") { ls->set_showbackup(true); } else { return false; } } } else if (token == "dump") { eos::console::ConfigProto_DumpProto* dump = config->mutable_dump(); if (tokenizer.NextToken(token)) { dump->set_file(token); } } else if (token == "reset") { if (tokenizer.NextToken(token)) { return false; // no need for more arguments } config->set_reset(true); } else if (token == "export") { if (!tokenizer.NextToken(token)) { return false; } eos::console::ConfigProto_ExportProto* exp = config->mutable_exp(); // either " or -f if (token.find('-') != 0) { // does not begins with '-' exp->set_file(token); if (tokenizer.NextToken(token)) { if (token == "-f") { exp->set_force(true); } else { return false; } } } else { return false; } } else if (token == "save") { if (!tokenizer.NextToken(token)) { return false; } eos::console::ConfigProto_SaveProto* save = config->mutable_save(); if (token.find('-') != 0) { save->set_file(token); } else { return false; } while (tokenizer.NextToken(token)) { if (token == "-c" || token == "--comment") { // put the comment in the mReq object std::string sline = arg; if (token == "-c") { // have to replace "-c" with "--comment" in sline size_t pos = sline.find("-c"); sline.replace(pos, std::string("-c").length(), "--comment"); parse_comment(sline.c_str(), token); } else if (token == "--comment") { parse_comment(sline.c_str(), token); } mReq.set_comment(token); tokenizer.NextToken(token); // skip comment text } else if (token == "-f") { save->set_force(true); } else { return false; } } } else if (token == "load") { if (!tokenizer.NextToken(token)) { return false; } eos::console::ConfigProto_LoadProto* load = config->mutable_load(); load->set_file(token); } else if (token == "changelog") { eos::console::ConfigProto_ChangelogProto* changelog = config->mutable_changelog(); if (tokenizer.NextToken(token)) { if (token.find('-') == 0) { token.erase(0); // remove first char to allow both -100 and 100 } try { changelog->set_lines(std::stoi(token)); } catch (const std::exception& e) { std::cerr << "error: argument needs to be numeric" << std::endl; return false; } } else { changelog->set_lines(10); } } else { // no proper subcommand return false; } return true; } //------------------------------------------------------------------------------ // Config command entry point //------------------------------------------------------------------------------ int com_protoconfig(char* arg) { if (wants_help(arg)) { com_config_help(); global_retc = EINVAL; return EINVAL; } ConfigHelper config(gGlobalOpts); if (!config.ParseCommand(arg)) { com_config_help(); global_retc = EINVAL; return EINVAL; } global_retc = config.Execute(); return global_retc; } //------------------------------------------------------------------------------ // Print help message //------------------------------------------------------------------------------ void com_config_help() { std::ostringstream oss; oss << " usage:\n" << "config changelog|dump|export|load|ls|reset|save [OPTIONS]\n" << "'[eos] config' provides the configuration interface to EOS.\n" << std::endl << "Subcommands:\n" << "config changelog [#lines] : show the last #lines from the changelog - default is 10\n" << std::endl << "config dump [] : dump configuration with name or current one by default\n" << std::endl << "config export [-f] : export a configuration stored on file to QuarkDB (you need to specify the full path!)\n" << "\t -f : overwrite existing config name and create a timestamped backup\n" << std::endl << "config load : load config\n" << std::endl << "config ls [-b|--backup] : list existing configurations\n" << "\t -b : show also backup & autosave files\n" << std::endl << "config reset : reset all configuration to empty state\n" << std::endl << "config save [-f] [-c|--comment \"\"] : save config under \n" << "\t -f : overwrite existing config name and create a timestamped backup\n" << "\t -c : add a comment entry to the config\n"; std::cerr << oss.str() << std::endl; }