35 using namespace msgGridTools;
42 using clock = std::chrono::steady_clock;
47 std::recursive_mutex mutex;
50 bool haveProxy =
false;
53 clock::time_point proxyExpiration;
57 std::lock_guard<std::recursive_mutex>
lock (mutex);
59 if (haveProxy ==
false)
70 std::istringstream
str (output);
73 if (!(str >> seconds))
76 std::istringstream str2 (
output.substr(
output.rfind(
'\n',
output.size()-2)+1,std::string::npos));
78 if (!(str2 >> seconds)){
79 ANA_MSG_INFO (
"failed to parse command output: " << output);
82 proxyExpiration = clock::now() + std::chrono::seconds (seconds);
88 proxyExpiration = clock::now() + std::chrono::seconds (seconds);
95 proxyExpiration > clock::now() + std::chrono::minutes (20);
100 std::lock_guard<std::recursive_mutex>
lock (mutex);
109 throw std::runtime_error (
"failed to obtain a valid grid proxy after several attempts");
125 ProxyData& proxyData ()
136 std::vector<std::string>
137 readLineList (
const std::string& text,
138 const std::string& begin)
140 std::vector<std::string>
result;
142 for (std::string::size_type
split = 0;
150 if (split2 == std::string::npos)
151 split2 =
text.size();
157 const char *
const whitespace =
" \t\n\r\f\v";
158 const auto first = subresult.find_first_not_of (whitespace);
159 if (first == std::string::npos)
163 const auto last = subresult.find_last_not_of (whitespace);
164 subresult = subresult.substr (first, last - first + 1);
166 result.push_back (std::move (subresult));
176 std::string readLine (
const std::string& text,
177 const std::string& begin)
179 auto lines = readLineList (text, begin);
181 throw std::runtime_error (
"failed to find line starting with: " + begin);
182 if (
lines.size() > 1)
183 throw std::runtime_error (
"multiple lines starting with: " + begin);
191 unsigned readLineUnsigned (
const std::string& text,
192 const std::string& begin)
194 const auto line = readLine (text, begin);
195 std::istringstream
str (line);
197 if (!(str >> result) || !
str.eof())
198 throw std::runtime_error (
"failed to convert " + line +
" into an unsigned");
205 std::string rucioSetupCommand ()
207 return "source $ATLAS_LOCAL_ROOT_BASE/user/atlasLocalSetup.sh -q && lsetup --force 'rucio -w'";
215 static const std::string result =
"SAMPLEHANDLER_RUCIO_DOWNLOAD";
223 return proxyData().checkVomsProxy();
230 proxyData().ensureVomsProxy();
235 std::vector<std::string>
238#pragma GCC diagnostic push
239#pragma GCC diagnostic ignored "-Wpragmas"
240#pragma GCC diagnostic ignored "-Wunknown-pragmas"
241#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
243#pragma GCC diagnostic pop
248 std::vector<std::string>
257 static const std::string separator =
"------- SampleHandler Split -------";
258 std::vector<std::string> result;
261 std::string output =
sh::exec_read (
"source $ATLAS_LOCAL_ROOT_BASE/user/atlasLocalSetup.sh -q && lsetup --force fax && echo " + separator +
" && fax-get-gLFNs " +
sh::quote (name));
262 auto split = output.rfind (separator +
"\n");
263 if (
split == std::string::npos)
264 throw std::runtime_error (
"couldn't find separator in: " + output);
266 std::istringstream
str (output.substr (
split + separator.size() + 1));
267 std::regex pattern (filter);
269 while (std::getline (
str, line))
273 if (!line.starts_with (
"root:"))
274 throw std::runtime_error (
"faxListFilesRegex: couldn't parse line: " + line);
276 std::string::size_type split1 = line.rfind (
":");
277 std::string::size_type split2 = line.rfind (
"/");
280 if (split1 != std::string::npos)
283 result.push_back (line);
285 throw std::runtime_error (
"faxListFilesRegex: couldn't parse line: " + line);
288 if (result.size() == 0)
289 ANA_MSG_WARNING (
"dataset " << name <<
" did not contain any files. this is likely not right");
295 std::vector<std::string>
297 const std::string& selectOptions)
305 std::vector<std::string>
307 const std::string& selectOptions)
315 static const std::string separator =
"------- SampleHandler Split -------";
318 std::string output =
sh::exec_read (rucioSetupCommand() +
" && echo " + separator +
" && rucio list-file-replicas --pfns --protocols root " + selectOptions +
" " +
sh::quote (name));
319 auto split = output.rfind (separator +
"\n");
320 if (
split == std::string::npos)
321 throw std::runtime_error (
"couldn't find separator in: " + output);
322 std::istringstream
str (output.substr (
split + separator.size() + 1));
327 std::map<std::string,std::string> resultMap;
329 std::regex urlPattern (
"^root://.*");
330 std::regex pattern (filter);
332 while (std::getline (
str, line))
342 std::string::size_type
split = line.rfind (
"/");
343 if (
split != std::string::npos)
345 std::string filename = line.substr (
split+1);
347 resultMap[filename] = line;
349 throw std::runtime_error (
"rucioDirectAccessRegex: couldn't parse line: " + line);
353 std::vector<std::string> result;
354 for (
const auto&
file : resultMap)
355 result.push_back (
file.second);
356 if (result.size() == 0)
357 ANA_MSG_WARNING (
"dataset " + name +
" did not contain any files. this is likely not right");
369 static const std::string separator =
"------- SampleHandler Split -------";
370 std::vector<RucioListDidsEntry> result;
374 auto split = output.rfind (separator +
"\n");
375 if (
split == std::string::npos)
376 throw std::runtime_error (
"couldn't find separator in: " + output);
378 std::istringstream
str (output.substr (
split + separator.size() + 1));
379 std::regex pattern (
"^\\| ([a-zA-Z0-9_.-]+):([a-zA-Z0-9_.-]+) +\\| ([a-zA-Z0-9_.-]+) +\\| *$");
381 while (std::getline (
str, line))
384 if (std::regex_match (line, what, pattern))
387 entry.scope = what[1];
388 entry.name = what[2];
389 entry.type = what[3];
390 result.push_back (entry);
398 std::vector<RucioListFileReplicasEntry>
405 static const std::string separator =
"------- SampleHandler Split -------";
406 std::vector<RucioListFileReplicasEntry> result;
408 std::string command = rucioSetupCommand() +
" && echo " + separator +
" && rucio list-file-replicas --protocols root " +
sh::quote (
dataset);
412 auto split = output.rfind (separator +
"\n");
413 if (
split == std::string::npos)
414 throw std::runtime_error (
"couldn't find separator in: " + output);
416 std::istringstream
str (output.substr (
split + separator.size() + 1));
417 std::regex pattern (
"^\\| +([^ ]+) +\\| +([^ ]+) +\\| +([^ ]+ [^ ]+) +\\| +([^ ]+) +\\| +([^: ]+): ([^ ]+) +\\| *$");
419 while (std::getline (
str, line))
422 if (std::regex_match (line, what, pattern) &&
426 entry.scope = what[1];
427 entry.name = what[2];
428 entry.filesize = what[3];
429 entry.adler32 = what[4];
430 entry.disk = what[5];
431 entry.replica = what[6];
432 result.push_back (entry);
440 std::map<std::string,std::unique_ptr<MetaObject> >
447 static const std::string separator =
"------- SampleHandler Split -------";
448 std::map<std::string,std::unique_ptr<MetaObject> > result;
450 std::string command = rucioSetupCommand() +
" && echo " + separator +
" && rucio get-metadata";
459 auto split = output.rfind (separator +
"\n");
460 if (
split == std::string::npos)
461 throw std::runtime_error (
"couldn't find separator in: " + output);
463 std::istringstream
str (output.substr (
split + separator.size() + 1));
464 std::regex pattern (
"^([^:]+): *(.+)$");
466 auto meta = std::make_unique<MetaObject>();
468 auto addMeta = [&] ()
470 std::string name =
meta->castString (
"scope") +
":" +
meta->castString (
"name");
471 if (result.find (name) != result.end())
472 throw std::runtime_error (
"rucioGetMetadata: read " + name +
" twice");
473 result[name] = std::move (
meta);
476 while (std::getline (
str, line))
479 if (line ==
"------")
482 meta = std::make_unique<MetaObject>();
483 }
else if (std::regex_match (line, what, pattern))
485 if (
meta->get (what[1]))
486 throw std::runtime_error (std::string(
"duplicate entry: ") + what[1].
str());
487 meta->setString (what[1], what[2]);
488 }
else if (!line.empty())
495 for (
auto& subresult : result)
497 if (datasets.find (subresult.first) == datasets.end())
498 throw std::runtime_error (
"received result for dataset not requested: " + subresult.first);
502 if (result.find (
dataset) == result.end())
503 throw std::runtime_error (
"received no result for dataset: " +
dataset);
516 const std::string separator =
"------- SampleHandler Split -------";
517 std::string command = rucioSetupCommand() +
" && echo " + separator +
" && cd " +
sh::quote (location) +
" && rucio download " +
sh::quote (
dataset) +
" 2>&1";
521 auto split = output.rfind (separator +
"\n");
522 if (
split == std::string::npos)
523 throw std::runtime_error (
"couldn't find separator in: " + output);
524 output = output.substr (
split + separator.size() + 1);
527 result.did = readLine (output,
"DID ");
528 result.totalFiles = readLineUnsigned (output,
"Total files (DID): ");
529 result.downloadedFiles = readLineUnsigned (output,
"Downloaded files: ");
530 result.alreadyLocal = readLineUnsigned (output,
"Files already found locally: ");
531 result.notDownloaded = readLineUnsigned (output,
"Files that cannot be downloaded: ");
537 std::vector<RucioDownloadResult>
539 const std::vector<std::string>& datasets)
541 std::vector<RucioDownloadResult> result;
549 std::vector<std::string>
552 const std::string& fileGlob)
554 std::vector<std::string> result;
556 std::string path = location;
557 if (path.empty() || path.back() !=
'/')
559 if (
dataset.find (
':') != std::string::npos)
563 const std::string finished {
576 if (gSystem->AccessPathName (finished.c_str()) != 0)
579 if (status.downloadedFiles + status.alreadyLocal < status.totalFiles)
580 throw std::runtime_error (
"failed to download all files of " +
dataset);
582 std::ofstream finishedFile (finished.c_str());
584 throw std::runtime_error (
"failed to create marker file: " + finished);
588 std::istringstream
str (output);
590 while (std::getline (
str, line))
593 result.push_back (line);
#define RCU_REQUIRE_SOFT(x)
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
std::vector< std::string > split(const std::string &s, const std::string &t=":")
std::string exec_read(const std::string &cmd)
effects: execute the given command and return the output returns: the output of the command guarantee...
void exec(const std::string &cmd)
effects: execute the given command guarantee: strong failures: out of memory II failures: system fail...
std::string quote(const std::string &name)
effects: quote the given name to protect it from the shell returns: the quoted name guarantee: strong...
bool match_expr(const std::regex &expr, std::string_view str)
returns: whether we can match the entire string with the regular expression guarantee: strong failure...
std::string glob_to_regexp(std::string_view glob)
returns: a string that is the regular expression equivalent of the given glob expression guarantee: s...
This module provides a lot of global definitions, forward declarations and includes that are used by ...
std::vector< RucioDownloadResult > rucioDownloadList(const std::string &location, const std::vector< std::string > &datasets)
run rucio-download with multiple datasets
RucioDownloadResult rucioDownload(const std::string &location, const std::string &dataset)
run rucio-download
const std::string & downloadStageEnvVar()
the name of the environment variable containing the directory for staging files from the grid
std::vector< std::string > faxListFilesGlob(const std::string &name, const std::string &filter)
list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as...
std::vector< RucioListFileReplicasEntry > rucioListFileReplicas(const std::string &dataset)
run rucio-list-file-replicas for the given dataset
std::vector< RucioListDidsEntry > rucioListDids(const std::string &dataset)
run rucio-list-dids for the given dataset
void ensureVomsProxy()
ensure that we have a valid VOMS proxy available
std::map< std::string, std::unique_ptr< MetaObject > > rucioGetMetadata(const std::set< std::string > &datasets)
run rucio-get-metadata for the given list of datasets
std::vector< std::string > rucioDirectAccessRegex(const std::string &name, const std::string &filter, const std::string &selectOptions)
list the rucio URLs for all the files in the dataset or dataset container matching the given filter (...
std::vector< std::string > rucioCacheDatasetGlob(const std::string &location, const std::string &dataset, const std::string &fileGlob)
download the dataset, and return a list matching the pattern
bool checkVomsProxy()
return whether we have a valid VOMS proxy available
std::vector< std::string > faxListFilesRegex(const std::string &name, const std::string &filter)
list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as...
std::vector< std::string > rucioDirectAccessGlob(const std::string &name, const std::string &filter, const std::string &selectOptions)
list the rucio URLs for all the files in the dataset or dataset container matching the given filter (...
the result from rucio_download
one entry from the rucio-list-dids command
one entry from the rucio-list-file-replicas command