diff --git a/xroot_plugins/XrdSsiCtaServiceProvider.cpp b/xroot_plugins/XrdSsiCtaServiceProvider.cpp index 5b9025c60e12ba07efc86c4d15bf950c9137ff92..ee42e84d96901bc9fc3a552b583f27bd0b5395d3 100644 --- a/xroot_plugins/XrdSsiCtaServiceProvider.cpp +++ b/xroot_plugins/XrdSsiCtaServiceProvider.cpp @@ -101,7 +101,7 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC } else if (loggerURL.second.substr(0, 5) == "file:") { m_log.reset(new log::FileLogger(shortHostname, "cta-frontend", loggerURL.second.substr(5), loggerLevel)); } else { - throw exception::Exception(std::string("Unknown log URL: ") + loggerURL.second); + throw exception::UserError(std::string("Unknown log URL: ") + loggerURL.second); } } catch(exception::Exception &ex) { std::string ex_str("Failed to instantiate object representing CTA logging system: "); @@ -115,7 +115,7 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC const rdbms::Login catalogueLogin = rdbms::Login::parseFile("/etc/cta/cta-catalogue.conf"); auto catalogue_numberofconnections = config.getOptionValueInt("cta.catalogue.numberofconnections"); if(!catalogue_numberofconnections.first) { - throw exception::Exception("cta.catalogue.numberofconnections is not set in configuration file " + cfgFn); + throw exception::UserError("cta.catalogue.numberofconnections is not set in configuration file " + cfgFn); } const uint64_t nbArchiveFileListingConns = 2; @@ -129,7 +129,7 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC // Initialise the Backend auto objectstore_backendpath = config.getOptionValueStr("cta.objectstore.backendpath"); if(!objectstore_backendpath.first) { - throw exception::Exception("cta.objectstore.backendpath is not set in configuration file " + cfgFn); + throw exception::UserError("cta.objectstore.backendpath is not set in configuration file " + cfgFn); } m_backend = std::move(cta::objectstore::BackendFactory::createBackend(objectstore_backendpath.second, *m_log)); m_backendPopulator = cta::make_unique<cta::objectstore::BackendPopulator>(*m_backend, "Frontend", cta::log::LogContext(*m_log)); @@ -156,11 +156,12 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC } // Get the endpoint for namespace queries - auto nsEndpointConf = config.getOptionValueStr("cta.ns.endpoint"); - //m_nsEndpoint = nsEndpointConf.first ? nsEndpointConf.second : ""; - auto nsTokenConf = config.getOptionValueStr("cta.ns.token"); - //m_nsToken = nsTokenConf.first ? nsTokenConf.second : ""; - m_namespaceMap.insert(std::make_pair("endpoint", Namespace(nsEndpointConf.second, nsTokenConf.second))); + auto nsConf = config.getOptionValueStr("cta.ns.config"); + if(nsConf.first) { + setNamespaceMap(nsConf.second); + } else { + Log::Msg(XrdSsiPb::Log::WARNING, LOG_SUFFIX, "warning: 'cta.ns.config' not specified; namespace queries are disabled"); + } // Start the heartbeat thread for the agent object. The thread is guaranteed to have started before we call the unique_ptr deleter auto aht = new cta::objectstore::AgentHeartbeatThread(m_backendPopulator->getAgentReference(), *m_backend, *m_log); @@ -171,6 +172,40 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC log(log::INFO, std::string("cta-frontend started"), params); } +void XrdSsiCtaServiceProvider::setNamespaceMap(const std::string &keytab_file) +{ + // Open the keytab file for reading + std::ifstream file(keytab_file); + if(!file) { + throw cta::exception::UserError("Failed to open namespace keytab configuration file " + keytab_file); + } + + // Parse the keytab line by line + std::string line; + for(int lineno = 0; std::getline(file, line); ++lineno) { + // Strip out comments + auto pos = line.find('#'); + if(pos != std::string::npos) { + line.resize(pos); + } + + // Parse one line + std::stringstream ss(line); + std::string diskInstance; + std::string endpoint; + std::string token; + std::string eol; + ss >> diskInstance >> endpoint >> token >> eol; + + // Ignore blank lines, all other lines must have exactly 3 elements + if(token.empty() || !eol.empty()) { + if(diskInstance.empty() && endpoint.empty() && token.empty()) continue; + throw cta::exception::UserError("Could not parse namespace keytab configuration file line " + std::to_string(lineno) + ": " + line); + } + m_namespaceMap.insert(std::make_pair(diskInstance, cta::Namespace(endpoint, token))); + } +} + XrdSsiService* XrdSsiCtaServiceProvider::GetService(XrdSsiErrInfo &eInfo, const std::string &contact, int oHold) { XrdSsiPb::Log::Msg(XrdSsiPb::Log::INFO, LOG_SUFFIX, "Called GetService(", contact, ',', oHold, ')'); diff --git a/xroot_plugins/XrdSsiCtaServiceProvider.hpp b/xroot_plugins/XrdSsiCtaServiceProvider.hpp index babdd1069ea30058621d204b3c63f9b471c51e80..74acb3ce53d0e2873874bdb0a7a042b175c55c5d 100644 --- a/xroot_plugins/XrdSsiCtaServiceProvider.hpp +++ b/xroot_plugins/XrdSsiCtaServiceProvider.hpp @@ -110,6 +110,11 @@ public: */ cta::optional<std::string> getRepackBufferURL() const { return m_repackBufferURL; } + /*! + * Populate the namespace endpoint configuration from a keytab file + */ + void setNamespaceMap(const std::string &keytab_file); + /*! * Get the endpoints for namespace queries */ diff --git a/xroot_plugins/cta-frontend-xrootd.conf b/xroot_plugins/cta-frontend-xrootd.conf index b0585903132e1daad5264ec13e1823d63deca515..e047c265a661cc771fd218b82e4a5802181a59b2 100644 --- a/xroot_plugins/cta-frontend-xrootd.conf +++ b/xroot_plugins/cta-frontend-xrootd.conf @@ -14,12 +14,20 @@ cta.catalogue.numberofconnections 10 # CTA Frontend log URL cta.log.url file:/var/log/cta/cta-frontend.log -# CTA XRootD SSI/Protobuf log level +# CTA Logger log level +# Valid log levels are EMERG, ALERT, CRIT, ERR, WARNING, NOTICE (==USERERR), INFO, DEBUG +# cta.log.level DEBUG + +# CTA XRootD SSI Protobuf log level +# cta.log.ssi debug protobuf cta.log.ssi warning # CTA Repack buffer URL # cta.repack.repack_buffer_url root://ctaeos//eos/ctaeos/repack +# Keytab containing gRPC endpoints and tokens for each disk instance +cta.ns.config /etc/cta/eos.grpc.keytab + # # XRootD/SSI options #