ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitProd/Processing/python/task.py
Revision: 1.12
Committed: Wed Jul 25 03:05:47 2012 UTC (12 years, 9 months ago) by paus
Content type: text/x-python
Branch: MAIN
CVS Tags: Mit_029_pre1
Changes since 1.11: +3 -1 lines
Log Message:
Preparing for new tag (Mit_029).

File Contents

# User Rev Content
1 paus 1.2 #---------------------------------------------------------------------------------------------------
2     # Python Module File to describe CRAB tasks and the corresponding job stati
3     #
4     # Author: C.Paus (Oct 10, 2008)
5     #---------------------------------------------------------------------------------------------------
6     import os,sys,getopt,re,string
7    
8 paus 1.7 def Domain():
9     domain = os.uname()[1]
10     f = domain.split('.')
11     return '.'.join(f[1:])
12    
13     #---------------------------------------------------------------------------------------------------
14     """
15     Class: Sample(cmsDataset='undefined',mitDataset='undefined',
16     localpath='undefined',status='undefined')
17     Each sample can be described through this class
18     """
19     #---------------------------------------------------------------------------------------------------
20     class Sample:
21     "Description of a datasample to be produced using CRAB"
22     cmsDataset = 'undefined'
23     mitDataset = 'undefined'
24     nEvents = 'undefined'
25     status = 'undefined'
26     localPath = 'undefined'
27     dbs = 'undefined'
28 paus 1.11 fixSites = 'undefined'
29 paus 1.7 #-----------------------------------------------------------------------------------------------
30     # constructor to connect with existing setup
31     #-----------------------------------------------------------------------------------------------
32     def __init__(self,cmsDataset='undefined',mitDataset='undefined',
33 paus 1.11 nEvents='undefined',status='undefined',localPath='undefined',dbs='undefined',
34     fixSites='undefined'):
35 paus 1.7 self.cmsDataset = cmsDataset
36     self.mitDataset = mitDataset
37     self.nEvents = nEvents
38     self.status = status
39     self.localPath = localPath
40     self.dbs = dbs
41 paus 1.11 self.fixSites = fixSites
42 paus 1.7
43     #-----------------------------------------------------------------------------------------------
44     # present the current samples
45     #-----------------------------------------------------------------------------------------------
46     def show(self):
47     print ' Dataset : ' + self.cmsDataset + ' (' + self.mitDataset + ')'
48     print ' NEvents : ' + self.nEvents
49     print ' Status : ' + self.status
50     print ' LocalPath: ' + self.localPath
51     print ' Dbs : ' + self.dbs
52 paus 1.11 print ' FixSites : ' + self.fixSites
53 paus 1.7
54 paus 1.11 def showFormat(self,f1,f2,f3,f4,f5,f6,f7):
55 paus 1.7 dbs = ''
56     if self.dbs != 'undefined':
57 paus 1.11 dbs += ' ' + self.dbs
58     fixSites = ''
59     if self.fixSites != 'undefined':
60     fixSites += ' ' + self.fixSites
61 paus 1.7 print self.cmsDataset.ljust(f1),self.mitDataset.ljust(f2),self.nEvents.ljust(f3),\
62 paus 1.11 self.status.ljust(f4),self.localPath.ljust(f5),dbs.ljust(f6),fixSites.ljust(f7)
63 paus 1.7
64 paus 1.2 #---------------------------------------------------------------------------------------------------
65     """
66     Class: SubTask(tag,)
67     Each SubTask in CRAB can be described through this class
68     """
69     #---------------------------------------------------------------------------------------------------
70     class SubTask:
71     "Description of a SubTask in CRAB"
72     # variable to be determined
73     index = -1
74     lfnFile = 'undefined' # file containing the LFNs to be processed
75     nSubTaskLfn = -1 # number of LFNs in this subtask
76     #-----------------------------------------------------------------------------------------------
77     # constructor to connect with existing setup
78     #-----------------------------------------------------------------------------------------------
79     def __init__(self,index,lfnFile):
80     self.index = index
81     self.lfnFile = lfnFile
82     self.nSubTaskLfn = 0
83    
84     #-----------------------------------------------------------------------------------------------
85     # present the current crab subtask
86     #-----------------------------------------------------------------------------------------------
87     def show(self):
88     print ' SubTask (Idx: %d, LfnFile: %s) ===='%(self.index,self.lfnFile)
89    
90     #-----------------------------------------------------------------------------------------------
91     # subtask tag
92     #-----------------------------------------------------------------------------------------------
93     def tag(self):
94     return "%04d"%self.index
95    
96     #---------------------------------------------------------------------------------------------------
97     """
98     Class: Task(tag,cmsDataset='undefined',mitCfg='undefined',mitVersion='undefined')
99     Each task in CRAB can be described through this class
100     """
101     #---------------------------------------------------------------------------------------------------
102     class Task:
103     "Description of a Task in CRAB"
104     # this is sufficient to do anything
105     tag = 'undefined'
106     # from actual crab configuration directly
107     storageEle = 'undefined'
108     storagePath = 'undefined'
109     cmsDataset = 'undefined'
110     nEvents = -1
111     nTotalEvts = -1
112     # MIT specific stuff
113     mitCfg = 'undefined'
114     mitVersion = 'undefined'
115     mitDataset = 'undefined'
116 paus 1.7 cmssw = 'undefined'
117 paus 1.2 localPath = 'undefined'
118 paus 1.7 dbs = 'undefined'
119 paus 1.11 fixSites = 'undefined'
120 paus 1.2 # status of task as a whole and each individual job
121     status = 'undefined' # 'undefined', ....
122     #
123     # 'undefined': initial status, not yet even checked
124     # 'cataloged': all jobs of the tasks have completed and are cataloged successfully
125     # 'completed': all jobs of the tasks have completed successfully
126     # 'finished' : all jobs have run, but unsubmitted jobs, errors or aborts might have occured
127     # 'active' : some jobs are either in Done, Running or to be Run
128     #
129     jobStati = []
130     failingSites = {}
131     lfns = {}
132     blocks = {}
133     # subtasks
134     nSubTaskLfnMax = 400 # maximum number of LFNs in a subtask
135     subTasks = [] # list of subtasks
136     #-----------------------------------------------------------------------------------------------
137     # constructor to connect with existing setup
138     #-----------------------------------------------------------------------------------------------
139 paus 1.7 def __init__(self,tag,cmsDataset='undefined',
140     mitDataset='undefined',mitCfg='undefined',mitVersion='undefined',
141     cmssw='undefined'):
142     self.tag = tag
143 paus 1.2 self.status = 'undefined'
144 paus 1.7
145 paus 1.2 if tag == 'new':
146 paus 1.7 self.new(cmsDataset,mitDataset,mitCfg,mitVersion,cmssw)
147 paus 1.2 elif not os.path.exists(tag):
148 paus 1.7 self.new(cmsDataset,mitDataset,mitCfg,mitVersion,cmssw)
149 paus 1.2 else:
150     cmd = 'cat ' + tag + '/share/crab.cfg | grep ^dataset| cut -d= -f2| tr -d \' \''
151     for line in os.popen(cmd).readlines(): # run command
152     self.cmsDataset = line[:-1] # strip '\n'
153     cmd = 'cat ' + tag + '/share/crab.cfg | grep ^storage_element| cut -d= -f2| tr -d \' \''
154     for line in os.popen(cmd).readlines(): # run command
155     self.storageEle = line[:-1] # strip '\n'
156     cmd = 'cat ' + tag + '/share/crab.cfg | grep ^storage_path| cut -d= -f2-3| tr -d \' \''
157     for line in os.popen(cmd).readlines(): # run command
158     self.storagePath = line[:-1] # strip '\n'
159     cmd = 'cat '+tag+'/share/crab.cfg | grep ^user_remote_dir| cut -d= -f2-3| tr -d \' \''
160     for line in os.popen(cmd).readlines(): # run command
161     self.storagePath += line[:-1] # strip '\n'
162     f = (self.storagePath).split('/')
163     if re.search('crab_0_',f[-1]):
164     self.mitDataset = f[-2]
165     self.mitVersion = f[-3]
166     self.mitCfg = f[-4]
167     else:
168     self.mitDataset = f[-1]
169     self.mitVersion = f[-2]
170     self.mitCfg = f[-3]
171    
172     #-----------------------------------------------------------------------------------------------
173     # constructor for new creation
174     #-----------------------------------------------------------------------------------------------
175 paus 1.7 def new(self,cmsDataset,mitDataset,mitCfg,mitVersion,cmssw):
176 paus 1.2 self.cmsDataset = cmsDataset
177 paus 1.7 self.mitDataset = mitDataset
178 paus 1.2 self.mitCfg = mitCfg
179     self.mitVersion = mitVersion
180 paus 1.7 self.cmssw = cmssw
181 paus 1.2 self.status = 'undefined'
182 paus 1.7
183 paus 1.2 # derive the missing parameters
184 paus 1.7 seFile = os.environ['MIT_PROD_DIR'] + '/' + mitCfg + '/'+ mitVersion + '/seTable'
185     if not os.path.exists(seFile):
186     cmd = "Storage element file not found: %s" % seFile
187 paus 1.2 raise RuntimeError, cmd
188     # resolve the other mitCfg parameters from the configuration file
189 paus 1.12 #cmd = 'cat ' + os.environ['MIT_PROD_DIR'] + '/' + \
190     # mitCfg + '/' + mitVersion + '/' + 'Productions' + '.' + self.cmssw
191     cmd = 'cat ' + './' + \
192 paus 1.7 mitCfg + '/' + mitVersion + '/' + 'Productions' + '.' + self.cmssw
193 paus 1.2 join = 0
194     fullLine = ""
195     bSlash = "\\";
196     for line in os.popen(cmd).readlines(): # run command
197     line = line[:-1]
198     # get ride of empty or commented lines
199     if line == '' or line[0] == '#':
200     continue
201     # join lines
202     if join == 1:
203     fullLine += line
204     else:
205     fullLine = line
206     # determine if finished or more is coming
207     if fullLine[-1] == bSlash:
208     join = 1
209     fullLine = fullLine[:-1]
210     else:
211     join = 0
212     # test whether there is a directory
213 paus 1.8 #-print ' Full line: ' + fullLine
214 paus 1.2 names = fullLine.split() # splitting every blank
215 paus 1.7 if names[0] == self.cmsDataset or names[1] == self.mitDataset:
216     self.cmsDataset = names[0] # CMS name of the dataset
217 paus 1.2 self.mitDataset = names[1] # the equivalent MIT name of the dataset
218     self.nEvents = int(names[2]) # number of events to be used in the production
219     if names[4] != "-":
220     self.localPath = names[4]
221     print "\n Sample Info: " + fullLine + "\n"
222 paus 1.7 print "\n Sample info from database Productions.%s\n %s"%(cmssw,fullLine)
223 paus 1.11 if len(names) >= 6:
224 paus 1.7 dbs = names[5]
225 paus 1.10 testDbs = 'wget http://cmsdbsprod.cern.ch/cms_dbs_' + dbs \
226     + '/servlet/DBSServlet >& /dev/null'
227     status = os.system(testDbs)
228     if status == 0:
229     self.dbs = 'http://cmsdbsprod.cern.ch/cms_dbs_' + dbs \
230     + '/servlet/DBSServlet'
231     else:
232     self.dbs = dbs
233 paus 1.7 print ' dbs: ' + self.dbs + '\n'
234 paus 1.11 if len(names) >= 7:
235     self.fixSites = names[6]
236 paus 1.7 else:
237     self.dbs = \
238     "http://cmsdbsprod.cern.ch/cms_dbs_prod_global/servlet/DBSServlet"
239     print ''
240    
241     # decide on the forseen default storage place (where are we running?)
242     storageTag = 'T2_US_MIT'
243     domain = Domain()
244     if re.search('mit.edu',domain):
245     storageTag = 'T2_US_MIT'
246     elif re.search('cern.ch',domain):
247     storageTag = 'T0_CH_CERN'
248     print ' Loading storage from local seTable: ' + storageTag
249     cmd = 'grep ^' + storageTag + ' ' + seFile
250 paus 1.2 for line in os.popen(cmd).readlines(): # run command
251 paus 1.7 #print ' LINE: ' + line
252     line = line[:-1] # strip '\n'
253     line = line.replace(' ','')
254     f = line.split(':')
255     self.storageEle = f[1]
256     self.storagePath = f[2]
257     userRemoteDir = f[3]
258     print ' Storage -- Ele: ' + self.storageEle \
259     + ' Path: ' + self.storagePath + ' UserDir: ' + userRemoteDir
260     self.storagePath += userRemoteDir \
261     + '/' + self.mitCfg + '/' + self.mitVersion + '/' + self.mitDataset
262 paus 1.2
263     #-----------------------------------------------------------------------------------------------
264     # present the current crab task
265     #-----------------------------------------------------------------------------------------------
266     def show(self):
267     print ' ==== CRAB Task Information (%s, %s, %s) ===='%(self.tag,self.mitCfg,self.mitVersion)
268     print ' Dataset: ' + self.cmsDataset + ' (' + self.mitDataset + ')'
269     print ' Storage: %s @ %s'%(self.storagePath,self.storageEle)
270     print ' List of sub tasks to be completed: '
271     for subTask in self.subTasks:
272     subTask.show()
273     print ' '
274    
275     #-----------------------------------------------------------------------------------------------
276     # create all subtasks of the tasks
277     #-----------------------------------------------------------------------------------------------
278     def createSubTasks(self,lfnFile):
279     print ' creating subtasks'
280     # loop through the missing lfn file and create subtasks each nSubTaskEvents
281     cmd = 'cat ' + lfnFile
282     iLine = 0
283     index = 0
284     output = open("/tmp/tmp.bak",'w')
285     for line in os.popen(cmd).readlines(): # run command
286     iLine += 1
287     # open file as needed
288     if iLine % self.nSubTaskLfnMax == 1:
289     if output:
290     output.close()
291     index += 1
292     file = lfnFile + '_%04d' % index
293     output = open(file,'w')
294     subTask = SubTask(index,file)
295     # add this subtaks to the list
296     self.subTasks.append(subTask)
297     # one more lfn entry for this sub task
298     output.write(line)
299     subTask.nSubTaskLfn += 1
300    
301     # closeup the last subtask
302     output.close()
303    
304     print ' '
305     self.show()
306    
307     #-----------------------------------------------------------------------------------------------
308     # load all lfns relevant to this task
309     #-----------------------------------------------------------------------------------------------
310     def loadAllLfns(self, lfnFile):
311     # initialize from scratch
312     self.lfns = {}
313     self.blocks = {}
314     self.nTotalEvts = 0
315     # use the complete lfn file list
316     cmd = 'cat ' + lfnFile
317     for line in os.popen(cmd).readlines(): # run command
318     line = line[:-1]
319     # get ride of empty or commented lines
320     if line == '' or line[0] == '#':
321     continue
322    
323     # decoding the input line
324     f = line.split() # splitting every blank
325     block = f[0]
326     file = f[1]
327     nEvents = int(f[2])
328     self.nTotalEvts += nEvents
329    
330     f = file.split('/')
331     file = f[-1]
332    
333 paus 1.4 if file in self.lfns.keys():
334     self.lfns[file] = 1
335     else:
336 paus 1.2 self.lfns[file] = 0
337    
338     if not self.blocks.get(block):
339     self.blocks[block] = 1
340     else:
341     self.blocks[block] += 1
342    
343     print ' TOTAL - Lfns: %6d [ Blocks: %4d Events: %9d ]'\
344     %(len(self.lfns),len(self.blocks),self.nTotalEvts)
345    
346     #-----------------------------------------------------------------------------------------------
347     # load all lfns so far completed relevant to this task
348     #-----------------------------------------------------------------------------------------------
349     def loadCompletedLfns(self):
350     # initialize from scratch
351     self.nLfnDone = 0
352     # find all already existing files
353     f = self.storagePath.split('=')
354     path = f[-1]
355     if re.search('crab_0_',path) or re.search('CRAB',path):
356     f = path.split('/')
357     f = f[:-1]
358     path = '/'.join(f)
359     cmd = 'list ' + path + ' | grep root 2> /dev/null'
360     for line in os.popen(cmd).readlines(): # run command
361     f = line.split()
362     file = f[1]
363 paus 1.4 if file in self.lfns.keys():
364     self.lfns[file] = 1
365     else:
366     print ' ERROR -- found completed lfn not in list of all lfns?! ->' + file + '<-'
367 paus 1.2 self.lfns[file] = 2
368     self.nLfnDone += 1
369 paus 1.9
370     # account for files already done in old storage location
371     if re.match('/mnt/hadoop',path):
372     oldpath = path.replace('/mnt/hadoop','/pnfs/cmsaf.mit.edu/t2bat')
373     cmd = 'list ' + oldpath + ' | grep root 2> /dev/null'
374     for line in os.popen(cmd).readlines(): # run command
375     f = line.split()
376     file = f[1]
377     if file in self.lfns.keys():
378     self.lfns[file] = 1
379     else:
380     print ' ERROR -- found completed lfn not in list of all lfns?! ->' + file + '<-'
381     self.lfns[file] = 2
382     self.nLfnDone += 1
383     # end of old storage location accounting #
384    
385 paus 1.2 print ' DONE - Lfns: %6d'%(self.nLfnDone)
386    
387     #-----------------------------------------------------------------------------------------------
388     # load all lfns relevant to this task
389     #-----------------------------------------------------------------------------------------------
390     def createMissingLfns(self, lfnFile, restLfnFile = "remaining.lfns"):
391     # fill the remaining lfns from complete database
392     self.status = 'cataloged'
393     self.nLfnMissing = 0
394     cmd = 'rm -rf ' + restLfnFile + '; touch ' + restLfnFile
395     os.system(cmd)
396     for lfn,status in self.lfns.iteritems():
397     if status == 0:
398     # add this lfn to the file
399     self.nLfnMissing += 1
400     cmd = 'grep ' + lfn + ' ' + lfnFile + ' >> ' + restLfnFile
401     os.system(cmd)
402     else:
403     self.status = 'undefined'
404    
405     # it is important to sort them (by first column == block)
406     cmd = 'sort -u ' + restLfnFile + ' > /tmp/cache' + ' ; mv /tmp/cache '+ restLfnFile
407     os.system(cmd)
408    
409     print ' MISSING - Lfns: %6d'%(self.nLfnMissing)
410    
411     #-----------------------------------------------------------------------------------------------
412     # create an inventory of all the existing output files
413     #-----------------------------------------------------------------------------------------------
414     def makeInventory(self):
415     castorPath = self.storagePath
416     f = castorPath.split("=")
417     castorPath = f[1]
418     #cmd = "srmls srm://" + self.storageEle + ":8443" + self.storagePath + " | grep " \
419     # + self.mitDataset + "_"
420     cmd = "list " + castorPath + " | grep root | cut -d ' ' -f2"
421    
422     print " cmd: " + cmd
423     for status in self.jobStati:
424     status.outputFile = 0
425     for line in os.popen(cmd).readlines(): # run directory list command
426     #print " line: " + line
427     line = line[:-1] # strip '\n'
428     f = line.split("_")
429     number = f.pop()
430 paus 1.6
431     # new crab (2_7_7 from 2_7_2) pop two more :-)
432     number = f.pop()
433     number = f.pop()
434    
435 paus 1.2 f = number.split(".")
436     number = int(f[0])
437     # update the job status
438     #print ' Index: %d >> %s'%(number,line)
439     if number-1 >= len(self.jobStati):
440     print ' Index out of range requested: %d Waiting for the CRASH!'%(number)
441     self.jobStati[number-1].outputFile = 1
442     #-----------------------------------------------------------------------------------------------
443     # get crab status information for each job in the task
444     #-----------------------------------------------------------------------------------------------
445     def getJobStati(self):
446     # Interact with crab to determine the present status of the jobs
447     pattern = 'Created'
448     # result = re.search(pattern,line)
449    
450     active = 0
451     self.jobStati = []
452     self.failingSites = {}
453     cmd = 'crab -status -continue ' + self.tag
454     #print 'Access Crab Job Stati, now!'
455     for line in os.popen(cmd).readlines(): # run command
456     line = line[:-1] # strip '\n'
457     if active == 0:
458     print ' CRAB: ' + line
459     else:
460     if not re.search(pattern,line) and not re.search('------',line):
461     print ' CRAB: ' + line
462    
463     #>> # compactify line
464     #>> line = " ".join(str(line).split()).strip()
465     #>> f = line.split(" ")
466     # decide whether we are in job status line or not
467     if line[1:5] == "----":
468     if active == 0:
469     active = 1 # print "Activated parsing"
470     continue
471     if active == 1 and line == '':
472     active = 0 # print "Deactivated parsing"
473     # parse the content of the job report
474     if active == 1:
475     #>> #print ' LINE: ' + line
476     #>> status = JobStatus(int(f[0]),f[1])
477     #>> if len(f) > 2:
478     #>> status.ce = f[2]
479     #>>
480     #>> if len(f) >= 2 and f[1] == 'Retrieved':
481     #>> if len(f) > 5:
482     #>> status.exitCode = int(f[3])
483     #>> status.exitStatus = int(f[4])
484    
485     # fixed column read
486 paus 1.6 ## # CRAB_2_7_2
487     ## ##ID STATUS E_HOST EXE_EXIT_CODE JOB_EXIT_STATUS
488     ## #lastChar = len(line)
489     ## #print 'Last Char: %d'%lastChar
490     ## iJob = int(line[0:5].strip())
491     ## sJob = line[7:24].strip()
492     ## status = JobStatus(iJob,sJob)
493     ## status.ce = line[26:61].strip()
494     ## tmp = line[63:75].strip()
495    
496     # CRAB_2_7_7
497     ##ID END STATUS ACTION ExeExitCode JobExitCode E_HOST
498     ##25 N Running SubSuccess llrcream.in2p3.fr
499 paus 1.2 #lastChar = len(line)
500     #print 'Last Char: %d'%lastChar
501     iJob = int(line[0:5].strip())
502 paus 1.6 sJob = line[10:27].strip()
503 paus 1.2 status = JobStatus(iJob,sJob)
504 paus 1.6 status.ce = line[65:].strip()
505     tmp = line[41:52].strip()
506    
507 paus 1.2 if tmp != '':
508     status.exitCode = int(tmp)
509 paus 1.6 tmp = line[53:64].strip()
510 paus 1.2 if tmp != '':
511     status.exitStatus = int(tmp)
512    
513     #print ' Appending: id %d array entry: %d '%(iJob,len(self.jobStati))
514     self.jobStati.append(status)
515    
516     # review job output so far
517     if len(self.jobStati) > 0:
518     self.makeInventory()
519     else:
520     print ' ERROR - This task has not jobs stati assigned to it. Something is wrong.'
521     print ' crab task id: ' + self.tag
522    
523    
524     # Make sure certain cases get fixed to avoid deletion
525     for status in self.jobStati:
526     # fix those jobs where the output has already been found
527     if status.exitStatus == 60303 and status.outputFile == 1:
528     status.exitStatus = 0
529     elif status.exitStatus == -1 and status.exitCode == -1 and status.outputFile == 1:
530     status.exitStatus = 0
531     status.exitCode = 0
532    
533     elif (status.exitStatus != 0 or status.exitCode != 0) and \
534     not (status.exitStatus == -1 and status.exitCode == -1):
535    
536     print " ==> Failure: filing with status/code: %d %d CE: %s" \
537     %(status.exitStatus,status.exitCode,status.ce)
538    
539     if status.ce in self.failingSites:
540     self.failingSites[status.ce] += 1
541     else:
542     self.failingSites[status.ce] = 1
543    
544     #print ' Dimension of Job Stati: %d'%(len(self.jobStati))
545    
546     # Loop through the job stati and determine the task status
547     # - check whether task is completed
548     active = 0
549     for status in self.jobStati:
550 paus 1.5 if status.tag != 'Aborted' and status.tag != 'Retrieved' and status.tag != 'Created' and status.tag != 'Cleared':
551 paus 1.2 active = 1
552     break
553     if active == 0:
554     self.status = 'completed'
555     for status in self.jobStati:
556     if status.tag == 'Aborted' or status.exitCode != 0 or status.exitStatus != 0:
557     self.status = 'finished'
558     break
559     else:
560     self.status = 'active'
561    
562    
563    
564     #-----------------------------------------------------------------------------------------------
565     # print the line to complete the task
566     #-----------------------------------------------------------------------------------------------
567     def complete(self):
568     print ' ./bin/submit.py --noTestJob --complete --version=008 --mitDataset=%s'% \
569     (self.mitDataset)
570    
571     #-----------------------------------------------------------------------------------------------
572     # print the line to remove the task and do it if requested
573     #-----------------------------------------------------------------------------------------------
574     def remove(self,clean=0):
575 paus 1.9 cmd = ' cleanupLog.py --crabId=' + self.tag + \
576 paus 1.2 '; mkdir -p ./completed; mv ' + self.tag + ' ./completed/'
577     print ' -> ' + cmd
578     if clean == 1:
579     os.system(cmd)
580    
581     #-----------------------------------------------------------------------------------------------
582     # print the line to remove the task and do it if requested
583     #-----------------------------------------------------------------------------------------------
584     def killAndRemove(self,clean=0):
585 paus 1.9 # kill the remaining jobs
586     cmd = 'crab -kill all -continue ' +self.tag
587 paus 1.2 print ' -> ' + cmd
588     if clean == 1:
589     os.system(cmd)
590 paus 1.9 # now remove the remainders
591 paus 1.11 self.remove(clean)
592 paus 1.2
593     #---------------------------------------------------------------------------------------------------
594     """
595     Class: JobStatus(index,tag)
596     The status of one job of a list of CRAB jobs (inside one task) is described by this class
597     """
598     #---------------------------------------------------------------------------------------------------
599     class JobStatus:
600     "Minimal but sufficient Job Status for crab operations"
601     index = -1
602     tag = 'undefined'
603     ce = 'undefined'
604     outputFile = -1
605     exitCode = -1
606     exitStatus = -1
607     #-----------------------------------------------------------------------------------------------
608     # constructor
609     #-----------------------------------------------------------------------------------------------
610     def __init__(self, index, tag):
611     self.index = index
612     self.tag = tag
613     #-----------------------------------------------------------------------------------------------
614     # present the current crab task in compact form
615     #-----------------------------------------------------------------------------------------------
616     def showCompact(self):
617     print 'Status: %6d %20s Output: %2d Exit: %6d,%6d at CE: %s'% \
618     (self.index,self.tag,self.outputFile,self.exitCode, \
619     self.exitStatus,self.ce)
620     #-----------------------------------------------------------------------------------------------
621     # present the current crab task in long form
622     #-----------------------------------------------------------------------------------------------
623     def show(self):
624     print '==== Job Status Information ===='
625     print ' Index: %6d Tag: %s CE: %s'%(self.index,self.tag,self.ce)
626     print ' Output: %2d Exit: %6d,%6d'%(self.outputFile,self.exitCode,self.exitStatus)