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