From b31ac52a638976d75e7a8b34149d3b927f3fd019 Mon Sep 17 00:00:00 2001 From: Cedric CAFFY <cedric.caffy@cern.ch> Date: Thu, 5 Mar 2020 11:05:50 +0100 Subject: [PATCH] Added cta-admin virtualorganization management commands (add, ch, ls, rm) --- cmdline/CtaAdminCmd.cpp | 3 + cmdline/CtaAdminCmdParse.hpp | 13 ++- cmdline/CtaAdminTextFormatter.cpp | 27 ++++++ cmdline/CtaAdminTextFormatter.hpp | 2 + xroot_plugins/XrdCtaVirtualOrganizationLs.hpp | 92 +++++++++++++++++++ xroot_plugins/XrdSsiCtaRequestMessage.cpp | 63 ++++++++++++- xroot_plugins/XrdSsiCtaRequestMessage.hpp | 6 +- 7 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 xroot_plugins/XrdCtaVirtualOrganizationLs.hpp diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp index 017c11d0e6..39d196cee6 100644 --- a/cmdline/CtaAdminCmd.cpp +++ b/cmdline/CtaAdminCmd.cpp @@ -103,6 +103,7 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const case Data::kTflsItem: std::cout << Log::DumpProtobuf(&record.tfls_item()); break; case Data::kTplsItem: std::cout << Log::DumpProtobuf(&record.tpls_item()); break; case Data::kDslsItem: std::cout << Log::DumpProtobuf(&record.dsls_item()); break; + case Data::kVolsItem: std::cout << Log::DumpProtobuf(&record.vols_item()); break; default: throw std::runtime_error("Received invalid stream data from CTA Frontend."); } @@ -131,6 +132,7 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const case Data::kTflsItem: formattedText.print(record.tfls_item()); break; case Data::kTplsItem: formattedText.print(record.tpls_item()); break; case Data::kDslsItem: formattedText.print(record.dsls_item()); break; + case Data::kVolsItem: formattedText.print(record.vols_item()); break; default: throw std::runtime_error("Received invalid stream data from CTA Frontend."); } @@ -286,6 +288,7 @@ void CtaAdminCmd::send() const case HeaderType::TAPEFILE_LS: formattedText.printTapeFileLsHeader(); break; case HeaderType::TAPEPOOL_LS: formattedText.printTapePoolLsHeader(); break; case HeaderType::DISKSYSTEM_LS: formattedText.printDiskSystemLsHeader(); break; + case HeaderType::VIRTUALORGANIZATION_LS: formattedText.printVirtualOrganizationLsHeader(); break; case HeaderType::NONE: default: break; } diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index 00a7ea608b..a1c5ad8440 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -214,7 +214,9 @@ const cmdLookup_t cmdLookup = { { "tapepool", AdminCmd::CMD_TAPEPOOL }, { "tp", AdminCmd::CMD_TAPEPOOL }, { "disksystem", AdminCmd::CMD_DISKSYSTEM }, - { "ds", AdminCmd::CMD_DISKSYSTEM } + { "ds", AdminCmd::CMD_DISKSYSTEM }, + { "virtualorganization", AdminCmd::CMD_VIRTUALORGANIZATION }, + { "vo", AdminCmd::CMD_VIRTUALORGANIZATION } }; @@ -392,6 +394,7 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = { " If the targeted free space is reach, the queue will sleep during this amount of seconds." "\n\n" }}, + { AdminCmd::CMD_VIRTUALORGANIZATION, { "virtualorganization", "vo", { "add", "ch", "rm", "ls" } }}, }; @@ -597,6 +600,14 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { opt_targeted_free_space.optional(), opt_sleep_time.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_RM }, { opt_disksystem }}, {{ AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_LS }, { }}, + {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_ADD }, + { opt_vo, opt_comment }}, + {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_CH }, + { opt_vo, opt_comment }}, + {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_RM }, + { opt_vo }}, + {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_LS }, + { }}, }; diff --git a/cmdline/CtaAdminTextFormatter.cpp b/cmdline/CtaAdminTextFormatter.cpp index a42957cfb3..d56d1a0574 100644 --- a/cmdline/CtaAdminTextFormatter.cpp +++ b/cmdline/CtaAdminTextFormatter.cpp @@ -992,4 +992,31 @@ void TextFormatter::print(const DiskSystemLsItem &dsls_item) ); } +void TextFormatter::printVirtualOrganizationLsHeader(){ + push_back("HEADER"); + push_back( + "name", + "c.user", + "c.host", + "c.time", + "m.user", + "m.host", + "m.time", + "comment" + ); +} + +void TextFormatter::print(const VirtualOrganizationLsItem& vols_item){ + push_back( + vols_item.name(), + vols_item.creation_log().username(), + vols_item.creation_log().host(), + timeToStr(vols_item.creation_log().time()), + vols_item.last_modification_log().username(), + vols_item.last_modification_log().host(), + timeToStr(vols_item.last_modification_log().time()), + vols_item.comment() + ); +} + }} diff --git a/cmdline/CtaAdminTextFormatter.hpp b/cmdline/CtaAdminTextFormatter.hpp index 7a4192078b..1793ef1092 100644 --- a/cmdline/CtaAdminTextFormatter.hpp +++ b/cmdline/CtaAdminTextFormatter.hpp @@ -66,6 +66,7 @@ public: void printTapeFileLsHeader(); void printTapePoolLsHeader(); void printDiskSystemLsHeader(); + void printVirtualOrganizationLsHeader(); // Output records void print(const AdminLsItem &adls_item); @@ -90,6 +91,7 @@ public: void print(const TapeFileLsItem &tfls_item); void print(const TapePoolLsItem &tpls_item); void print(const DiskSystemLsItem &dsls_item); + void print(const VirtualOrganizationLsItem &vols_item); private: diff --git a/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp b/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp new file mode 100644 index 0000000000..0a1cb57a4f --- /dev/null +++ b/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp @@ -0,0 +1,92 @@ +/*! + * @project The CERN Tape Archive (CTA) + * @brief CTA TapePool Ls stream implementation + * @copyright Copyright 2019 CERN + * @license 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <xroot_plugins/XrdCtaStream.hpp> +#include <xroot_plugins/XrdSsiCtaRequestMessage.hpp> + +#include "disk/DiskSystem.hpp" + + +namespace cta { namespace xrd { + +/*! + * Stream object which implements "virtualorganization ls" command + */ +class VirtualOrganizationLsStream: public XrdCtaStream{ +public: + /*! + * Constructor + * + * @param[in] requestMsg RequestMessage containing command-line arguments + * @param[in] catalogue CTA Catalogue + * @param[in] scheduler CTA Scheduler + */ + VirtualOrganizationLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler); + +private: + /*! + * Can we close the stream? + */ + virtual bool isDone() const { + return m_virtualOrganizationList.empty(); + } + + /*! + * Fill the buffer + */ + virtual int fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf); + + std::list<cta::common::dataStructures::VirtualOrganization> m_virtualOrganizationList; //!< List of virtual organizations from the catalogue + + static constexpr const char* const LOG_SUFFIX = "VirtualOrganizationLsStream"; //!< Identifier for log messages +}; + + +VirtualOrganizationLsStream::VirtualOrganizationLsStream(const RequestMessage &requestMsg, cta::catalogue::Catalogue &catalogue, cta::Scheduler &scheduler) : + XrdCtaStream(catalogue, scheduler), + m_virtualOrganizationList(catalogue.getVirtualOrganizations()) +{ + using namespace cta::admin; + + XrdSsiPb::Log::Msg(XrdSsiPb::Log::DEBUG, LOG_SUFFIX, "VirtualOrganizationLsStream() constructor"); +} + +int VirtualOrganizationLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { + for(bool is_buffer_full = false; !m_virtualOrganizationList.empty() && !is_buffer_full; m_virtualOrganizationList.pop_front()) { + Data record; + + auto &vo = m_virtualOrganizationList.front(); + auto vo_item = record.mutable_vols_item(); + + vo_item->set_name(vo.name); + vo_item->mutable_creation_log()->set_username(vo.creationLog.username); + vo_item->mutable_creation_log()->set_host(vo.creationLog.host); + vo_item->mutable_creation_log()->set_time(vo.creationLog.time); + vo_item->mutable_last_modification_log()->set_username(vo.lastModificationLog.username); + vo_item->mutable_last_modification_log()->set_host(vo.lastModificationLog.host); + vo_item->mutable_last_modification_log()->set_time(vo.lastModificationLog.time); + vo_item->set_comment(vo.comment); + + is_buffer_full = streambuf->Push(record); + } + return streambuf->Size(); +} + +}} // namespace cta::xrd diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp index 26f631403d..5802d4db36 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp @@ -38,6 +38,7 @@ using XrdSsiPb::PbException; #include "XrdCtaStorageClassLs.hpp" #include "XrdCtaTapePoolLs.hpp" #include "XrdCtaDiskSystemLs.hpp" +#include "XrdCtaVirtualOrganizationLs.hpp" namespace cta { namespace xrd { @@ -246,8 +247,19 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons break; case cmd_pair(AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_CH): processDiskSystem_Ch(response); - break; - + break; + case cmd_pair(AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_ADD): + processVirtualOrganization_Add(response); + break; + case cmd_pair(AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_CH): + processVirtualOrganization_Ch(response); + break; + case cmd_pair(AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_RM): + processVirtualOrganization_Rm(response); + break; + case cmd_pair(AdminCmd::CMD_VIRTUALORGANIZATION,AdminCmd::SUBCMD_LS): + processVirtualOrganization_Ls(response, stream); + break; default: throw PbException("Admin command pair <" + AdminCmd_Cmd_Name(request.admincmd().cmd()) + ", " + @@ -1661,6 +1673,53 @@ void RequestMessage::processDiskSystem_Rm(cta::xrd::Response &response) response.set_type(cta::xrd::Response::RSP_SUCCESS); } +void RequestMessage::processVirtualOrganization_Add(cta::xrd::Response &response){ + using namespace cta::admin; + + const auto &name = getRequired(OptionString::VO); + const auto &comment = getRequired(OptionString::COMMENT); + + cta::common::dataStructures::VirtualOrganization vo; + vo.name = name; + vo.comment = comment; + + m_catalogue.createVirtualOrganization(m_cliIdentity,vo); + + response.set_type(cta::xrd::Response::RSP_SUCCESS); +} + +void RequestMessage::processVirtualOrganization_Ch(cta::xrd::Response &response){ + using namespace cta::admin; + + const auto &name = getRequired(OptionString::VO); + const auto &comment = getRequired(OptionString::COMMENT); + + m_catalogue.modifyVirtualOrganizationComment(m_cliIdentity,name,comment); + + response.set_type(cta::xrd::Response::RSP_SUCCESS); +} + +void RequestMessage::processVirtualOrganization_Rm(cta::xrd::Response& response) { + using namespace cta::admin; + + const auto &name = getRequired(OptionString::VO); + + m_catalogue.deleteVirtualOrganization(name); + + response.set_type(cta::xrd::Response::RSP_SUCCESS); +} + +void RequestMessage::processVirtualOrganization_Ls(cta::xrd::Response &response, XrdSsiStream * & stream){ + using namespace cta::admin; + + // Create a XrdSsi stream object to return the results + stream = new VirtualOrganizationLsStream(*this, m_catalogue, m_scheduler); + + response.set_show_header(HeaderType::VIRTUALORGANIZATION_LS); + response.set_type(cta::xrd::Response::RSP_SUCCESS); +} + + std::string RequestMessage::setDriveState(const std::string ®ex, DriveState drive_state) { using namespace cta::admin; diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp index c71640b750..ed6928bead 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp @@ -190,7 +190,10 @@ private: void processDiskSystem_Add (cta::xrd::Response &response); void processDiskSystem_Ch (cta::xrd::Response &response); void processDiskSystem_Rm (cta::xrd::Response &response); - + void processVirtualOrganization_Add(cta::xrd::Response &response); + void processVirtualOrganization_Ch(cta::xrd::Response &response); + void processVirtualOrganization_Rm(cta::xrd::Response &response); + /*! * Process AdminCmd events which can return a stream response * @@ -218,6 +221,7 @@ private: admincmdstream_t processTapeFile_Ls; admincmdstream_t processRepack_Ls; admincmdstream_t processDiskSystem_Ls; + admincmdstream_t processVirtualOrganization_Ls; /*! * Log an admin command -- GitLab