From 54ac042a19faf80f572a9fb5488aa5df7571a920 Mon Sep 17 00:00:00 2001 From: Lasse Tjernaes Wardenaer <lasse.tjernaes.wardenaer@cern.ch> Date: Tue, 25 Oct 2022 08:33:26 +0200 Subject: [PATCH] Resolve "Configurable configuration folder for cta command line tools" --- ReleaseNotes.md | 2 ++ cmdline/CMakeLists.txt | 2 +- cmdline/CtaAdminCmd.cpp | 26 +++++++++++++++++++++----- cmdline/CtaAdminCmd.hpp | 5 +++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 151e6ee771..8d609a97e0 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,4 +1,6 @@ # v4.NEXT +### Features +- cta/CTA#16 - Add option for a user config file ## Summary ### Features diff --git a/cmdline/CMakeLists.txt b/cmdline/CMakeLists.txt index 66d988f3b6..2aa5a2f841 100644 --- a/cmdline/CMakeLists.txt +++ b/cmdline/CMakeLists.txt @@ -33,7 +33,7 @@ include_directories(${CMAKE_BINARY_DIR}/eos_cta ${PROTOBUF3_INCLUDE_DIRS}) # cta-admin <admin_command> is the SSI version of "cta <admin_command>" # add_executable(cta-admin CtaAdminCmd.cpp CtaAdminCmdParse.cpp CtaAdminTextFormatter.cpp) -target_link_libraries(cta-admin XrdSsiPbEosCta XrdSsiLib XrdUtils ctacommon) +target_link_libraries(cta-admin XrdSsiPbEosCta XrdSsiLib XrdUtils ctacommon stdc++fs) set_property (TARGET cta-admin APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH}) # diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp index fca4cdf396..0c01ca0c19 100644 --- a/cmdline/CtaAdminCmd.cpp +++ b/cmdline/CtaAdminCmd.cpp @@ -15,6 +15,7 @@ * submit itself to any jurisdiction. */ +#include <filesystem> #include <sstream> #include <iostream> @@ -33,9 +34,10 @@ std::atomic<bool> isHeaderSent(false); // initialise an output buffer of 1000 lines cta::admin::TextFormatter formattedText(1000); - +const std::filesystem::path DEFAULT_CLI_CONFIG = "/etc/cta/cta-cli.conf"; std::string tp_config_file = "/etc/cta/TPCONFIG"; + namespace XrdSsiPb { /*! @@ -184,6 +186,8 @@ CtaAdminCmd::CtaAdminCmd(int argc, const char *const *const argv) : if(std::string(argv[argno]) == "--json") { is_json = true; ++argno; } + if(std::string(argv[argno]) == "--config") { m_config = argv[++argno]; ++argno; } + // Commands, subcommands and server-side options if(argc <= argno || (cmd_it = cmdLookup.find(argv[argno++])) == cmdLookup.end()) { @@ -226,7 +230,18 @@ CtaAdminCmd::CtaAdminCmd(int argc, const char *const *const argv) : parseOptions(has_subcommand ? argno+1 : argno, argc, argv, option_list_it->second); } - +const std::string CtaAdminCmd::getConfigFilePath() const { + std::filesystem::path config_file = DEFAULT_CLI_CONFIG; + + const std::filesystem::path home = std::getenv("HOME"); + const std::filesystem::path home_dir_config_file = home / ".cta/cta-cli.conf"; + if(std::filesystem::exists(home_dir_config_file)) { config_file = home_dir_config_file; } + + if(m_config) { + config_file = m_config.value(); + } + return config_file; +} void CtaAdminCmd::send() const { @@ -237,8 +252,9 @@ void CtaAdminCmd::send() const throwUsage(ex.what()); } + const std::filesystem::path config_file = getConfigFilePath(); + // Set configuration options - const std::string config_file = "/etc/cta/cta-cli.conf"; XrdSsiPb::Config config(config_file, "cta"); config.set("resource", "/ctafrontend"); config.set("response_bufsize", StreamBufferSize); // default value = 1024 bytes @@ -256,7 +272,7 @@ void CtaAdminCmd::send() const // Validate that endpoint was specified in the config file if(!config.getOptionValueStr("endpoint").first) { - throw std::runtime_error("Configuration error: cta.endpoint missing from " + config_file); + throw std::runtime_error("Configuration error: cta.endpoint missing from " + config_file.string()); } // If the server is down, we want an immediate failure. Set client retry to a single attempt. @@ -504,7 +520,7 @@ void CtaAdminCmd::throwUsage(const std::string &error_txt) const { // Command has not been set: show generic help help << "CTA Administration Tool" << std::endl << std::endl - << "Usage: " << m_execname << " [--json] <command> [<subcommand> [<option>...]]" << std::endl + << "Usage: " << m_execname << " [--json] [--config <configpath>] <command> [<subcommand> [<option>...]]" << std::endl << " " << m_execname << " <command> help" << std::endl << std::endl << "By default, the output is in tabular format. If the --json option is supplied, the output is a JSON array." << std::endl << "Commands have a long and short version. Subcommands (add/ch/ls/rm/etc.) do not have short versions. For" << std::endl diff --git a/cmdline/CtaAdminCmd.hpp b/cmdline/CtaAdminCmd.hpp index f083a9b9fd..d741448862 100644 --- a/cmdline/CtaAdminCmd.hpp +++ b/cmdline/CtaAdminCmd.hpp @@ -61,6 +61,9 @@ private: //! Return the request timeout value (to pass to the ServiceClientSide constructor) int GetRequestTimeout() const; + //! Returns user config path if specified, if not looks in $HOME/.cta, then in /etc/cta + const std::string getConfigFilePath() const; + // Member variables const std::string StreamBufferSize = "1024"; //!< Buffer size for Data/Stream Responses @@ -77,6 +80,8 @@ private: static std::atomic<bool> is_json; //!< Display results in JSON format static std::atomic<bool> is_first_record; //!< Delimiter for JSON records + std::optional<std::string> m_config; //!< User defined config file + static constexpr const char* const LOG_SUFFIX = "CtaAdminCmd"; //!< Identifier for log messages }; -- GitLab