ATLAS Offline Software
taskman.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 
5 from __future__ import print_function
6 
7 """
8 taskman is a command line utility to run TaskManager functions.
9 """
10 __author__ = 'Juerg Beringer'
11 __version__ = 'taskman.py atlas/athena'
12 __usage__ = '''%prog [options] taskdbconn command [args ...]
13 
14 Commands are:
15 
16 init Create a new database
17 checkdb Check (and fix) sqlite database
18 checkdup Check task database for duplicate entries
19 debug Interactive debugging (EXPERTS ONLY!)
20 dump [DSNAME TASKNAME] Dump all or selected tasks in database
21 show DSNAME [TASKNAME] Show list of tasks
22 update Update information of ongoing tasks
23 update DSNAME TASKNAME Update information of selected tasks
24 rebuild [DSNAME TASKNAME] Rebuild missing or selected database entries from job files
25 import [DSNAME TASKNAME] DBCONN Import all or selected tasks from database DBCONN (duplicates not checked)
26 setstatus DSNAME TASKNAME STATUS Set status of selected tasks to STATUS
27 setfield DSNAME TASKNAME FIELDNAME VALUE Set database field to value (experts only!)
28 delete DSNAME TASKNAME Delete entry for selected task(s) (task files are NOT removed)
29 deleteResults DSNAME TASKNAME Delete postprocessing results for selected set of tasks
30 deleteTask DSNAME TASKNAME Delete task files and corresponding TaskManager entry
31  for a single task (will prompt for confirmation unless
32  option --batch is used)
33 '''
34 
35 import sys, os, stat
36 import pprint
38 from InDetBeamSpotExample.Utils import getRunFromName
39 
40 from future import standard_library
41 standard_library.install_aliases()
42 import subprocess
43 
44 
45 from optparse import OptionParser
46 parser = OptionParser(usage=__usage__, version=__version__)
47 #parser.add_option('-x', '--xxx', dest='xx', default='myvalue', help='sample option')
48 parser.add_option('-b', '--batch', dest='batch', action='store_true', default=False, help='batch mode - never ask for confirmation')
49 parser.add_option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='enable more verbose output for some commands')
50 parser.add_option('-n', '--nowildcards', dest='nowildcards', action='store_true', default=False, help='do not add wildcards when looking up dataset and task names')
51 parser.add_option('-d', '--dbconn', dest='dbconn', default='', help='task manager database connection string (default: check TASKDB, otherwise use sqlite_file:taskdata.db)')
52 parser.add_option('', '--proddir', dest='proddir', default='.', help='production directory (default: "."')
53 parser.add_option('-p', '--pretty', dest='pretty', action='store_true', default=None, help='try to nicely format output (default: auto)')
54 parser.add_option('', '--no-pretty', dest='pretty', action='store_false', help='do not attempt to format output')
55 parser.add_option('', '--runtaskname', dest='runtaskname', default='CB_BEAMSPOT', help='task name')
56 (options,args) = parser.parse_args()
57 
58 if len(args) < 1:
59  parser.error('wrong number of command line arguments')
60 cmd = args[0]
61 cmdargs = args[1:]
62 
63 proddir = options.proddir
64 if not os.path.exists(proddir):
65  sys.exit('ERROR: Job directory %s does not exist or is unreadable' % proddir)
66 
67 def getTaskManager(dbconn=None):
68  ''' Open task manager '''
69  dbconn = dbconn or options.dbconn
70  try:
71  return TaskManager(dbconn)
72  except:
73  print ('ERROR: Unable to access task manager database %s' % dbconn)
74  sys.exit(1)
75 
76 #
77 # Initialize a new task database
78 #
79 if cmd == 'init':
80  if cmdargs: parser.error('Command init does not take arguments')
81  try:
82  dbtype, dbname = TaskManager.parseConnectionInfo(options.dbconn)
83  except ValueError as e:
84  sys.exit('ERROR: {}'.format(e))
85  print ('Will initialise schema for database: {}:{}'.format(dbtype, dbname))
86 
87  print()
88  print ('Checking for existing database ...')
89  try:
90  with TaskManager(options.dbconn): pass
91  except ValueError as e:
92  print ('Test connection failed: {}'.format(e))
93  else:
94  print ('Test connection succeeded: the database already exists!')
95 
96  if not options.batch:
97  a = raw_input('\nRECREATING TASK DATABASE SCHEMA - ANY EXISTING DATA WILL BE ERASED!\n\nARE YOU REALLY ABSOLUTELY SURE [n] ? ')
98  if a != 'y': sys.exit('ERROR: Rebuilding aborted by user')
99  print()
100  with TaskManager(options.dbconn, createDatabase=True): pass
101  sys.exit(0)
102 
103 
104 #
105 # Check integrity of sqlite database and vacuum, if necessary
106 #
107 if cmd == 'checkdb':
108  if cmdargs: parser.error('Command checkdb does not take arguments')
109  try:
110  dbtype, dbfile = TaskManager.parseConnectionInfo(options.dbconn)
111  except ValueError:
112  sys.exit("ERROR: Illegal or empty/default database connection string - must provide explicity SQLite file reference")
113  if dbtype != 'sqlite_file':
114  sys.exit('ERROR: checkdb is only supported for SQLite databases')
115  if not os.path.exists(dbfile):
116  sys.exit('ERROR: SQLite file %s does not exist' % dbfile)
117 
118  (status, output) = subprocess.getstatusoutput("sqlite3 %s 'pragma integrity_check;'" % dbfile)
119  if status != 0:
120  sys.exit('ERROR: Error executing sqlite3 command')
121  if output != 'ok':
122  print ('ERROR: SQLite database file has errors:')
123  print (output)
124  print()
125 
126  if not options.batch:
127  a = raw_input('Do you want to try VACUUM [n] ? ')
128  if a != 'y':
129  sys.exit('\nERROR: VACUUM not executed - please fix database file manually')
130  (status, output) = subprocess.getstatusoutput("sqlite3 %s 'vacuum;'" % dbfile)
131  print (output)
132  if status != 0:
133  sys.exit('ERROR: VACUUM failed')
134 
135  (status, output) = subprocess.getstatusoutput("sqlite3 %s 'pragma integrity_check;'" % dbfile)
136  if status != 0 or output != 'ok':
137  print (output)
138  sys.exit('ERROR: Integrity check still failed - please check')
139  print ('INFO: SQLite file now passes integrity test (content may still have errors)')
140  sys.exit(2)
141 
142  print ('INFO: SQLite file {} ok'.format(dbfile))
143  sys.exit(0)
144 
145 
146 #
147 # Check database for duplicate entries and remove duplicates, if necessary
148 #
149 if cmd == 'checkdup':
150  if cmdargs: parser.error('Command checkdup does not take arguments')
151  #q = ['select dsname,taskname,count(*) from tasks group by dsname,taskname']
152  nDuplicates = 0
153  with getTaskManager() as taskman:
154  for t in taskman.taskIter('dsname,taskname,count(*)', ['group by dsname,taskname']):
155  if t[2] > 1:
156  nDuplicates += 1
157  print ('Duplicate task: {} / {}'.format(t[0], t[1]))
158  for d in taskman.taskIterDict(qual=[
159  'where DSNAME =', DbParam(t[0]),
160  'and TASKNAME =', DbParam(t[1]),
161  'order by taskid']):
162  print (' TASKID =', d['TASKID'])
163  print (nDuplicates, 'duplicates found')
164  sys.exit(0)
165 
166 
167 #
168 # Dump contents of task database
169 #
170 if cmd == 'dump':
171  if not cmdargs:
172  with getTaskManager() as taskman:
173  print (taskman.getNTasks(),'task(s) found:\n')
174  if options.pretty:
175  for t in taskman.taskIterDict():
176  print ('\n\nTask {} / {}:\n'.format(
177  t['DSNAME'],
178  t['TASKNAME']))
179  print (pprint.pformat(t))
180  else:
181  for t in taskman.taskIter():
182  print (t)
183  sys.exit(0)
184 
185  elif len(cmdargs) == 2:
186  dsname = cmdargs[0]
187  taskname = cmdargs[1]
188 
189  with getTaskManager() as taskman:
190  try:
191  taskList = getFullTaskNames(taskman, dsname, taskname,
192  addWildCards=not options.nowildcards)
193  except TaskManagerCheckError as e:
194  sys.exit(e)
195  for t in taskList:
196  taskEntry = taskman.getTaskDict(t[0], t[1])
197  if options.pretty is None or options.pretty:
198  print ('\n\nTask {} / {}:\n'.format(
199  taskEntry['DSNAME'],
200  taskEntry['TASKNAME']))
201  print (pprint.pformat(taskEntry))
202  else:
203  print (taskEntry)
204  sys.exit(0)
205 
206  else: parser.error('Command dump takes either 0 or 2 arguments')
207 
208 
209 #
210 # Show list of tasks
211 #
212 if cmd=='show' and (len(args)==2 or len(args)==3):
213  dsname = args[1]
214  taskname = args[2] if len(args)>2 else ''
215  try:
216  with getTaskManager() as taskman:
217  taskList = getFullTaskNames(taskman,dsname,taskname,addWildCards=not options.nowildcards)
218  print()
219  print (" %-50s %s" % ('DATASET NAME','TASK NAME'))
220  print (" %s" % (75*'-'))
221  for t in taskList:
222  print (" %-50s %s" % (t[0],t[1]) )
223  print ('\n%i task(s) found\n' % len(taskList))
224  sys.exit(0)
225  except TaskManagerCheckError as e:
226  print (e)
227  sys.exit(1)
228 
229 
230 #
231 # Update task database entries based on task files on disk
232 #
233 if cmd=='update' and len(args)==1:
234  if cmdargs: parser.error('Command update does not take any arguments')
235 
236  with getTaskManager() as taskman:
237  for t in taskman.taskIterDict('DSNAME,TASKNAME', [
238  'where STATUS < {:d} and ONDISK < {:d}'.format(
239  TaskManager.StatusCodes['POSTPROCESSING'],
240  TaskManager.OnDiskCodes['ARCHIVED'])]):
241  a = TaskAnalyzer(proddir, t['DSNAME'], t['TASKNAME'])
242  if a.analyzeFiles():
243  print ('Updating task {}/{}'.format(t['DSNAME'], t['TASKNAME']))
244  a.updateStatus(taskman)
245  else:
246  taskman.setDiskStatus(t['DSNAME'], t['TASKNAME'],
247  TaskManager.OnDiskCodes['DELETED'])
248  sys.exit(0)
249 
250 if cmd=='update' and len(args)==3:
251  with getTaskManager() as taskman:
252  try:
253  taskList = getFullTaskNames(taskman,args[1],args[2],confirmWithUser=not options.batch,addWildCards=not options.nowildcards)
254  except TaskManagerCheckError as e:
255  print (e)
256  sys.exit(1)
257  for t in taskList:
258  a = TaskAnalyzer(proddir,t[0],t[1])
259  if a.analyzeFiles():
260  print ('Updating task %s/%s' % (t[0],t[0]))
261  a.updateStatus(taskman)
262  else:
263  taskman.setDiskStatus(t[0],t[0],TaskManager.OnDiskCodes['DELETED'])
264  sys.exit(0)
265 
266 
267 #
268 # Rebuild task database entries based on task files on disk
269 #
270 if cmd == 'rebuild':
271  if len(cmdargs) == 2:
272  dsname = cmdargs[0]
273  taskname = cmdargs[1]
274  taskpath = os.path.join(proddir, dsname, taskname)
275  elif not cmdargs:
276  taskpath = os.path.join(proddir, '*', '*')
277  else:
278  parser.error('Command rebuild takes 0 or 2 arguments')
279 
280  print ('Will reconstruct database from directory: {}'.format(taskpath))
281  print()
282 
283  with getTaskManager() as taskman:
284  dirs = []
285  if not options.batch:
286  print ('Rebuilding the following tasks:')
287  print()
288  print ( ' DB {:50} {}'.format('DATASET NAME','TASK NAME'))
289  print (' {}'.format(85 * '-'))
290  for p in glob.glob(taskpath):
291  if not os.path.isdir(p): continue
292  (dsName, taskName) = p.split('/')[-2:]
293  nDefined = taskman.getNTasks([
294  'where DSNAME=', DbParam(dsName),
295  'and TASKNAME=', DbParam(taskName)])
296  dirs.append((dsName, taskName, nDefined))
297 
298  if nDefined == 0:
299  print (' {:50} {}'.format(dsName, taskName))
300  elif options.verbose:
301  print (' * {:50} {}'.format(dsName, taskName))
302 
303  a = raw_input('\nARE YOU SURE [n] ? ')
304  if a != 'y':
305  sys.exit('ERROR: Rebuilding aborted by user')
306  print()
307 
308  for (dsName, taskName, nDefined) in dirs:
309  if nDefined == 0:
310  print ('Adding missing entry for task {}/{}'.format(dsName, taskName))
311  configFile = glob.glob(os.path.join(proddir, dsName, taskName, '*', '*.config.py'))
312  if configFile:
313  mtime = os.stat(configFile[0])[stat.ST_MTIME]
314  config = {}
315  exec(compile(open(configFile[0]).read()), config)
316  try:
317  template = config['jobConfig']['joboptionpath']
318  except KeyError:
319  template = 'UNKNOWN'
320  try:
321  release = config['jobConfig']['release']
322  except KeyError:
323  release = 'UNKNOWN'
324  try:
325  taskpostprocsteps = config['jobConfig']['taskpostprocsteps']
326  except KeyError:
327  taskpostprocsteps = ''
328  try:
329  comment = config['jobConfig']['comment'] + ' (rebuilt from config file)'
330  except KeyError:
331  comment = 'rebuilt from config file'
332  taskman.addTask(dsName, taskName, template, release, 0, taskpostprocsteps,
333  createdTime=mtime,
334  createdUser='UNKNOWN',
335  createdHost='UNKNOWN',
336  comment=comment)
337  else:
338  print ('WARNING: no config file found, unable to determine task creation time and configuration details')
339  # Should we still add such a task - most likely this is a directory of files, e.g. some AOD or ESD files
340  taskman.addTask(dsName, taskName, 'UNKNOWN', 'UNKNOWN', 0,
341  comment='rebuilt, no config file found')
342  a = TaskAnalyzer(proddir, dsName, taskName)
343  a.analyzeFiles()
344  a.updateStatus(taskman)
345  elif nDefined == 1:
346  print ('Entry exists already for task {}/{} - SKIPPED'.format(dsName, taskName))
347  elif nDefined > 1:
348  print ('ERROR: {:d} conflicting task entries for task {}/{} - SKIPPED'.format(nDefined, dsName, taskName))
349  sys.exit(0)
350 
351 
352 #
353 # Import tasks from another task database
354 #
355 if cmd == 'import':
356  if len(cmdargs) == 1:
357  fromDbconn = cmdargs[0]
358  qual = []
359  elif len(cmdargs) == 3:
360  dsname = cmdargs[0]
361  taskname = cmdargs[1]
362  fromDbconn = cmdargs[2]
363 
364  # Convert a minimal shell glob syntax into an SQL query:
365  import string
366  wildcards = string.maketrans('*?', '%_')
367  qual = []
368  if '*' in dsname or '?' in dsname:
369  qual.append("where DSNAME like '{}'".format(dsname.translate(wildcards)))
370  else:
371  qual.extend(['where DSNAME =', DbParam(dsname)])
372  if '*' in taskname or '?' in taskname:
373  qual.append("and TASKNAME like '{}'".format(taskname.translate(wildcards)))
374  else:
375  qual.extend(['and TASKNAME =', DbParam(taskname)])
376  else:
377  parser.error('Command import takes 1 or 3 arguments')
378 
379  try:
380  destDbtype, destDbname = TaskManager.parseConnectionInfo(options.dbconn)
381  fromDbtype, fromDbname = TaskManager.parseConnectionInfo(fromDbconn)
382  except ValueError as e:
383  sys.exit('ERROR: Bad database connection string {}'.format(e))
384  print()
385  print ('Import from: {}:{}'.format(fromDbtype, fromDbname))
386  print ('Import into: {}:{}'.format(destDbtype, destDbname))
387  print()
388 
389  with getTaskManager() as taskman:
390  with getTaskManager(fromDbconn) as fromman:
391  nImported = 0
392  qual.append('order by RUNNR desc')
393  for t in fromman.taskIterDict(qual=qual):
394  print ('Importing ', t['DSNAME'], '/' , t['TASKNAME'], '...')
395  if not 'RUNNR' in t.keys():
396  # Fill run number from DSNAME
397  t['RUNNR'] = getRunFromName(t['DSNAME'], None, True)
398  if not t.get('RESULTLINKS'):
399  # Rebuild old result files and links
400  links = ''
401  files = t.get('RESULTFILES','')
402  if files==None:
403  files = ''
404  dsname = t['DSNAME']
405  taskname = t['TASKNAME']
406  summaryFiles = glob.glob('%s/%s/*beamspot.gif' % (dsname,taskname))
407  if len(summaryFiles)>0:
408  for r in summaryFiles:
409  f = r.split('/')[-1]
410  pdf = f[:-3]+'pdf'
411  if not f in files.split():
412  files = ' '.join([files,f])
413  if not pdf in files.split():
414  files = ' '.join([files,pdf])
415  links += ' <a href="../files?u=%s/%s/%s">summary</a>' %(dsname,taskname,f)
416  links += ' (<a href="/jobfiles/%s/%s/%s">pdf</a>)' %(dsname,taskname,pdf)
417  monitoringFiles = glob.glob('%s/%s/*beamspotmon.gif' % (dsname,taskname))
418  if len(monitoringFiles)>0:
419  for r in monitoringFiles:
420  f = r.split('/')[-1]
421  pdf = f[:-3]+'pdf'
422  if not f in files.split():
423  files = ' '.join([files,f])
424  if not pdf in files.split():
425  files = ' '.join([files,pdf])
426  links += ' <a href="../files?u=%s/%s/%s">monitoring</a>' %(dsname,taskname,f)
427  links += ' (<a href="/jobfiles/%s/%s/%s">pdf</a>)' %(dsname,taskname,pdf)
428  t['RESULTFILES'] = files
429  t['RESULTLINKS'] = links
430 
431  fieldNameString = ''
432  params = []
433  for fieldName in t.keys():
434  newFieldName = fieldName
435  if fieldName == 'TASKID':
436  continue # Skip old primary key
437  elif fieldName == 'COMMENT':
438  newFieldName = 'TASKCOMMENT'
439  if params:
440  fieldNameString += ','
441  params.append(',')
442  fieldNameString += newFieldName
443  params.append(DbParam(t[fieldName]))
444  q = [ 'insert into TASKS (%s) values (' % fieldNameString ]
445  q.extend(params)
446  q.append(')')
447  taskman.execute(q, True)
448  nImported += 1
449  print()
450  print ('{:d} tasks imported'.format(nImported))
451  sys.exit(0)
452 
453 
454 #
455 # Set task status
456 #
457 if cmd == 'setstatus':
458  if len(cmdargs) != 3: parser.error('Command setstatus takes 3 arguments')
459  dsname = cmdargs[0]
460  taskname = cmdargs[1]
461  statusName = cmdargs[2].upper()
462 
463  status = TaskManager.StatusCodes.get(statusName)
464  if status:
465  print ('Setting task status to {} (code {:d})'.format(statusName,status))
466  else:
467  sys.exit('ERROR: Illegal status code name {}'.format(statusName))
468  print()
469 
470  with getTaskManager() as taskman:
471  try:
472  taskList = getFullTaskNames(taskman, dsname, taskname,
473  confirmWithUser=not options.batch,
474  addWildCards=not options.nowildcards)
475  except TaskManagerCheckError as e:
476  sys.exit(e)
477 
478  n = 0
479  for t in taskList:
480  n += taskman.setValue(t[0], t[1], 'STATUS', status)
481  print ('%i task status entries updated\n' % (n))
482  sys.exit(0)
483 
484 
485 #
486 # Set database field
487 #
488 if cmd == 'setfield':
489  if len(cmdargs) != 4: parser.error('Command setfield takes 4 arguments')
490  dsname = cmdargs[0]
491  taskname = cmdargs[1]
492  fieldName = cmdargs[2].upper()
493  fieldValue = cmdargs[3]
494 
495  print ('Setting field %s to: %s' % (fieldName,fieldValue))
496  print()
497  with getTaskManager() as taskman:
498  try:
499  [(dsname,task)] = getFullTaskNames(taskman, dsname, taskname,
500  requireSingleTask=True,
501  confirmWithUser=not options.batch,
502  addWildCards=not options.nowildcards)
503  except TaskManagerCheckError as e:
504  sys.exit(e)
505  n = taskman.setValue(dsname,task,fieldName,fieldValue)
506  print ('{:d} task status entries updated'.format(n))
507  sys.exit(0)
508 
509 
510 #
511 # Delete task entry
512 #
513 if cmd=='delete' and len(args)==3:
514  with getTaskManager() as taskman:
515  try:
516  taskList = getFullTaskNames(taskman,args[1],args[2],confirmWithUser=not options.batch,addWildCards=not options.nowildcards)
517  except TaskManagerCheckError as e:
518  print (e)
519  sys.exit(1)
520  n = 0
521  for t in taskList:
522  n += taskman.deleteTask(t[0],t[1])
523  print ('\n%i task entries deleted\n' % (n))
524  sys.exit(0)
525 
526 # List results for selected sets of tasks
527 #
528 if cmd=='listResults' and len(args)==3:
529  with getTaskManager() as taskman:
530  try:
531  taskList = getFullTaskNames(taskman,args[1],args[2],confirmWithUser=not options.batch,addWildCards=not options.nowildcards)
532  except TaskManagerCheckError as e:
533  print (e)
534  sys.exit(1)
535  for t in taskList:
536  print ('Listing results for task %s/%s ...' % (t[0],t[1]) )
537  print (taskman.getTaskValue(t[0],t[1],'RESULTFILES'))
538  print (taskman.getTaskValue(t[0],t[1],'RESULTLINKS'))
539  sys.exit(0)
540 
541 
542 #
543 # Clear results for selected sets of tasks
544 # TODO: remove associated files as well (?)
545 #
546 if cmd=='deleteResults' and len(args)==3:
547  with getTaskManager() as taskman:
548  try:
549  taskList = getFullTaskNames(taskman,args[1],args[2],confirmWithUser=not options.batch,addWildCards=not options.nowildcards)
550  except TaskManagerCheckError as e:
551  print (e)
552  sys.exit(1)
553  for t in taskList:
554  print ('Deleting results for task %s/%s ...' % (t[0],t[1]) )
555  taskman.setValue(t[0],t[1],'RESULTFILES','')
556  taskman.setValue(t[0],t[1],'RESULTLINKS','')
557  sys.exit(0)
558 
559 
560 #
561 # Delete task (files and associated TaskManager entry)
562 #
563 if cmd=='deleteTask' and len(args)==3:
564  with getTaskManager() as taskman:
565  try:
566  [(dsname,task)] = getFullTaskNames(taskman,args[1],args[2],confirmWithUser=not options.batch,requireSingleTask=True,addWildCards=not options.nowildcards)
567  except TaskManagerCheckError as e:
568  print (e)
569  sys.exit(1)
570  dir = '/'.join([proddir,dsname,task])
571  print()
572  if os.path.exists(dir):
573  os.system('du -hs %s' % dir)
574  else:
575  print ('No task files found (no directory %s)' % dir)
576  if not options.batch:
577  a = input('\nDeleteing task entry and all files - ARE YOU SURE [n] ? ')
578  if a!='y':
579  print ("ERROR: Deletion aborted by user.")
580  sys.exit(1)
581  n = taskman.deleteTask(dsname,task)
582  print ('\n%i task entry deleted.' % (n))
583  print ('Deleting ',dir,' ...')
584  os.system('rm -rf %s' % dir)
585  sys.exit(0)
586 
587 if cmd=='deleteTask' and len(args)==2:
588  dsname = args[1]
589  taskname = ''
590  with getTaskManager() as taskman:
591  try:
592  taskList = getFullTaskNames(taskman,dsname,taskname,addWildCards=not options.nowildcards)
593  except TaskManagerCheckError as e:
594  print (e)
595  sys.exit(1)
596  print()
597  # print (" %-50s %s" % ('DATASET NAME','TASK NAME'))
598  # print (" %s" % (75*'-'))
599  # for t in taskList:
600  # print (" %-50s %s" % (t[0],t[1]) )
601  print ('\n%i task(s) found\n' % len(taskList))
602  n = 0
603  for t in taskList:
604  taskname = t[1]
605  print (" %-50s %s" % (dsname,taskname) )
606  dir = '/'.join([proddir,dsname,taskname])
607  print()
608  if os.path.exists(dir):
609  os.system('du -hs %s' % dir)
610  else:
611  print ('No task files found (no directory %s)' % dir)
612  if not options.batch:
613  a = input('\nDeleteing task entry and all files - ARE YOU SURE [n] ? ')
614  if a!='y':
615  print ("ERROR: Deletion aborted by user.")
616  sys.exit(1)
617  n += taskman.deleteTask(dsname,taskname)
618  print ('Deleting ',dir,' ...')
619  os.system('rm -rf %s' % dir)
620  print ('\n%i tasks deleted.' % (n))
621  sys.exit(0)
622 
623 if cmd=='notifyFailed' and len(args)<3:
624  if len(args)==2:
625  earliestUpdateTime = time.time()-float(args[1])
626  else:
627  earliestUpdateTime = 0
628 
629  taskList = []
630  with getTaskManager() as taskman:
631  for t in taskman.taskIterDict('*',["where TASKNAME like '%%%s%%'" % options.runtaskname,
632  "and UPDATED >= ", DbParam(earliestUpdateTime),
633  "and (STATUS = %i or STATUS = %i)" %(TaskManager.StatusCodes['FAILED'], TaskManager.StatusCodes['POSTPROCFAILED']),
634  "order by RUNNR desc"]):
635 
636  # Change status to string version
637  t['STATUS'] = [k for k, v in TaskManager.StatusCodes.items() if v == t['STATUS']][0]
638  taskList.append(t)
639 
640  if taskList:
641 
642  dsWidth = len(max([t['DSNAME'] for t in taskList],key=len))
643  taskWidth = len(max([t['TASKNAME'] for t in taskList],key=len))
644  statusWidth = len(max([t['STATUS'] for t in taskList],key=len))
645 
646  bodyFormat = '%%(DSNAME)%ss %%(TASKNAME)%ss %%(STATUS)%ss' %(dsWidth, taskWidth, statusWidth)
647 
648  mailBody = 'The following %s tasks have reported failures' % len(taskList)
649  if len(args)==2:
650  hours = round(float(args[1])/3600.)
651  mailBody += ' in the last %s hours' % hours
652  mailBody += ':\n\n'
653  mailBody += '\n'.join([bodyFormat % t for t in taskList])
654  stat = os.system('source /afs/cern.ch/user/a/atlidbs/cron/mailwrapper; mailwrapper "[atlidbs] %s tasks report failures" "%s"' %(len(taskList), mailBody)) >> 8
655 
656  if stat:
657  print ('\nERROR: Unable to send mail\n')
658 
659  sys.exit(0)
660 
661 #
662 # Debugging (for experts only!)
663 #
664 # This must be the last command. If we end up here, it's either debugging
665 # or an illegal command.
666 #
667 if cmd=='debug' and len(args)==1:
668  taskman = getTaskManager()
669  taskman.debug = True
670  os.environ['PYTHONINSPECT'] = '1'
671  print()
672  print ('Entering python shell. taskman is the TaskManager object. Be careful!')
673  print()
674 else:
675  print ('ERROR: Illegal command or number of arguments')
676  sys.exit(1)
read
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
Definition: openCoraCool.cxx:569
max
#define max(a, b)
Definition: cfImp.cxx:41
vtune_athena.format
format
Definition: vtune_athena.py:14
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
upper
int upper(int c)
Definition: LArBadChannelParser.cxx:49
python.Utils.getRunFromName
def getRunFromName(name, default='', asInt=False)
Definition: InnerDetector/InDetExample/InDetBeamSpotExample/python/Utils.py:13
TaskManager
LArG4FSStartPointFilter.exec
exec
Definition: LArG4FSStartPointFilter.py:103
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
python.TaskManager.getFullTaskNames
def getFullTaskNames(taskman, dsname, taskname, requireSingleTask=False, confirmWithUser=False, addWildCards=True)
Definition: TaskManager.py:74
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
taskman.getTaskManager
def getTaskManager(dbconn=None)
Definition: taskman.py:67
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
readCCLHist.float
float
Definition: readCCLHist.py:83