Commit 1cf202ae authored by Michael Davis's avatar Michael Davis
Browse files

Merge remote-tracking branch 'origin/master' into tapefile_ls

Conflicts:
	cmdline/CtaAdminCmdParse.hpp
parents 61dbb4bc f8e83e6a
# v3.1-3
## Summary
### Features
- Upstream eos 4.8.10-1
- Adds a fix for `eos-ns-inspect` to [correctly list extended attributes on files](https://its.cern.ch/jira/browse/EOS-4319)
- The `--no-recall` flag can be passed to `cta-admin repack add` command:
- The repack request will NOT trigger any retrieve mount. Only the files that are in the repack buffer will be considered for archival. This is used to inject recoverred files from a tape with some hard to read fseqs.
- New `cta-admin schedulinginfos ls` command available to list potential mounts detected by the scheduler
### Modification
- Shrinked `cta-admin repack ls` tabular output
- cta-admin help commands listed in alphabetical order
- Catalogue connection pool improvements
- The scheduler will take the tape that has the highest occupancy for archival in order to limit data scattering across all available tapes
# v3.1-2
## Summary
### Moficiation
### Modification
- Added database upgrade/changelog script oracle/3.0to3.1.sql
# v3.1-1
## Summary
......@@ -17,6 +38,7 @@
- Catalogue schema version 3.1 : addition of a new index on the TAPE table
- Catalogue and Unit tests improvements
# v3.0-3
## Summary
......@@ -25,6 +47,7 @@
- The cta-statistics-update tool updates the tape statistics one by one
# v3.0-2
## Summary
......
......@@ -138,7 +138,6 @@ namespace {
auto tape = getTape1();
tape.vid = "VIDTWO";
tape.comment = "Creation of tape two";
return tape;
}
}
......@@ -5880,6 +5879,69 @@ TEST_P(cta_catalogue_CatalogueTest, getTapesForWriting) {
ASSERT_EQ(0, tape.dataOnTapeInBytes);
}
 
