Skip to content
Snippets Groups Projects
Commit e1979acf authored by Michael Davis's avatar Michael Davis
Browse files

Merge branch 'cta_admin_stream_all'

parents 2f26a018 271211a4
No related branches found
No related tags found
No related merge requests found
...@@ -27,9 +27,14 @@ ...@@ -27,9 +27,14 @@
#include <cmdline/CtaAdminTextFormatter.hpp> #include <cmdline/CtaAdminTextFormatter.hpp>
// global synchronisation flag between main thread and stream handler thread // GLOBAL VARIABLES : used to pass information between main thread and stream handler thread
// global synchronisation flag
std::atomic<bool> isHeaderSent(false); std::atomic<bool> isHeaderSent(false);
// initialise an output buffer of 1000 lines
cta::admin::TextFormatter formattedText(1000);
namespace XrdSsiPb { namespace XrdSsiPb {
...@@ -83,17 +88,17 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const ...@@ -83,17 +88,17 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
} }
// Format results in a tabular format for a human // Format results in a tabular format for a human
else switch(record.data_case()) { else switch(record.data_case()) {
case Data::kAflsItem: CtaAdminTextFormatter::print(record.afls_item()); break; case Data::kAflsItem: formattedText.print(record.afls_item()); break;
case Data::kAflsSummary: CtaAdminTextFormatter::print(record.afls_summary()); break; case Data::kAflsSummary: formattedText.print(record.afls_summary()); break;
case Data::kFrlsItem: CtaAdminTextFormatter::print(record.frls_item()); break; case Data::kFrlsItem: formattedText.print(record.frls_item()); break;
case Data::kFrlsSummary: CtaAdminTextFormatter::print(record.frls_summary()); break; case Data::kFrlsSummary: formattedText.print(record.frls_summary()); break;
case Data::kLpaItem: CtaAdminTextFormatter::print(record.lpa_item()); break; case Data::kLpaItem: formattedText.print(record.lpa_item()); break;
case Data::kLpaSummary: CtaAdminTextFormatter::print(record.lpa_summary()); break; case Data::kLpaSummary: formattedText.print(record.lpa_summary()); break;
case Data::kLprItem: CtaAdminTextFormatter::print(record.lpr_item()); break; case Data::kLprItem: formattedText.print(record.lpr_item()); break;
case Data::kLprSummary: CtaAdminTextFormatter::print(record.lpr_summary()); break; case Data::kLprSummary: formattedText.print(record.lpr_summary()); break;
case Data::kTplsItem: CtaAdminTextFormatter::print(record.tpls_item()); break; case Data::kTplsItem: formattedText.print(record.tpls_item()); break;
case Data::kTalsItem: CtaAdminTextFormatter::print(record.tals_item()); break; case Data::kTalsItem: formattedText.print(record.tals_item()); break;
case Data::kRelsItem: CtaAdminTextFormatter::print(record.rels_item()); break; case Data::kRelsItem: formattedText.print(record.rels_item()); break;
default: default:
throw std::runtime_error("Received invalid stream data from CTA Frontend."); throw std::runtime_error("Received invalid stream data from CTA Frontend.");
} }
...@@ -227,17 +232,17 @@ void CtaAdminCmd::send() const ...@@ -227,17 +232,17 @@ void CtaAdminCmd::send() const
std::cout << response.message_txt(); std::cout << response.message_txt();
// Print streaming response header // Print streaming response header
if(!isJson()) switch(response.show_header()) { if(!isJson()) switch(response.show_header()) {
case HeaderType::ARCHIVEFILE_LS: CtaAdminTextFormatter::printAfLsHeader(); break; case HeaderType::ARCHIVEFILE_LS: formattedText.printAfLsHeader(); break;
case HeaderType::ARCHIVEFILE_LS_SUMMARY: CtaAdminTextFormatter::printAfLsSummaryHeader(); break; case HeaderType::ARCHIVEFILE_LS_SUMMARY: formattedText.printAfLsSummaryHeader(); break;
case HeaderType::FAILEDREQUEST_LS: CtaAdminTextFormatter::printFrLsHeader(); break; case HeaderType::FAILEDREQUEST_LS: formattedText.printFrLsHeader(); break;
case HeaderType::FAILEDREQUEST_LS_SUMMARY: CtaAdminTextFormatter::printFrLsSummaryHeader(); break; case HeaderType::FAILEDREQUEST_LS_SUMMARY: formattedText.printFrLsSummaryHeader(); break;
case HeaderType::LISTPENDINGARCHIVES: CtaAdminTextFormatter::printLpaHeader(); break; case HeaderType::LISTPENDINGARCHIVES: formattedText.printLpaHeader(); break;
case HeaderType::LISTPENDINGARCHIVES_SUMMARY: CtaAdminTextFormatter::printLpaSummaryHeader(); break; case HeaderType::LISTPENDINGARCHIVES_SUMMARY: formattedText.printLpaSummaryHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES: CtaAdminTextFormatter::printLprHeader(); break; case HeaderType::LISTPENDINGRETRIEVES: formattedText.printLprHeader(); break;
case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: CtaAdminTextFormatter::printLprSummaryHeader(); break; case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: formattedText.printLprSummaryHeader(); break;
case HeaderType::TAPEPOOL_LS: CtaAdminTextFormatter::printTpLsHeader(); break; case HeaderType::TAPEPOOL_LS: formattedText.printTapePoolLsHeader(); break;
case HeaderType::TAPE_LS: CtaAdminTextFormatter::printTapeLsHeader(); break; case HeaderType::TAPE_LS: formattedText.printTapeLsHeader(); break;
case HeaderType::REPACK_LS: CtaAdminTextFormatter::printRepackLsHeader(); break; case HeaderType::REPACK_LS: formattedText.printRepackLsHeader(); break;
case HeaderType::NONE: case HeaderType::NONE:
default: break; default: break;
} }
......
This diff is collapsed.
...@@ -24,46 +24,109 @@ ...@@ -24,46 +24,109 @@
namespace cta { namespace cta {
namespace admin { namespace admin {
class CtaAdminTextFormatter class TextFormatter
{ {
public: public:
// Output headers /*!
static void printAfLsHeader(); * Constructor
static void printAfLsSummaryHeader(); *
static void printFrLsHeader(); * @param[in] bufLines Number of text lines to buffer before flushing formatted output
static void printFrLsSummaryHeader(); * (Not used for JSON output which does not need to be formatted
static void printLpaHeader(); * so can be streamed directly)
static void printLpaSummaryHeader(); */
static void printLprHeader(); TextFormatter(unsigned int bufLines = 1000) :
static void printLprSummaryHeader(); m_bufLines(bufLines) {
static void printTpLsHeader(); m_outputBuffer.reserve(bufLines);
static void printTapeLsHeader(); }
static void printRepackLsHeader();
~TextFormatter() {
flush();
}
// Output headers
void printAfLsHeader();
void printAfLsSummaryHeader();
void printFrLsHeader();
void printFrLsSummaryHeader();
void printLpaHeader();
void printLpaSummaryHeader();
void printLprHeader();
void printLprSummaryHeader();
void printTapePoolLsHeader();
void printTapeLsHeader();
void printRepackLsHeader();
// Output records // Output records
static void print(const ArchiveFileLsItem &afls_item); void print(const ArchiveFileLsItem &afls_item);
static void print(const ArchiveFileLsSummary &afls_summary); void print(const ArchiveFileLsSummary &afls_summary);
static void print(const FailedRequestLsItem &frls_item); void print(const FailedRequestLsItem &frls_item);
static void print(const FailedRequestLsSummary &frls_summary); void print(const FailedRequestLsSummary &frls_summary);
static void print(const ListPendingArchivesItem &lpa_item); void print(const ListPendingArchivesItem &lpa_item);
static void print(const ListPendingArchivesSummary &lpa_summary); void print(const ListPendingArchivesSummary &lpa_summary);
static void print(const ListPendingRetrievesItem &lpr_item); void print(const ListPendingRetrievesItem &lpr_item);
static void print(const ListPendingRetrievesSummary &lpr_summary); void print(const ListPendingRetrievesSummary &lpr_summary);
static void print(const TapePoolLsItem &tpls_item); void print(const TapePoolLsItem &tpls_item);
static void print(const TapeLsItem &tals_item); void print(const TapeLsItem &tals_item);
static void print(const RepackLsItem &rels_item); void print(const RepackLsItem &rels_item);
private: private:
// Static method to convert time to string //! Add a line to the buffer
static std::string timeToString(const time_t &time) template<typename... Args>
{ void push_back(Args... args) {
std::string timeString(ctime(&time)); std::vector<std::string> line;
timeString.resize(timeString.size()-1); //remove newline buildVector(line, args...);
return timeString; m_outputBuffer.push_back(line);
} if(m_outputBuffer.size() >= m_bufLines) flush();
}
static constexpr const char* const TEXT_RED = "\x1b[31;1m"; //!< Terminal formatting code for red text
static constexpr const char* const TEXT_NORMAL = "\x1b[0m"; //!< Terminal formatting code for normal text //! Recursive variadic method to build a log string from an arbitrary number of items of arbitrary type
template<typename T, typename... Args>
static void buildVector(std::vector<std::string> &line, const T &item, Args... args) {
buildVector(line, item);
buildVector(line, args...);
}
//! Base case method to add one item to the log
static void buildVector(std::vector<std::string> &line, const std::string &item) {
line.push_back(item);
}
//! Base case method to add one item to the log, overloaded for char*
static void buildVector(std::vector<std::string> &line, const char *item) {
line.push_back(std::string(item));
}
//! Base case method to add one item to the log, overloaded for bool
static void buildVector(std::vector<std::string> &line, bool item) {
line.push_back(item ? "true" : "false");
}
/*!
* Base case method to add one item to the log, with partial specialisation
* (works for all integer and floating-point types)
*/
template<typename T>
static void buildVector(std::vector<std::string> &line, const T &item) {
line.push_back(std::to_string(item));
}
//! Convert double to string with one decimal place precision and a suffix
static std::string doubleToStr(double value, char unit);
//! Convert UNIX time to string
static std::string timeToStr(const time_t &unixtime);
//! Convert data size in bytes to abbreviated string with appropriate size suffix (K/M/G/T/P/E)
static std::string dataSizeToStr(uint64_t value);
//! Flush buffer to stdout
void flush();
unsigned int m_bufLines; //!< Number of text lines to buffer before flushing formatted output
std::vector<std::vector<std::string>> m_outputBuffer; //!< Buffer for text output (not used for JSON)
static constexpr const char* const TEXT_RED = "\x1b[31;1m"; //!< Terminal formatting code for red text
static constexpr const char* const TEXT_NORMAL = "\x1b[0m"; //!< Terminal formatting code for normal text
}; };
}} }}
...@@ -89,7 +89,7 @@ echo "Launching repack request for VID ${VID_TO_REPACK}, bufferURL = ${FULL_REPA ...@@ -89,7 +89,7 @@ echo "Launching repack request for VID ${VID_TO_REPACK}, bufferURL = ${FULL_REPA
admin_cta re add --vid ${VID_TO_REPACK} --justmove --bufferurl ${FULL_REPACK_BUFFER_URL} admin_cta re add --vid ${VID_TO_REPACK} --justmove --bufferurl ${FULL_REPACK_BUFFER_URL}
SECONDS_PASSED=0 SECONDS_PASSED=0
while test 0 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Complete|Failed" | wc -l`; do while test 0 = `admin_cta --json repack ls --vid ${VID_TO_REPACK} | jq -r '.[0] | select(.status == "Complete" or .status == "Failed")' | wc -l`; do
echo "Waiting for repack request on tape ${VID_TO_REPACK} to be complete: Seconds passed = $SECONDS_PASSED" echo "Waiting for repack request on tape ${VID_TO_REPACK} to be complete: Seconds passed = $SECONDS_PASSED"
sleep 1 sleep 1
let SECONDS_PASSED=SECONDS_PASSED+1 let SECONDS_PASSED=SECONDS_PASSED+1
...@@ -99,7 +99,7 @@ while test 0 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Complete|F ...@@ -99,7 +99,7 @@ while test 0 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Complete|F
exit 1 exit 1
fi fi
done done
if test 1 = `admin_cta repack ls --vid ${VID_TO_REPACK} | grep -E "Failed" | wc -l`; then if test 1 = `admin_cta --json repack ls --vid ${VID_TO_REPACK} | jq -r '.[0] | select(.status == "Failed")' | wc -l`; then
echo "Repack failed for tape ${VID_TO_REPACK}." echo "Repack failed for tape ${VID_TO_REPACK}."
exit 1 exit 1
fi fi
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment