59 if isinstance(c.server, str):
65 if c.server != []
or c.webHandoffDir !=
"" or c.lockFile ==
'':
67 print(
"Lockfile is disabled")
73 instance = SingleAppInstance( c.htmlDir +
"/" + c.lockFile,
True )
74 islocked = instance.acquire()
75 except SingleAppInstance.FileLockAcquisitionError
as e:
76 print(
'=========================================================================')
77 print(
'Cannot acquire lock on', c.htmlDir)
78 print(
'This usually means either')
79 print(
' -> the directory does not exist,')
80 print(
' -> you do not have the required permissions, or')
81 print(
' -> the directory is out of space.')
82 print(
'If you ran into this error while trying to test the web display, please')
83 print(
'read the instructions at:')
84 print(
'https://twiki.cern.ch/twiki/bin/view/Atlas/DQOperationalRecipes#Obtain_SVN_and_disk_write_permis')
86 print(
'Explicit error:', e)
87 print(
'=========================================================================')
91 print(
"Another instance is running; waiting 60 seconds...")
101 allDirsScriptLoc = c.htmlWeb
102 runlistLoc = c.htmlWeb +
"/" + c.runlist
108 if ( c.hanResultsDir.rfind(
"/")!=(len(c.hanResultsDir)-1) ):
111 if ( c.htmlDir.rfind(
"/")!=(len(c.htmlDir)-1) ):
114 inputFileName = inputFilePath
115 i = inputFilePath.rfind(
"/")
117 inputFileName = inputFilePath[i+1:]
120 shortStream =
"NoStream"
122 procpass = int(sys.argv[3])
124 if c.config ==
"RTT":
125 shortStream = time.strftime(
"%A")
127 fields = inputFileName.split(
".")
129 runid = int(fields[1])
130 shortStream = fields[2]
136 print(
"Searching for existing histogram cache to merge with input histograms...")
138 inputFilePath = _local_apply(mergeAndCache, ( inputFilePath, runid, shortStream, c.histogramCache ) )
139 except LockAcquisitionException:
141 shortStream =
"tmp_" + shortStream
142 elif c.histogramCache !=
"":
143 cacheFile, version =
findCacheFile( inputFilePath, runid, shortStream, c.histogramCache )
146 print(
"Removing cached histograms used during accumulation mode")
148 while cacheFile !=
'':
149 fullCachePath = c.histogramCache +
"/" + cacheFile
150 os.unlink( fullCachePath )
151 cacheFile, version =
findCacheFile( inputFilePath, runid, shortStream, c.histogramCache )
156 if len(sys.argv) >= 5:
157 stream = repr(procpass) +
"/" + shortStream
159 outputHanResultsDir = c.hanResultsDir + stream +
'/run_' + repr(runid)
160 outputHtmlDir = c.htmlDir + stream +
"/"
162 if c.server != []
or c.webHandoffDir !=
"" or c.eosResultsDir:
163 print(
"Writing all output to \'./\'; will copy at the end to ", end=
'')
164 if c.webHandoffDir !=
"":
165 print(
"a handoff directory:", c.webHandoffDir)
167 print(
"the web server(s):",
', '.join(c.server))
169 outputHanResultsDir =
"./han_results/" + stream +
'/run_' + repr(runid)
170 outputHtmlDir =
"./www/" + stream +
"/"
175 total=_local_apply(getHanResults, ( inputFilePath, outputHanResultsDir, inputFilePath, c.hcfg, c.hcfg_min10, c.hcfg_min30 ))
176 fileList=total.rsplit(
'\n')
177 if amitag
is not None:
181 if (len(fileList[number-1])<1):
185 runfile=fileList[0].rsplit()
186 if (len(runfile) == 0):
187 print(
"ERROR: TFile has no \"run_*\" directories. The input monitoring file is not organized for production use,")
188 print(
"probably because AthenaMonitoring is not configured properly. Exiting.\n")
192 for allLines
in fileList:
193 splitLine = allLines.rsplit()
194 if len(splitLine) >= 1:
195 xferFileList.append( splitLine[0] +
"\n" )
198 runNumber = runfile[1]
199 rN=runNumber.lstrip(
"run_")
200 if not runAccumulating:
201 print(
"Getting COOL authentications")
210 if 'COOLUPLOADS' in os.environ:
211 uploadAllowed = (os.environ[
'COOLUPLOADS'] ==
'1')
215 if not uploadAllowed:
216 print(
'hancool run and upload to DB switched off by request')
218 if (uploadAllowed
and c.dbConnection):
220 print(
"Now calling hancool ...")
222 if '_' in stream: stream = stream.split(
'_',1)[-1]
223 if amitag
is not None and 'x' in amitag
and stream.startswith(
'express'):
224 dbTagName = c.dbTagNameESn
227 dbTagName = c.dbTagName
231 uploadTag = dbTagName % {
'stream': stream,
233 'procpass': procpass }
236 uploadTag = dbTagName
237 doUpload = (
'-%s-' % stream
in uploadTag)
240 print(
'isESn?', isESn)
241 _local_apply(hancool, (int(rN),outputHanResultsDir,c.dbConnection,isESn))
246 for server
in c.server:
247 print(
"Transfering han files to server: ", server)
254 print(
"FAILED!", end=
'')
256 email(
'The transfer of han files\n\n' +
257 ''.join(xferFileList) +
258 '\nto server ' + server +
259 ' failed. This may indicate that this server is down.\n'
260 'Please investigate as soon as possible!',
261 'WARNING! File transfer from Tier-0 failed',
263 'hn-atlas-data-quality-operations@cern.ch'
265 print(
"Email sent...")
269 if failures == len(c.server):
270 print(
"SERIOUS PROBLEM: file transfers failed to ALL defined servers")
271 print(
"These are:",
', '.join(c.server))
272 print(
"Will die so as to alert Tier-0 shifter")
273 raise IOError(
'tarfile ssh transfer failed')
274 if c.eosResultsDir !=
"":
275 print(
"Transfering han files to EOS")
278 while failures < (eos_attempts+1) :
279 success_EOS =
transferFilesToEOS( xferFileList[:],
"./han_results/", c.eosResultsDir )
289 raise IOError(
"Transfer to /eos failed after {} attempts".format(failures))
291 email(
'The transfer of han files\n\n' +
292 ''.join(xferFileList) +
294 'Please investigate as soon as possible!',
295 'WARNING! File transfer from Tier-0 failed',
297 'hn-atlas-data-quality-operations@cern.ch'
299 print(
"Email sent...")
305 rundir=outputHtmlDir+runNumber+
"/"
309 now = time.localtime()
310 lastUpdate =
"Last Update: "+time.strftime(
'%Y-%m-%d %H:%M %Z', now)
313 g=open(outputHtmlDir+runNumber +
'/index.html',
'w')
314 g.write(
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
315 g.write(
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
317 g.write(
'<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
318 g.write(
'<title>run ' +rN+
' ' + stream +
'</title>\n')
319 g.write(
'<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
322 g.write(
'<font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font>\n')
323 g.write(
'<h1>Run '+rN+
', ' + stream +
'</h1>\n\n')
325 makeCSSFile( rundir,
"",
"" )
330 for x
in range(0,number):
331 sp=fileList[x].rsplit()
333 print(
"Running handi on " + sp[0] +
":")
334 print(
'handi("Run '+rN+
', '+ stream +
'",' + sp[0] +
','+rundir+
'/run)')
335 _local_apply(handiWithComparisons, ( (
'Run '+rN+
', ' + stream), sp[0], (rundir+
"/run"), runlistLoc, compare, browserMenu, allDirsScriptLoc) )
338 if sp[1].
find(
"lowStat")!=-1:
339 print(
"Running handi on " + sp[0] +
":")
340 print(
'handi("Run '+rN+
', '+sp[1]+
', ' + stream +
'",' + sp[0] +
','+rundir+sp[3]+
')')
341 _local_apply(handiWithComparisons, ( (
'Run '+rN+
', '+sp[1]+
', ' + stream), sp[0], (rundir+sp[3]), runlistLoc, compare, browserMenu, allDirsScriptLoc) )
343 mN = sp[1].removeprefix(
"lowStat_")
344 min10List.append( (sp[3], mN) )
345 elif sp[1].
find(
"medStat")!=-1:
346 print(
"Running handi on " + sp[0] +
":")
347 print(
'handi("Run '+rN+
', '+sp[1]+
', ' + stream +
'",' + sp[0] +
','+rundir+sp[3]+
')')
348 _local_apply(handiWithComparisons, ((
'Run '+rN+
', '+sp[1]+
', ' + stream), sp[0], (rundir+sp[3]), runlistLoc, compare, browserMenu, allDirsScriptLoc))
350 mN = sp[1].removeprefix(
"medStat_")
351 min30List.append( (sp[3], mN) )
358 if len(min10List) == 0
and len(min30List) == 0:
360 g.write(
' <td width=120>\n')
361 g.write(
' <a href="run/index.html">Entire Run</a>\n')
364 elif len(min10List) == 0
or len(min30List) == 0:
367 if len(min10List) == 0:
369 blockName =
"medium stat interval"
372 blockName =
"low stat interval"
374 g.write(
' <td rowspan='+ str(len(minList)) +
' valign="top" width=120>\n')
375 g.write(
' <a href="run/index.html">Entire Run</a>\n')
379 for page, nMin
in minList:
381 g.write(
' <td width=200>\n')
382 if nMin.find(
'merged_')!=-1:
383 g.write(
' <a href="' + page +
'/index.html">' + nMin +
'</a>\n')
385 g.write(
' <a href="' + page +
'/index.html">' + blockName +
' ' + nMin +
'</a>\n')
387 margin =
'</tr>\n<tr>\n'
391 g.write(
' <td rowspan='+ str(len(min10List)) +
' valign="top" width=120>\n')
392 g.write(
' <a href="run/index.html">Entire Run</a>\n')
397 for page10, nMin10
in min10List:
401 iMin30 = (count // 3)
402 page30, nMin30 = min30List[iMin30]
403 g.write(
' <td rowspan=3 valign="top" width=200>\n')
404 g.write(
' <a href="' + page30 +
'/index.html">medium stat interval ' + nMin30 +
'</a>\n')
406 g.write(
' <td width=200>\n')
407 g.write(
' <a href="' + page10 +
'/index.html">low stat interval ' + nMin10 +
'</a>\n')
410 margin =
'</tr>\n<tr>\n'
413 g.write(
'</table>\n')
416 g.write(
'<br/>\n<font class=\"Note\">'+lastUpdate+
'</font><br />\n')
417 g.write(
'</body>\n</html>')
420 if c.webHandoffDir !=
"":
421 print(
'Transfering web files to handoff directory')
425 for server
in c.server:
426 print(
"Transfering web files to server: ", server)
434 email(
'The transfer of web files\n'
436 '\nto server' + server +
437 'failed. This may indicate that this server is down.\n'
438 'Please investigate as soon as possible!',
439 'WARNING! File transfer from Tier-0 failed',
441 'hn-atlas-data-quality-operations@cern.ch'
445 if failures == len(c.server):
446 print(
"SERIOUS PROBLEM: web files transfer failed to ALL defined servers")
447 print(
"These are:",
', '.join(c.server))
448 print(
"Will die so as to alert Tier-0 shifter")
449 raise IOError(
'Directory ssh transfer failed')
454 if c.webHandoffDir ==
'':
455 print(
"Generating index files...")
456 for server
in c.server:
460 os.unlink(inputFilePath)
462 if instance
is not None:
484 print(
"Cannot use cache: No cache directory defined")
491 for i
in range(MAX_LOCK_TRIES):
493 lockfilename = os.path.join(cache,
'lock_%s_%s' % (run, stream))
494 instance = SingleAppInstance( lockfilename,
True )
495 islocked = instance.acquire()
496 except SingleAppInstance.FileLockAcquisitionError
as e:
497 print(
'Unable to start to acquire cache directory lock! Bailing')
502 print(
'Unable to acquire cache directory lock; waiting 60 seconds; try', (i+1))
506 raise LockAcquisitionException(
' '.join([
'Tried', repr(MAX_LOCK_TRIES),
'times to acquire cache lock; exiting now']))
508 cacheFile, version =
findCacheFile( inputFilePath, run, stream, cache )
511 print(
"Found cached histograms: ")
512 print(
" dir: ", cache)
513 print(
" file: ", cacheFile)
514 fullCachePath = cache +
"/" + cacheFile
516 print(
"Did not find cached histograms: ")
517 print(
" dir: ", cache)
519 inputFileName = inputFilePath
520 i = inputFilePath.rfind(
"/")
522 inputFileName = inputFilePath[i+1:]
523 updatedFile = inputFileName +
".CACHE_" + str(version+1)
524 print(
"Creating updated cache: ")
525 print(
" file: ", updatedFile)
526 fullUpdatedFile = cache +
"/" + updatedFile
529 if fullCachePath !=
'':
530 print(
'Copying previous cache to local directory ...', end=
'')
531 shutil.copy(fullCachePath, cacheFile)
534 mergeListName =
"cache_merge.list"
535 f = open( mergeListName,
'w' )
537 txtstr +=
"%s\n" % cacheFile
538 txtstr +=
"%s\n" % inputFilePath
542 print(
"Running DQHistogramMerge...")
544 print(
"Finished DQHistogramMerge.")
547 if fullCachePath !=
'':
548 print(
'Deleting local copy of old cache ...', end=
'')
552 print(
'Copying new cache to cache directory ...', end=
'')
553 shutil.copy(updatedFile, fullUpdatedFile)
563 os.unlink( mergeListName )
564 if fullCachePath !=
"":
565 os.unlink( fullCachePath )
569 print(
'Now running histogram postprocessing ...')
570 from DataQualityUtils
import DQPostProcessMod
571 DQPostProcessMod.DQPostProcess( updatedFile, isIncremental=
True )
612 import time, shutil, glob
613 import configparser
as configparser
614 targetfname = repr(int(time.time())) +
'-' + repr(os.getpid()) \
615 +
'-' + os.uname()[1] +
'.tgz'
616 targetfile = os.path.join(targetDir, targetfname)
618 print(
'Creating tarball', targetfname,
'...')
619 parser = configparser.ConfigParser()
620 parser.set(
'DEFAULT',
'target', config.htmlDir)
621 parser.add_section(
'execute')
622 parser.set(
'execute',
'command', config.htmlDir +
'/generateDQIndexFiles.py')
623 parser.set(
'execute',
'options',
'"%s" "%s" "%s" "%s" "%s"' % (config.htmlDir, config.config, config.indexFile, config.runlist, config.htmlWeb))
624 dnames = glob.glob(
'%s/*/*/*' % localDir)
626 print(
'Unexpected glob result')
628 parser.add_section(
'webdisplay')
629 parser.set(
'webdisplay',
'id', dnames[0][len(localDir):])
630 manifest = open(localDir +
'/MANIFEST',
'w')
631 parser.write(manifest); manifest.close()
638 print(
'About to execute', end=
'')
639 cmd =
'cd %s ; tar czf %s MANIFEST %s ; mv %s ..' % (localDir, targetfname, dirName.replace(localDir,
''), targetfname)
643 raise IOError(
'Unable to create tarfile')
647 print(
'Copying tarball to', targetDir,
'...', end=
'')
648 shutil.copy(targetfname, targetfile)
650 print(
'Removing local tarball copy ...', end=
'')
651 os.unlink(targetfname)