TEST_P(cta_catalogue_CatalogueTest, getTapesForWritingOrderedByDataInBytesDesc) {
using namespace cta;
const bool logicalLibraryIsDisabled= false;
const uint64_t nbPartialTapes = 2;
const bool isEncrypted = true;
const cta::optional<std::string> supply("value for the supply pool mechanism");
m_catalogue->createMediaType(m_admin, m_mediaType);
m_catalogue->createLogicalLibrary(m_admin, m_tape1.logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
m_catalogue->createVirtualOrganization(m_admin, m_vo);
m_catalogue->createTapePool(m_admin, m_tape1.tapePoolName, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool");
m_catalogue->createTape(m_admin, m_tape1);
m_catalogue->tapeLabelled(m_tape1.vid, "tape_drive");
const std::list<catalogue::TapeForWriting> tapes = m_catalogue->getTapesForWriting(m_tape1.logicalLibraryName);
ASSERT_EQ(1, tapes.size());
const catalogue::TapeForWriting tape = tapes.front();
ASSERT_EQ(m_tape1.vid, tape.vid);
ASSERT_EQ(m_tape1.mediaType, tape.mediaType);
ASSERT_EQ(m_tape1.vendor, tape.vendor);
ASSERT_EQ(m_tape1.tapePoolName, tape.tapePool);
ASSERT_EQ(m_vo.name, tape.vo);
ASSERT_EQ(0, tape.lastFSeq);
ASSERT_EQ(m_mediaType.capacityInBytes, tape.capacityInBytes);
ASSERT_EQ(0, tape.dataOnTapeInBytes);
//Create a tape and insert a file in it
m_catalogue->createStorageClass(m_admin, m_storageClassSingleCopy);
m_catalogue->createTape(m_admin, m_tape2);
m_catalogue->tapeLabelled(m_tape2.vid, "tape_drive");
const uint64_t fileSize = 1234 * 1000000000UL;
{
auto file1WrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>();
auto & file1Written = *file1WrittenUP;
std::set<cta::catalogue::TapeItemWrittenPointer> file1WrittenSet;
file1WrittenSet.insert(file1WrittenUP.release());
file1Written.archiveFileId = 1234;
file1Written.diskInstance = "diskInstance";
file1Written.diskFileId = "5678";
file1Written.diskFileOwnerUid = PUBLIC_DISK_USER;
file1Written.diskFileGid = PUBLIC_DISK_GROUP;
file1Written.size = fileSize;
file1Written.checksumBlob.insert(checksum::ADLER32, 0x1000); // tests checksum with embedded zeros
file1Written.storageClassName = m_storageClassSingleCopy.name;
file1Written.vid = m_tape2.vid;
file1Written.fSeq = 1;
file1Written.blockId = 4321;
file1Written.copyNb = 1;
file1Written.tapeDrive = "tape_drive";
m_catalogue->filesWrittenToTape(file1WrittenSet);
}
//The tape m_tape2 should be returned by the Catalogue::getTapesForWriting() method
ASSERT_EQ(m_tape2.vid,m_catalogue->getTapesForWriting(m_tape2.logicalLibraryName).front().vid);
}
TEST_P(cta_catalogue_CatalogueTest, getTapesForWriting_disabled_tape) {
using namespace cta;
 
......
......@@ -4821,6 +4821,7 @@ void RdbmsCatalogue::createMountPolicy(
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5445,6 +5446,7 @@ void RdbmsCatalogue::deleteMountPolicy(const std::string &name) {
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5584,6 +5586,7 @@ void RdbmsCatalogue::modifyMountPolicyArchivePriority(const common::dataStructur
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5622,6 +5625,7 @@ void RdbmsCatalogue::modifyMountPolicyArchiveMinRequestAge(const common::dataStr
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5660,6 +5664,7 @@ void RdbmsCatalogue::modifyMountPolicyRetrievePriority(const common::dataStructu
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5698,6 +5703,7 @@ void RdbmsCatalogue::modifyMountPolicyRetrieveMinRequestAge(const common::dataSt
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5736,6 +5742,7 @@ void RdbmsCatalogue::modifyMountPolicyMaxDrivesAllowed(const common::dataStructu
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -5774,6 +5781,7 @@ void RdbmsCatalogue::modifyMountPolicyComment(const common::dataStructures::Secu
m_groupMountPolicyCache.invalidate();
m_userMountPolicyCache.invalidate();
m_allMountPoliciesCache.invalidate();
}
//------------------------------------------------------------------------------
......@@ -7342,7 +7350,8 @@ std::list<TapeForWriting> RdbmsCatalogue::getTapesForWriting(const std::string &
"TAPE.IS_FULL = '0' AND "
"TAPE.IS_READ_ONLY = '0' AND "
"TAPE.IS_FROM_CASTOR = '0' AND "
"LOGICAL_LIBRARY.LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME";
"LOGICAL_LIBRARY.LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME "
"ORDER BY TAPE.DATA_IN_BYTES DESC";
auto conn = m_connPool.getConn();
auto stmt = conn.createStmt(sql);
......
......@@ -143,6 +143,7 @@ RdbmsCatalogueGetArchiveFilesForRepackItor::RdbmsCatalogueGetArchiveFilesForRepa
m_rset = m_stmt.executeQuery();
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
......@@ -155,6 +156,16 @@ RdbmsCatalogueGetArchiveFilesForRepackItor::RdbmsCatalogueGetArchiveFilesForRepa
// destructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetArchiveFilesForRepackItor::~RdbmsCatalogueGetArchiveFilesForRepackItor() {
releaseDbResources();
}
//------------------------------------------------------------------------------
// releaseDbResources
//------------------------------------------------------------------------------
void RdbmsCatalogueGetArchiveFilesForRepackItor::releaseDbResources() noexcept {
m_rset.reset();
m_stmt.reset();
m_conn.reset();
}
//------------------------------------------------------------------------------
......@@ -206,6 +217,7 @@ common::dataStructures::ArchiveFile RdbmsCatalogueGetArchiveFilesForRepackItor::
auto completeArchiveFile = m_archiveFileBuilder.append(archiveFile);
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
// If the ArchiveFile object under construction is complete
if (nullptr != completeArchiveFile.get()) {
......
......@@ -108,12 +108,18 @@ private:
*/
rdbms::Rset m_rset;
/**
* Releases the database resources.
*
* This method is idempotent.
*/
void releaseDbResources() noexcept;
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive
* ID and then copy number.
*/
ArchiveFileBuilder<cta::common::dataStructures::ArchiveFile> m_archiveFileBuilder;
}; // class RdbmsCatalogueGetArchiveFilesForRepackItor
} // namespace catalogue
......
......@@ -190,6 +190,7 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor(
}
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
......@@ -202,6 +203,16 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor(
// destructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetArchiveFilesItor::~RdbmsCatalogueGetArchiveFilesItor() {
releaseDbResources();
}
//------------------------------------------------------------------------------
// releaseDbResources
//------------------------------------------------------------------------------
void RdbmsCatalogueGetArchiveFilesItor::releaseDbResources() noexcept {
m_rset.reset();
m_stmt.reset();
m_conn.reset();
}
//------------------------------------------------------------------------------
......@@ -253,6 +264,7 @@ common::dataStructures::ArchiveFile RdbmsCatalogueGetArchiveFilesItor::next() {
auto completeArchiveFile = m_archiveFileBuilder.append(archiveFile);
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
// If the ArchiveFile object under construction is complete
if (nullptr != completeArchiveFile.get()) {
......
......@@ -106,12 +106,18 @@ private:
*/
rdbms::Rset m_rset;
/**
* Releases the database resources.
*
* This method is idempotent.
*/
void releaseDbResources() noexcept;
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive
* ID and then copy number.
*/
ArchiveFileBuilder<cta::common::dataStructures::ArchiveFile> m_archiveFileBuilder;
}; // class RdbmsCatalogueGetArchiveFilesItor
} // namespace catalogue
......
......@@ -72,6 +72,9 @@ namespace catalogue {
}
} // anonymous namespace
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetDeletedArchiveFilesItor::RdbmsCatalogueGetDeletedArchiveFilesItor(
log::Logger &log,
rdbms::ConnPool &connPool,
......@@ -191,6 +194,7 @@ RdbmsCatalogueGetDeletedArchiveFilesItor::RdbmsCatalogueGetDeletedArchiveFilesIt
}
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
} catch(exception::UserError &) {
throw;
} catch(exception::Exception &ex) {
......@@ -199,9 +203,25 @@ RdbmsCatalogueGetDeletedArchiveFilesItor::RdbmsCatalogueGetDeletedArchiveFilesIt
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
RdbmsCatalogueGetDeletedArchiveFilesItor::~RdbmsCatalogueGetDeletedArchiveFilesItor() {
releaseDbResources();
}
//------------------------------------------------------------------------------
// releaseDbResources
//------------------------------------------------------------------------------
void RdbmsCatalogueGetDeletedArchiveFilesItor::releaseDbResources() noexcept {
m_rset.reset();
m_stmt.reset();
m_conn.reset();
}
//------------------------------------------------------------------------------
// hasMore
//------------------------------------------------------------------------------
bool RdbmsCatalogueGetDeletedArchiveFilesItor::hasMore() {
m_hasMoreHasBeenCalled = true;
......@@ -217,7 +237,9 @@ bool RdbmsCatalogueGetDeletedArchiveFilesItor::hasMore() {
}
}
//------------------------------------------------------------------------------
// next
//------------------------------------------------------------------------------
common::dataStructures::DeletedArchiveFile RdbmsCatalogueGetDeletedArchiveFilesItor::next() {
try {
if(!m_hasMoreHasBeenCalled) {
......@@ -246,6 +268,7 @@ common::dataStructures::DeletedArchiveFile RdbmsCatalogueGetDeletedArchiveFilesI
auto completeArchiveFile = m_archiveFileBuilder.append(archiveFile);
m_rsetIsEmpty = !m_rset.next();
if(m_rsetIsEmpty) releaseDbResources();
// If the ArchiveFile object under construction is complete
if (nullptr != completeArchiveFile.get()) {
......
......@@ -108,6 +108,13 @@ private:
*/
rdbms::Rset m_rset;
/**
* Releases the database resources.
*
* This method is idempotent.
*/
void releaseDbResources() noexcept;
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive
* ID and then copy number.
......
......@@ -106,6 +106,7 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
case Data::kVolsItem: std::cout << Log::DumpProtobuf(&record.vols_item()); break;
case Data::kVersionItem: std::cout << Log::DumpProtobuf(&record.version_item()); break;
case Data::kMtlsItem: std::cout << Log::DumpProtobuf(&record.mtls_item()); break;
case Data::kSilsItem: std::cout << Log::DumpProtobuf(&record.sils_item()); break;
default:
throw std::runtime_error("Received invalid stream data from CTA Frontend.");
}
......@@ -137,6 +138,7 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
case Data::kVolsItem: formattedText.print(record.vols_item()); break;
case Data::kVersionItem: formattedText.print(record.version_item()); break;
case Data::kMtlsItem: formattedText.print(record.mtls_item()); break;
case Data::kSilsItem: break;
default:
throw std::runtime_error("Received invalid stream data from CTA Frontend.");
}
......@@ -298,6 +300,7 @@ void CtaAdminCmd::send() const
case HeaderType::VIRTUALORGANIZATION_LS: formattedText.printVirtualOrganizationLsHeader(); break;
case HeaderType::VERSION_CMD: formattedText.printVersionHeader(); break;
case HeaderType::MEDIATYPE_LS: formattedText.printMediaTypeLsHeader(); break;
case HeaderType::SCHEDULINGINFOS_LS: formattedText.printSchedulingInfosLsHeader(); break;
case HeaderType::NONE:
default: break;
}
......
......@@ -215,6 +215,8 @@ const cmdLookup_t cmdLookup = {
{ "vo", AdminCmd::CMD_VIRTUALORGANIZATION },
{ "version", AdminCmd::CMD_VERSION},
{ "v", AdminCmd::CMD_VERSION},
{ "schedulinginfos", AdminCmd::CMD_SCHEDULINGINFOS},
{ "si", AdminCmd::CMD_SCHEDULINGINFOS},
};
......@@ -260,7 +262,7 @@ const std::map<std::string, OptionBoolean::Key> boolOptions = {
{ "--log", OptionBoolean::SHOW_LOG_ENTRIES },
{ "--lookupnamespace", OptionBoolean::LOOKUP_NAMESPACE },
{ "--showsuperseded", OptionBoolean::SHOW_SUPERSEDED },
{ "--summary", OptionBoolean::SUMMARY }
{ "--no-recall", OptionBoolean::NO_RECALL}
};
......@@ -363,14 +365,15 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = {
"\n This command allows to manage repack requests.\n\n"
" Submit a repack request by using the \"add\" subcommand :\n"
" * Specify the vid (--vid option) or all the vids to repack by giving a file path to the --vidfile option.\n"
" * Specify the mount policy (--mountpolicy parameter) to give a specific mount policy that will be applied to the repack subrequests (retrieve and archive requests).\n"
" * If the --bufferURL option is set, it will overwrite the default one. It should respect the following format : root://eosinstance//path/to/repack/buffer.\n"
" The default bufferURL is set in the CTA frontend configuration file.\n"
" * If the --justmove option is set, the files located on the tape to repack will be migrated on one or multiple tapes.\n"
" If the --justaddcopies option is set, new (or missing) copies (as defined by the storage class) of the files located on the tape to repack will be created and migrated.\n"
" By default, CTA will migrate AND add new (or missing) copies (as defined by the storage class) of the files located on the tape to repack.\n"
" * The --mountpolicy option allows to give a specific mount policy that will be applied to the repack subrequests (retrieve and archive requests).\n"
" By default, a hardcoded mount policy is applied (every request priorities and minimum request ages = 1).\n"
" * If the --disabledtape flag is set, the tape to repack will be mounted for retrieval even if it is disabled."
" * If the --disabledtape flag is set, the tape to repack will be mounted for retrieval even if it is disabled.\n"
" * If the --no-recall flag is set, no retrieve mount will be triggered and only the files that are located in the buffer will be considered for archival."
"\n\n"
}},
{ AdminCmd::CMD_REQUESTERMOUNTRULE, { "requestermountrule", "rmr", { "add", "ch", "rm", "ls" } }},
......@@ -403,7 +406,8 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = {
"\n\n"
}},
{ AdminCmd::CMD_VIRTUALORGANIZATION, { "virtualorganization", "vo", { "add", "ch", "rm", "ls" } }},
{ AdminCmd::CMD_VERSION, { "version", "v", { } }},
{ AdminCmd::CMD_VERSION, { "version", "v", { } }},
{ AdminCmd::CMD_SCHEDULINGINFOS, { "schedulinginfos", "si", { "ls" } }},
};
......@@ -484,11 +488,12 @@ const Option opt_disabled_tape { Option::OPT_FLAG, "--disabledtape",
const Option opt_disksystem { Option::OPT_STR, "--disksystem", "-n", " <disk_system_name>" };
const Option opt_file_regexp { Option::OPT_STR, "--fileregexp", "-r", " <file_regexp>" };
const Option opt_free_space_query_url { Option::OPT_STR, "--freespacequeryurl", "-u", " <free_space_query_url>" };
const Option opt_refresh_interval { Option::OPT_UINT, "--refreshinterval", "-i", " <refresh_intreval>" };
const Option opt_targeted_free_space { Option::OPT_UINT, "--targetedfreespace", "-f", " <targeted_free_space>" };
const Option opt_sleep_time { Option::OPT_UINT, "--sleeptime", "-s", " <sleep time in s>" };
const Option opt_reason { Option::OPT_STR, "--reason", "-r", " <reason_status_change>" };
const Option opt_show_superseded { Option::OPT_FLAG, "--showsuperseded", "-s", "" };
const Option opt_refresh_interval { Option::OPT_UINT, "--refreshinterval", "-i", " <refresh_intreval>" };
const Option opt_targeted_free_space { Option::OPT_UINT, "--targetedfreespace", "-f", " <targeted_free_space>" };
const Option opt_sleep_time { Option::OPT_UINT, "--sleeptime", "-s", " <sleep time in s>" };
const Option opt_reason { Option::OPT_STR, "--reason", "-r", " <reason_status_change>" };
const Option opt_show_superseded { Option::OPT_FLAG, "--showsuperseded", "-s", "" };
const Option opt_no_recall { Option::OPT_FLAG, "--no-recall", "-nr", "" };
/*!
* Map valid options to commands
......@@ -551,7 +556,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
{{ AdminCmd::CMD_MOUNTPOLICY, AdminCmd::SUBCMD_LS }, { }},
/*----------------------------------------------------------------------------------------------------*/
{{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_ADD },
{ opt_vid.optional(), opt_vidfile.optional(), opt_bufferurl.optional(), opt_justmove.optional(), opt_justaddcopies.optional(), opt_mountpolicy, opt_disabled_tape.optional() }},
{ opt_vid.optional(), opt_vidfile.optional(), opt_bufferurl.optional(), opt_justmove.optional(), opt_justaddcopies.optional(), opt_mountpolicy, opt_disabled_tape.optional(), opt_no_recall.optional() }},
{{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_RM }, { opt_vid }},
{{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_LS }, { opt_vid.optional() }},
{{ AdminCmd::CMD_REPACK, AdminCmd::SUBCMD_ERR }, { opt_vid }},
......@@ -616,6 +621,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
{{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_LS },
{ }},
{{ AdminCmd::CMD_VERSION, AdminCmd::SUBCMD_NONE }, { }},
{{ AdminCmd::CMD_SCHEDULINGINFOS, AdminCmd::SUBCMD_LS }, { }},
};
......
......@@ -658,8 +658,7 @@ void TextFormatter::printRepackLsHeader() {
push_back("HEADER");
push_back(
"vid",
"repackBufferURL",
"userProvidedFiles",
"providedFiles",
"totalFilesToRetrieve",
"totalBytesToRetrieve",
"totalFilesToArchive",
......@@ -667,10 +666,6 @@ void TextFormatter::printRepackLsHeader() {
"retrievedFiles",
"archivedFiles",
"failedToRetrieveFiles",
"failedToRetrieveBytes",
"failedToArchiveFiles",
"failedToArchiveBytes",
"lastExpandedFSeq",
"status"
);
}
......@@ -678,7 +673,6 @@ void TextFormatter::printRepackLsHeader() {
void TextFormatter::print(const RepackLsItem &rels_item) {
push_back(
rels_item.vid(),
rels_item.repack_buffer_url(),
rels_item.user_provided_files(),
rels_item.total_files_to_retrieve(),
dataSizeToStr(rels_item.total_bytes_to_retrieve()),
......@@ -687,10 +681,6 @@ void TextFormatter::print(const RepackLsItem &rels_item) {
rels_item.retrieved_files(),
rels_item.archived_files(),
rels_item.failed_to_retrieve_files(),
dataSizeToStr(rels_item.failed_to_retrieve_bytes()),
rels_item.failed_to_archive_files(),
dataSizeToStr(rels_item.failed_to_archive_bytes()),
rels_item.last_expanded_fseq(),
rels_item.status()
);
}
......@@ -1095,4 +1085,9 @@ void TextFormatter::print(const VersionItem & version_item){
);
}
void TextFormatter::printSchedulingInfosLsHeader(){
push_back("HEADER");
push_back("No tabular output available for this command, please use the --json flag.");
}
}}
......@@ -69,6 +69,7 @@ public:
void printVirtualOrganizationLsHeader();
void printVersionHeader();
void printMediaTypeLsHeader();
void printSchedulingInfosLsHeader();
// Output records
void print(const AdminLsItem &adls_item);
......
......@@ -70,6 +70,7 @@ struct RepackInfo {
uint64_t archivedFiles;
bool isExpandFinished;
bool forceDisabledTape;
bool noRecall;
RepackDestinationInfo::List destinationInfos;
// std::string tag;
// uint64_t totalFiles;
......
......@@ -975,5 +975,22 @@ void appendParameterXRootFileURL(std::string &fileURL, const std::string &parame
}
}
std::string removePrefix(const std::string& input, char prefixChar){
size_t position = input.find_first_not_of(prefixChar);
if(position == std::string::npos){
return input;
} else {
return input.substr(position,input.size());
}
}
std::string getEnv(const std::string& variableName){
const char * envVarC = std::getenv(variableName.c_str());
if(envVarC == NULL){
return "";
}
return std::string(envVarC);
}
} // namespace utils
} // namespace cta
......@@ -462,6 +462,23 @@ namespace utils {
return ret;
}
/**
* Allows to remove the first c chars from the beginning of a string
* Example : removePrefix(aaaaaabcdef,'a') -> bcdef
* @param input the string from which we will remove the chars c from it
* @param prefixChar the character that we want to remove from the beginning
* @return a new string with the prefix.
*/
std::string removePrefix(const std::string & input, char prefixChar);
/**
* Returns the value of the environment variable passed in parameter
* @param variableName the name of the environment variable to be passed
* @return the value of the environment variable passed in parameter
* If the environment variable is not set, it will return an empty string
*/
std::string getEnv(const std::string & variableName);
} // namespace utils
} // namespace cta
0:eos-archive-4.8.3-1.el7.cern.x86_64
0:eos-cleanup-4.8.3-1.el7.cern.x86_64
0:eos-client-4.8.3-1.el7.cern.x86_64
0:eos-debuginfo-4.8.3-1.el7.cern.x86_64
0:eos-fuse-4.8.3-1.el7.cern.x86_64
0:eos-fuse-core-4.8.3-1.el7.cern.x86_64
0:eos-fuse-sysv-4.8.3-1.el7.cern.x86_64
0:eos-fusex-4.8.3-1.el7.cern.x86_64
0:eos-fusex-core-4.8.3-1.el7.cern.x86_64
0:eos-fusex-selinux-4.8.3-1.el7.cern.x86_64
0:eos-ns-inspect-4.8.3-1.el7.cern.x86_64
0:eos-server-4.8.3-1.el7.cern.x86_64
0:eos-srm-4.8.3-1.el7.cern.x86_64
0:eos-test-4.8.3-1.el7.cern.x86_64
0:eos-testkeytab-4.8.3-1.el7.cern.x86_64
0:eos-archive-4.8.10-1.el7.cern.x86_64