Commit 19801c1e authored by Eric Cano's avatar Eric Cano
Browse files

#252: Created and packaged a C++ based utility as an atlernative to the python based helper.

parent 1aaffb0d
......@@ -152,6 +152,8 @@ ELSE(DEFINED PackageOnly)
add_subdirectory(tapeserver)
add_subdirectory(XRootdSSiRmcd)
add_subdirectory(continuousintegration/orchestration/tests)
#Generate version information
configure_file(${PROJECT_SOURCE_DIR}/version.hpp.in
${CMAKE_BINARY_DIR}/version.h)
......
......@@ -7,7 +7,7 @@ if [ ! -e /etc/buildtreeRunner ]; then
yum-config-manager --enable ceph
# Install missing RPMs
yum -y install cta-cli cta-debuginfo xrootd-client eos-client jq python36
yum -y install cta-cli cta-systemtest-helpers cta-debuginfo xrootd-client eos-client jq python36
## Keep this temporary fix that may be needed if going to protobuf3-3.5.1 for CTA
# Install eos-protobuf3 separately as eos is OK with protobuf3 but cannot use it..
......
# The CERN Tape Archive(CTA) project
# Copyright(C) 2015 CERN
#
# 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/>.
cmake_minimum_required (VERSION 2.6)
find_package (xrootd REQUIRED)
find_package (xrootdclient REQUIRED)
include_directories (${XROOTD_INCLUDE_DIR} ${CMAKE_SOURCE_DIR})
add_executable(cta-client-ar-abortPrepare client-ar-abortPrepare.cpp)
target_link_libraries(cta-client-ar-abortPrepare XrdCl ctacommon)
install(TARGETS cta-client-ar-abortPrepare DESTINATION usr/bin)
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* 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/>.
*/
#include <getopt.h>
#include <string>
#include <iostream>
#include <memory>
#include <XrdCl/XrdClFileSystem.hh>
#include "common/utils/Regex.hpp"
#include "common/exception/XrootCl.hpp"
// No short options.
const char short_options[] = "";
// We require a handful of long options.
enum class OptionIds: int {
eos_instance = 1,
eos_poweruser = 2,
eos_dir = 3,
subdir = 4,
file = 5,
error_dir = 6
};
const struct ::option long_options[] = {
{ "eos-instance", required_argument, nullptr, (int)OptionIds::eos_instance },
{ "eos-poweruser", required_argument, nullptr, (int)OptionIds::eos_poweruser },
{ "eos-dir", required_argument, nullptr, (int)OptionIds::eos_dir },
{ "subdir", required_argument, nullptr, (int)OptionIds::subdir },
{ "file", required_argument, nullptr, (int)OptionIds::file },
{ "error-dir", required_argument, nullptr, (int)OptionIds::error_dir },
{ nullptr, 0, nullptr, 0 }
};
void help() {
std::cerr << "Expected parameters are: ";
const struct ::option * pOpt = long_options;
while (pOpt->name) {
std::cerr << "--" << pOpt->name << " ";
++pOpt;
}
std::cerr << std::endl;
}
// We make these variables global as they will be part of the process's environment.
char envXRD_LOGLEVEL[] = "XRD_LOGLEVEL=Dump";
std::unique_ptr<char[]> envKRB5CCNAME;
char envXrdSecPROTOCOL[] = "XrdSecPROTOCOL=krb5";
int main(int argc, char **argv) {
struct {
std::string eos_instance;
std::string eos_poweruser;
std::string eos_dir;
std::string subdir;
std::string file;
std::string error_dir;
} options;
int opt_ret;
while (-1 != (opt_ret = getopt_long(argc, argv, short_options, long_options, nullptr))) {
switch (opt_ret) {
case (int)OptionIds::eos_instance:
options.eos_instance = optarg;
break;
case (int)OptionIds::eos_poweruser:
options.eos_poweruser = optarg;
break;
case (int)OptionIds::eos_dir:
options.eos_dir = optarg;
break;
case (int)OptionIds::subdir:
options.subdir = optarg;
break;
case (int)OptionIds::file:
options.file = optarg;
break;
case (int)OptionIds::error_dir:
options.error_dir = optarg;
break;
case '?':
default:
std::cerr << "Unexpected option or missing argument." << std::endl;
exit(EXIT_FAILURE);
break;
}
}
if (options.eos_instance.empty() || options.eos_poweruser.empty() || options.error_dir.empty() || options.subdir.empty() ||
options.file.empty() || options.error_dir.empty()) {
std::cerr << "At least one option missing." << std::endl;
help();
exit (EXIT_FAILURE);
}
std::cout << "To run again: " << argv[0]
<< " --eos-instance=" << options.eos_instance
<< " --eos-poweruser=" << options.eos_poweruser
<< " --eos-dir=" << options.eos_dir
<< " --subdir=" << options.subdir
<< " --file=" << options.file
<< " --error_dir=" << options.error_dir << std::endl;
// Get the extended attribute for the retrieve request id
try {
// Prepare environment.
putenv(envXRD_LOGLEVEL);
std::string envKRB5CCNAMEvalue = std::string("KRB5CCNAME=/tmp/") + options.eos_poweruser + "/krb5cc_0";
// We need to copy to an array because of putenv's lack of const correctness.
envKRB5CCNAME.reset(new char[envKRB5CCNAMEvalue.size() + 1]);
strncpy(envKRB5CCNAME.get(), envKRB5CCNAMEvalue.c_str(), envKRB5CCNAMEvalue.size() + 1);
putenv(envKRB5CCNAME.get());
putenv(envXrdSecPROTOCOL);
XrdCl::FileSystem xrdfs(options.eos_instance);
std::string fileName = options.eos_dir + "/" + options.subdir + "/" + options.file;
std::string query = fileName + "?mgm.pcmd=xattr&mgm.subcmd=get&mgm.xattrname=sys.retrieve.req_id";
auto qcOpaque = XrdCl::QueryCode::OpaqueFile;
XrdCl::Buffer xrdArg;
xrdArg.FromString(query);
XrdCl::Buffer *respPtr = nullptr;
auto status = xrdfs.Query(qcOpaque, xrdArg, respPtr, (uint16_t)0 /*timeout=default*/);
// Ensure proper memory management for the response buffer (it is our responsilibity to free it, we delegate to the unique_ptr).
std::unique_ptr<XrdCl::Buffer> respUP(respPtr);
respPtr = nullptr;
cta::exception::XrootCl::throwOnError(status, "Error during XrdCl::Query");
cta::utils::Regex re("value=(.*)");
std::string respStr(respUP->GetBuffer(), respUP->GetSize());
auto reResult = re.exec(respStr);
if (reResult.size() != 2) {
// We did not receive the expected structure
throw cta::exception::Exception(std::string("Unexpected result from xattr query: ") + respStr);
}
std::string retrieveRequestId = reResult[1];
std::vector<std::string> files = { retrieveRequestId, fileName };
XrdCl::PrepareFlags::Flags flags = XrdCl::PrepareFlags::Cancel;
auto abortStatus = xrdfs.Prepare(files, flags, 0, respPtr, 0 /* timeout */);
cta::exception::XrootCl::throwOnError(abortStatus, "Error during XrdCl::Prepare");
} catch (cta::exception::Exception & ex) {
std::cerr << "Received exception: " << ex.what() << std::endl;
}
return 0;
}
......@@ -359,6 +359,8 @@ for ((subdir=0; subdir < ${NB_DIRS}; subdir++)); do
done
# Put all tape drives down
echo "Sleeping 3 seconds to let previous sessions finish."
sleep 3
admin_kdestroy &>/dev/null
admin_kinit &>/dev/null
INITIAL_DRIVES_STATE=`admin_cta --json dr ls`
......@@ -403,7 +405,7 @@ fi
for ((subdir=0; subdir < ${NB_DIRS}; subdir++)); do
echo -n "Cancelling prepare for files in ${EOS_DIR}/${subdir} using ${NB_PROCS} processes (prepare_abort)..."
cat ${STATUS_FILE} | grep ^${subdir}/ | cut -d/ -f2 \
| xargs --max-procs=${NB_PROCS} -iTEST_FILE_NAME /root/client_ar_abortPrepare.py --eos-instance ${EOSINSTANCE} \
| xargs --max-procs=${NB_PROCS} -iTEST_FILE_NAME cta-client-ar-abortPrepare --eos-instance ${EOSINSTANCE} \
--eos-poweruser ${EOSPOWER_USER} --eos-dir ${EOS_DIR} --subdir ${subdir} --file TEST_FILE_NAME --error-dir ${ERROR_DIR} \
| tee ${LOGDIR}/prepare_abort_sys.retrieve.req_id_${subdir}.log # | grep ^ERROR
echo Done.
......@@ -440,11 +442,12 @@ while test ${REMAINING_REQUESTS} -gt 0; do
done
# Check that the files were not retrieved
echo "Checking restaged files."
echo -n "Checking restaged files. Found: "
RESTAGEDFILES=0
for ((subdir=0; subdir < ${NB_DIRS}; subdir++)); do
RESTAGEDFILES=$(( ${RESTAGEDFILES} + $(eos root://${EOSINSTANCE} ls -y ${EOS_DIR}/${subdir} | egrep '^d[1-9][0-9]*::t1' | wc -l) ))
(( RESTAGEDFILES += $(eos root://${EOSINSTANCE} ls -y ${EOS_DIR}/${subdir} | egrep '^d[1-9][0-9]*::t1' | wc -l) ))
done
echo ${RESTAGEDFILES}
if [ "0" != "$(ls ${ERROR_DIR} 2> /dev/null | wc -l)" ]; then
# there were some prepare errors
......@@ -453,7 +456,6 @@ if [ "0" != "$(ls ${ERROR_DIR} 2> /dev/null | wc -l)" ]; then
mv ${ERROR_DIR}/* ${LOGDIR}/xrd_errors/
fi
# We can now delete the files
DELETED=0
if [[ $REMOVE == 1 ]]; then
......
......@@ -410,3 +410,13 @@ collects EOS disk copies that have been safely stored to tape.
%postun -n cta-fst-gcd
%systemd_postun cta-fst-gcd.service
%systemdDaemonReload
%package -n cta-systemtest-helpers
Summary: Collection of utilities deployed in system test client containers.
Group: Application/CTA
Requires: cta-lib = %{version}-%{release}
%description -n cta-systemtest-helpers
Collection of utilities deployed in system test client containers.
Currently contains a helper for the client-ar script, which should be installed alongside it.
%files -n cta-systemtest-helpers
%attr(0755,root,root) /usr/bin/cta-client-ar-abortPrepare
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment