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