ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/crab.py
Revision: 1.41
Committed: Thu Dec 15 14:38:33 2005 UTC (19 years, 4 months ago) by spiga
Content type: text/x-python
Branch: MAIN
Changes since 1.40: +1 -1 lines
Log Message:
crab submit bug fixed

File Contents

# User Rev Content
1 slacapra 1.27 #!/usr/bin/env python2.2
2 nsmirnov 1.1 from crab_help import *
3     from crab_util import *
4     from crab_exceptions import *
5     from crab_logger import Logger
6     from WorkSpace import WorkSpace
7     from JobDB import JobDB
8 nsmirnov 1.3 from JobList import JobList
9 nsmirnov 1.1 from Creator import Creator
10     from Submitter import Submitter
11 slacapra 1.8 from Checker import Checker
12 slacapra 1.9 from PostMortem import PostMortem
13     from Status import Status
14 spiga 1.16 from StatusBoss import StatusBoss
15 slacapra 1.36 from Cleaner import Cleaner
16 nsmirnov 1.1 import common
17 spiga 1.13 import Statistic
18 nsmirnov 1.1
19     import sys, os, time, string
20    
21     ###########################################################################
22     class Crab:
23 nsmirnov 1.3 def __init__(self, opts):
24 nsmirnov 1.1
25     # The order of main_actions is important !
26 slacapra 1.28 self.main_actions = [ '-create', '-submit' ]
27 slacapra 1.8 self.aux_actions = [ '-list', '-kill', '-status', '-getoutput',
28 slacapra 1.28 '-resubmit' , '-cancelAndResubmit', '-testJdl', '-postMortem', '-clean']
29 nsmirnov 1.1
30     # Dictionary of actions, e.g. '-create' -> object of class Creator
31     self.actions = {}
32    
33     # Configuration file
34     self.cfg_fname = None
35     # Dictionary with configuration parameters
36     self.cfg_params = {}
37    
38     # Current working directory
39     self.cwd = os.getcwd()+'/'
40     # Current time in format 'yymmdd_hhmmss'
41     self.current_time = time.strftime('%y%m%d_%H%M%S',
42     time.localtime(time.time()))
43    
44 nsmirnov 1.3 # Session name (?) Do we need this ?
45 nsmirnov 1.1 self.name = '0'
46    
47     # Job type
48     self.job_type_name = None
49    
50     # Continuation flag
51     self.flag_continue = 0
52    
53     # quiet mode, i.e. no output on screen
54     self.flag_quiet = 0
55     # produce more output
56     self.debug_level = 0
57    
58 nsmirnov 1.3 # Scheduler name, e.g. 'edg', 'lsf'
59 fanzago 1.14 self.scheduler_name = ''
60 nsmirnov 1.1
61 nsmirnov 1.3 self.initialize_(opts)
62 nsmirnov 1.1
63     return
64    
65 nsmirnov 1.7 def version():
66 nsmirnov 1.1 return common.prog_version_str
67    
68 nsmirnov 1.7 version = staticmethod(version)
69    
70 nsmirnov 1.3 def initialize_(self, opts):
71 nsmirnov 1.1
72     # Process the '-continue' option first because
73     # in the case of continuation the CRAB configuration
74     # parameters are loaded from already existing Working Space.
75 nsmirnov 1.3 self.processContinueOption_(opts)
76 nsmirnov 1.1
77     # Process ini-file first, then command line options
78     # because they override ini-file settings.
79    
80 nsmirnov 1.3 self.processIniFile_(opts)
81 nsmirnov 1.1
82 nsmirnov 1.3 if self.flag_continue: opts = self.loadConfiguration_(opts)
83 nsmirnov 1.1
84 nsmirnov 1.3 self.processOptions_(opts)
85 nsmirnov 1.1
86     if not self.flag_continue:
87 nsmirnov 1.3 self.createWorkingSpace_()
88 slacapra 1.9 optsToBeSaved={}
89     for it in opts.keys():
90     if (it in self.main_actions) or (it in self.aux_actions) or (it == '-debug'):
91     pass
92     else:
93     optsToBeSaved[it]=opts[it]
94     common.work_space.saveConfiguration(optsToBeSaved, self.cfg_fname)
95 nsmirnov 1.1 pass
96    
97     # At this point all configuration options have been read.
98    
99     args = string.join(sys.argv,' ')
100 slacapra 1.11
101 nsmirnov 1.3 self.updateHistory_(args)
102 slacapra 1.11
103 nsmirnov 1.3 self.createLogger_(args)
104 slacapra 1.11
105 nsmirnov 1.1 common.jobDB = JobDB()
106 slacapra 1.11
107 nsmirnov 1.3 if self.flag_continue:
108 slacapra 1.12 try:
109     common.jobDB.load()
110     common.logger.debug(6, str(common.jobDB))
111     except DBException,e:
112     pass
113 nsmirnov 1.3 pass
114 slacapra 1.11
115 nsmirnov 1.3 self.createScheduler_()
116 slacapra 1.11
117 nsmirnov 1.3 if common.logger.debugLevel() >= 6:
118     common.logger.debug(6, 'Used properties:')
119     keys = self.cfg_params.keys()
120     keys.sort()
121     for k in keys:
122     if self.cfg_params[k]:
123     common.logger.debug(6, ' '+k+' : '+self.cfg_params[k])
124     pass
125     else:
126     common.logger.debug(6, ' '+k+' : ')
127     pass
128     pass
129     common.logger.debug(6, 'End of used properties.\n')
130     pass
131     self.initializeActions_(opts)
132 nsmirnov 1.1 return
133    
134 nsmirnov 1.3 def processContinueOption_(self,opts):
135 nsmirnov 1.1
136     continue_dir = None
137 nsmirnov 1.4
138     # Look for the '-continue' option.
139    
140 nsmirnov 1.1 for opt in opts.keys():
141     if ( opt in ('-continue','-c') ):
142     self.flag_continue = 1
143     val = opts[opt]
144     if val:
145     if val[0] == '/': continue_dir = val # abs path
146     else: continue_dir = self.cwd + val # rel path
147     pass
148 nsmirnov 1.4 break
149     pass
150    
151     # Look for actions which has sense only with '-continue'
152    
153     if not self.flag_continue:
154     for opt in opts.keys():
155 slacapra 1.6 if ( opt in (self.aux_actions) ):
156 nsmirnov 1.4 self.flag_continue = 1
157     break
158 nsmirnov 1.1 pass
159     pass
160 slacapra 1.6 submit_flag=0
161     create_flag=0
162     for opt in opts.keys():
163     if opt == "-submit": submit_flag=1
164     if opt == "-create": create_flag=1
165     pass
166     if (submit_flag and not create_flag):
167 nsmirnov 1.7 msg = "'-submit' must be used with either '-create' or '-continue'."
168     raise CrabException(msg)
169 slacapra 1.6 pass
170 nsmirnov 1.1
171     if not self.flag_continue: return
172    
173     if not continue_dir:
174     prefix = common.prog_name + '_' + self.name + '_'
175     continue_dir = findLastWorkDir(prefix)
176     pass
177    
178     if not continue_dir:
179     raise CrabException('Cannot find last working directory.')
180    
181     if not os.path.exists(continue_dir):
182     msg = 'Cannot continue because the working directory <'
183     msg += continue_dir
184     msg += '> does not exist.'
185     raise CrabException(msg)
186    
187     # Instantiate WorkSpace
188     common.work_space = WorkSpace(continue_dir)
189    
190     return
191    
192 nsmirnov 1.3 def processIniFile_(self, opts):
193 nsmirnov 1.1 """
194     Processes a configuration INI-file.
195     """
196    
197     # Extract cfg-file name from the cmd-line options.
198    
199     for opt in opts.keys():
200     if ( opt == '-cfg' ):
201     if self.flag_continue:
202     raise CrabException('-continue and -cfg cannot coexist.')
203     if opts[opt] : self.cfg_fname = opts[opt]
204     else : usage()
205     pass
206    
207     elif ( opt == '-name' ):
208     self.name = opts[opt]
209     pass
210    
211     pass
212    
213     # Set default cfg-fname
214    
215     if self.cfg_fname == None:
216     if self.flag_continue:
217     self.cfg_fname = common.work_space.cfgFileName()
218     else:
219     self.cfg_fname = common.prog_name+'.cfg'
220     pass
221     pass
222    
223     # Load cfg-file
224    
225     if string.lower(self.cfg_fname) != 'none':
226     if os.path.exists(self.cfg_fname):
227     self.cfg_params = loadConfig(self.cfg_fname)
228     pass
229     else:
230     msg = 'cfg-file '+self.cfg_fname+' not found.'
231     raise CrabException(msg)
232     pass
233     pass
234    
235     # process the [CRAB] section
236    
237     lhp = len('CRAB.')
238     for k in self.cfg_params.keys():
239     if len(k) >= lhp and k[:lhp] == 'CRAB.':
240     opt = '-'+k[lhp:]
241     if len(opt) >= 3 and opt[:3] == '-__': continue
242     if opt not in opts.keys():
243     opts[opt] = self.cfg_params[k]
244     pass
245     pass
246     pass
247    
248     return
249    
250 nsmirnov 1.3 def processOptions_(self, opts):
251 nsmirnov 1.1 """
252     Processes the command-line options.
253     """
254    
255     for opt in opts.keys():
256     val = opts[opt]
257    
258 nsmirnov 1.3 # Skip actions, they are processed later in initializeActions_()
259     if opt in self.main_actions:
260     self.cfg_params['CRAB.'+opt[1:]] = val
261     continue
262     if opt in self.aux_actions:
263     self.cfg_params['CRAB.'+opt[1:]] = val
264     continue
265 nsmirnov 1.1
266    
267     elif ( opt == '-cfg' ):
268     pass
269    
270     elif ( opt in ('-continue', '-c') ):
271 nsmirnov 1.4 # Already processed in processContinueOption_()
272 nsmirnov 1.1 pass
273    
274     elif ( opt == '-jobtype' ):
275     if val : self.job_type_name = string.upper(val)
276     else : usage()
277     pass
278    
279     elif ( opt == '-Q' ):
280     self.flag_quiet = 1
281     pass
282    
283     elif ( opt == '-debug' ):
284 slacapra 1.6 if val: self.debug_level = int(val)
285     else: self.debug_level = 1
286 nsmirnov 1.1 pass
287    
288     elif ( opt == '-scheduler' ):
289     if val: self.scheduler_name = val
290     else:
291     print common.prog_name+". No value for '-scheduler'."
292     usage()
293     pass
294     pass
295 slacapra 1.22
296 fanzago 1.18 elif ( opt in ('-use_boss', '-useboss') ):
297     if ( val == '1' ):
298     self.scheduler_name = 'boss'
299     pass
300     elif ( val == '0' ):
301     pass
302     else:
303     print common.prog_name+'. Bad flag for -use_boss option:',\
304     val,'Possible values are 0(=No) or 1(=Yes)'
305     usage()
306     pass
307 fanzago 1.14 pass
308    
309 nsmirnov 1.3 elif string.find(opt,'.') == -1:
310     print common.prog_name+'. Unrecognized option '+opt
311     usage()
312     pass
313 nsmirnov 1.1
314 nsmirnov 1.3 # Override config parameters from INI-file with cmd-line params
315     if string.find(opt,'.') == -1 :
316     self.cfg_params['CRAB.'+opt[1:]] = val
317 nsmirnov 1.1 pass
318 nsmirnov 1.3 else:
319 nsmirnov 1.1 # Command line parameters in the form -SECTION.ENTRY=VALUE
320     self.cfg_params[opt[1:]] = val
321     pass
322     pass
323     return
324    
325 slacapra 1.8 def parseRange_(self, aRange):
326 nsmirnov 1.4 """
327 slacapra 1.8 Takes as the input a string with a range defined in any of the following
328     way, including combination, and return a tuple with the ints defined
329     according to following table. A consistency check is done.
330     NB: the first job is "1", not "0".
331     'all' -> [1,2,..., NJobs]
332     '' -> [1,2,..., NJobs]
333     'n1' -> [n1]
334     'n1-n2' -> [n1, n1+1, n1+2, ..., n2-1, n2]
335     'n1,n2' -> [n1, n2]
336     'n1,n2-n3' -> [n1, n2, n2+1, n2+2, ..., n3-1, n3]
337     """
338     result = []
339    
340 slacapra 1.9 common.logger.debug(5,"parseRange_ "+str(aRange))
341     if aRange=='all' or aRange==None or aRange=='':
342 slacapra 1.8 result=range(0,common.jobDB.nJobs())
343     return result
344 slacapra 1.9 elif aRange=='0':
345     return result
346 slacapra 1.8
347     subRanges = string.split(aRange, ',')
348     for subRange in subRanges:
349     result = result+self.parseSimpleRange_(subRange)
350    
351     if self.checkUniqueness_(result):
352     return result
353     else:
354 slacapra 1.33 common.logger.message("Error "+result)
355 slacapra 1.8 return []
356    
357     def checkUniqueness_(self, list):
358     """
359 slacapra 1.9 check if a list contains only unique elements
360 slacapra 1.8 """
361    
362     uniqueList = []
363     # use a list comprehension statement (takes a while to understand)
364    
365     [uniqueList.append(it) for it in list if not uniqueList.count(it)]
366    
367     return (len(list)==len(uniqueList))
368    
369     def parseSimpleRange_(self, aRange):
370     """
371     Takes as the input a string with two integers separated by
372     the minus sign and returns the tuple with these numbers:
373     'n1-n2' -> [n1, n1+1, n1+2, ..., n2-1, n2]
374     'n1' -> [n1]
375     """
376     (start, end) = (None, None)
377    
378     result = []
379     minus = string.find(aRange, '-')
380     if ( minus < 0 ):
381     if isInt(aRange) and int(aRange)>0:
382 fanzago 1.37 # FEDE
383     #result.append(int(aRange)-1)
384     ###
385     result.append(aRange)
386 slacapra 1.8 else:
387 slacapra 1.9 common.logger.message("parseSimpleRange_ ERROR "+aRange)
388 nsmirnov 1.4 pass
389     else:
390 slacapra 1.8 (start, end) = string.split(aRange, '-')
391     if isInt(start) and isInt(end) and int(start)>0 and int(start)<int(end):
392 spiga 1.38 #result=range(int(start)-1, int(end))
393     result=range(int(start), int(end)+1) #Daniele
394 slacapra 1.8 else:
395 slacapra 1.33 common.logger.message("parseSimpleRange_ ERROR "+start+end)
396 slacapra 1.8
397     return result
398 nsmirnov 1.4
399 nsmirnov 1.3 def initializeActions_(self, opts):
400 nsmirnov 1.1 """
401     For each user action instantiate a corresponding
402     object and put it in the action dictionary.
403     """
404     for opt in opts.keys():
405 spiga 1.32 self.flag_useboss = 0
406 spiga 1.16 if ( opt == '-use_boss'):
407 slacapra 1.25 val = opts[opt]
408     if ( val == '1' ):
409     self.flag_useboss = 1
410     common.logger.message('Using BOSS')
411     pass
412     else:
413     self.flag_useboss = 0
414     pass
415 spiga 1.15
416     for opt in opts.keys():
417    
418 nsmirnov 1.1 val = opts[opt]
419 spiga 1.15
420    
421     if ( opt == '-create' ):
422 slacapra 1.22 ncjobs = 0
423 nsmirnov 1.1 if val:
424     if ( isInt(val) ):
425     ncjobs = int(val)
426     elif ( val == 'all'):
427     ncjobs = val
428     else:
429 nsmirnov 1.5 msg = 'Bad creation bunch size <'+str(val)+'>\n'
430     msg += ' Must be an integer or "all"'
431 slacapra 1.8 msg += ' Generic range is not allowed"'
432 nsmirnov 1.5 raise CrabException(msg)
433 nsmirnov 1.1 pass
434     else: ncjobs = 'all'
435    
436     if ncjobs != 0:
437 nsmirnov 1.3 # Instantiate Creator object
438 nsmirnov 1.1 creator = Creator(self.job_type_name,
439     self.cfg_params,
440     ncjobs)
441     self.actions[opt] = creator
442 nsmirnov 1.3
443     # Initialize the JobDB object if needed
444 nsmirnov 1.1 if not self.flag_continue:
445     common.jobDB.create(creator.nJobs())
446     pass
447 nsmirnov 1.3
448     # Create and initialize JobList
449    
450     common.job_list = JobList(common.jobDB.nJobs(),
451     creator.jobType())
452    
453     common.job_list.setScriptNames(self.job_type_name+'.sh')
454     common.job_list.setJDLNames(self.job_type_name+'.jdl')
455 slacapra 1.12 common.job_list.setCfgNames(self.job_type_name+'.orcarc')
456 slacapra 1.9
457     creator.writeJobsSpecsToDB()
458 nsmirnov 1.1 pass
459 nsmirnov 1.3 pass
460 nsmirnov 1.1
461     elif ( opt == '-submit' ):
462 slacapra 1.23
463     # total jobs
464     # get the first not already submitted
465 slacapra 1.24 common.logger.debug(5,'Total jobs '+str(common.jobDB.nJobs()))
466     lastSubmittedJob=0
467     for nj in range(common.jobDB.nJobs()):
468 spiga 1.41 if (common.jobDB.status(nj)=='S') or (common.jobDB.status(nj)=='K'): #Da
469 slacapra 1.24 lastSubmittedJob +=1
470 slacapra 1.30 else: break
471 slacapra 1.24 # count job from 1
472 slacapra 1.30 totalJobsSubmittable = common.jobDB.nJobs()-lastSubmittedJob
473 slacapra 1.24 common.logger.debug(5,'lastSubmittedJob '+str(lastSubmittedJob))
474     common.logger.debug(5,'totalJobsSubmittable '+str(totalJobsSubmittable))
475 slacapra 1.23
476 slacapra 1.24 nsjobs = lastSubmittedJob+totalJobsSubmittable
477 slacapra 1.23 # get user request
478 slacapra 1.22 if val:
479     if ( isInt(val) ):
480 slacapra 1.24 tmp = int(val)
481     if (tmp >= totalJobsSubmittable):
482     common.logger.message('asking to submit '+str(tmp)+' jobs, but only '+str(totalJobsSubmittable)+' left: submitting those')
483     pass
484     else:
485     nsjobs=lastSubmittedJob+int(val)
486 slacapra 1.23 elif (val=='all'):
487     pass
488 slacapra 1.22 else:
489     msg = 'Bad submission option <'+str(val)+'>\n'
490     msg += ' Must be an integer or "all"'
491     msg += ' Generic range is not allowed"'
492     raise CrabException(msg)
493     pass
494 slacapra 1.24 common.logger.debug(5,'nsjobs '+str(nsjobs))
495 slacapra 1.23
496     # submit N from last submitted job
497 slacapra 1.24 nj_list = range(lastSubmittedJob, nsjobs)
498     common.logger.debug(5,'nj_list '+str(nj_list))
499 nsmirnov 1.5
500     if len(nj_list) != 0:
501 nsmirnov 1.3 # Instantiate Submitter object
502 nsmirnov 1.5 self.actions[opt] = Submitter(self.cfg_params, nj_list)
503 nsmirnov 1.3
504     # Create and initialize JobList
505     if len(common.job_list) == 0 :
506     common.job_list = JobList(common.jobDB.nJobs(),
507     None)
508     common.job_list.setJDLNames(self.job_type_name+'.jdl')
509     pass
510 nsmirnov 1.1 pass
511 slacapra 1.30 pass
512 nsmirnov 1.1
513 nsmirnov 1.4 elif ( opt == '-list' ):
514 slacapra 1.8 jobs = self.parseRange_(val)
515    
516     common.jobDB.dump(jobs)
517 nsmirnov 1.4 pass
518    
519     elif ( opt == '-status' ):
520 slacapra 1.8 jobs = self.parseRange_(val)
521    
522 slacapra 1.9 if len(jobs) != 0:
523 spiga 1.16 if ( self.flag_useboss == 1 ):
524 slacapra 1.36 self.actions[opt] = StatusBoss()
525 spiga 1.15 else:
526 slacapra 1.36 self.actions[opt] = Status(jobs)
527 spiga 1.15 pass
528 nsmirnov 1.1 pass
529     pass
530 slacapra 1.22
531 nsmirnov 1.4 elif ( opt == '-kill' ):
532 slacapra 1.8
533 spiga 1.31 if ( self.flag_useboss == 1 ):
534     if val:
535     if val =='all':
536 fanzago 1.37 allBoss_id = common.scheduler.listBoss()
537     jobs = allBoss_id.keys()
538 spiga 1.31 else:
539     jobs = self.parseRange_(val)
540     common.scheduler.cancel(jobs)
541     else:
542     common.logger.message("Warning: with '-kill' you _MUST_ specify a job range or 'all'")
543     else:
544     if val:
545     jobs = self.parseRange_(val)
546    
547     for nj in jobs:
548     st = common.jobDB.status(nj)
549     if st == 'S':
550     jid = common.jobDB.jobId(nj)
551     common.logger.message("Killing job # "+`(nj+1)`)
552     common.scheduler.cancel(jid)
553     common.jobDB.setStatus(nj, 'K')
554     pass
555 slacapra 1.9 pass
556 spiga 1.31
557     common.jobDB.save()
558 nsmirnov 1.4 pass
559 spiga 1.31 else:
560     common.logger.message("Warning: with '-kill' you _MUST_ specify a job range or 'all'")
561 nsmirnov 1.1
562 slacapra 1.8 elif ( opt == '-getoutput' ):
563    
564 spiga 1.20 if ( self.flag_useboss == 1 ):
565     if val=='all' or val==None or val=='':
566 fanzago 1.37 allBoss_id = common.scheduler.listBoss()
567     jobs = allBoss_id.keys()
568 spiga 1.20 else:
569     jobs = self.parseRange_(val)
570     common.scheduler.getOutput(jobs)
571     else:
572     jobs = self.parseRange_(val)
573 spiga 1.13
574 slacapra 1.22 ## also this: create a ActorClass (GetOutput)
575 spiga 1.20 jobs_done = []
576     for nj in jobs:
577     st = common.jobDB.status(nj)
578     if st == 'D':
579 slacapra 1.12 jobs_done.append(nj)
580 spiga 1.20 pass
581     elif st == 'S':
582     jid = common.jobDB.jobId(nj)
583     currStatus = common.scheduler.queryStatus(jid)
584     if currStatus=="Done":
585     jobs_done.append(nj)
586     else:
587     msg = 'Job # '+`(nj+1)`+' submitted but still status '+currStatus+' not possible to get output'
588     common.logger.message(msg)
589     pass
590 slacapra 1.9 else:
591 spiga 1.20 # common.logger.message('Jobs #'+`(nj+1)`+' has status '+st+' not possible to get output')
592     pass
593 slacapra 1.12 pass
594    
595 spiga 1.20 for nj in jobs_done:
596 spiga 1.15 jid = common.jobDB.jobId(nj)
597     dir = common.scheduler.getOutput(jid)
598     common.jobDB.setStatus(nj, 'Y')
599 slacapra 1.12
600     # Rename the directory with results to smth readable
601     new_dir = common.work_space.resDir()
602 spiga 1.20 try:
603     files = os.listdir(dir)
604     for file in files:
605     os.rename(dir+'/'+file, new_dir+'/'+file)
606     os.rmdir(dir)
607     except OSError, e:
608     msg = 'rename files from '+dir+' to '+new_dir+' error: '
609     msg += str(e)
610     common.logger.message(msg)
611     # ignore error
612 slacapra 1.12 pass
613 spiga 1.20 pass
614 slacapra 1.22 ###
615    
616 spiga 1.13 resFlag = 0
617     exCode = common.scheduler.getExitStatus(jid)
618 spiga 1.34 Statistic.Monitor('retrieved',resFlag,jid,exCode)
619 slacapra 1.12
620     msg = 'Results of Job # '+`(nj+1)`+' are in '+new_dir
621     common.logger.message(msg)
622 nsmirnov 1.4 pass
623    
624     common.jobDB.save()
625     pass
626    
627     elif ( opt == '-resubmit' ):
628 fanzago 1.37 if ( self.flag_useboss == 1 ):
629     if val=='all' or val==None or val=='':
630     allBoss_id = common.scheduler.listBoss()
631     # sono gli internal_id di BOSS
632     jobs = allBoss_id.keys()
633     else:
634     jobs = self.parseRange_(val)
635     else:
636     if val:
637     jobs = self.parseRange_(val)
638    
639 slacapra 1.11 if val:
640     # create a list of jobs to be resubmitted.
641 slacapra 1.8
642 slacapra 1.22 ### as before, create a Resubmittter Class
643 slacapra 1.11 nj_list = []
644     for nj in jobs:
645 fanzago 1.37 st = common.jobDB.status(int(nj)-1)
646     #print "stato del job = ", st
647 slacapra 1.11 if st in ['K','A']:
648 fanzago 1.37 nj_list.append(int(nj)-1)
649     common.jobDB.setStatus(int(nj)-1,'C')
650 slacapra 1.11 elif st == 'Y':
651 fanzago 1.39 common.scheduler.moveOutput(nj)
652 fanzago 1.37 nj_list.append(int(nj)-1)
653     st = common.jobDB.setStatus(int(nj)-1,'RC')
654     elif st in ['D','C','X']:
655     # Nel caso DONE bisogna prima ritirare l'output
656     # Nel caso C va prima sottomesso
657     # Nel caso X va prima creato
658 slacapra 1.11 pass
659     else:
660 fanzago 1.37 #common.logger.message('Job #'+str(nj+1)+' has status '+crabJobStatusToString(st)+' must be "killed" before resubmission')
661     common.logger.message('Job #'+nj+' has status '+crabJobStatusToString(st)+' must be "killed" before resubmission')
662 slacapra 1.9 pass
663 slacapra 1.8
664 fanzago 1.37 if len(common.job_list) == 0 :
665     #print "common.job_list = ", common.job_list
666     common.job_list = JobList(common.jobDB.nJobs(),None)
667     common.job_list.setJDLNames(self.job_type_name+'.jdl')
668     pass
669    
670 slacapra 1.11 if len(nj_list) != 0:
671 fanzago 1.37 #print "nj_list = ", nj_list
672     common.scheduler.resubmit(nj_list)
673 slacapra 1.11 # Instantiate Submitter object
674     self.actions[opt] = Submitter(self.cfg_params, nj_list)
675    
676 slacapra 1.8 pass
677     pass
678 slacapra 1.11 else:
679     common.logger.message("Warning: with '-resubmit' you _MUST_ specify a job range or 'all'")
680     common.logger.message("WARNING: _all_ job specified in the rage will be resubmitted!!!")
681     pass
682 fanzago 1.37 common.jobDB.save()
683 slacapra 1.8 pass
684    
685     elif ( opt == '-cancelAndResubmit' ):
686     jobs = self.parseRange_(val)
687 nsmirnov 1.5
688 nsmirnov 1.7 # Cancel submitted jobs.
689 nsmirnov 1.5
690 slacapra 1.8 nj_list = []
691     for nj in jobs:
692 nsmirnov 1.5 st = common.jobDB.status(nj)
693     if st == 'S':
694     jid = common.jobDB.jobId(nj)
695     common.scheduler.cancel(jid)
696     st = 'K'
697     common.jobDB.setStatus(nj, st)
698     pass
699 nsmirnov 1.7 pass
700 nsmirnov 1.5
701 slacapra 1.8 if st != 'X': nj_list.append(nj)
702     pass
703 nsmirnov 1.5
704     if len(nj_list) != 0:
705     # Instantiate Submitter object
706     self.actions[opt] = Submitter(self.cfg_params, nj_list)
707    
708     # Create and initialize JobList
709    
710     if len(common.job_list) == 0 :
711     common.job_list = JobList(common.jobDB.nJobs(),
712     None)
713     common.job_list.setJDLNames(self.job_type_name+'.jdl')
714     pass
715     pass
716 nsmirnov 1.4 pass
717    
718 slacapra 1.28 elif ( opt == '-testJdl' ):
719 slacapra 1.8 jobs = self.parseRange_(val)
720     nj_list = []
721     for nj in jobs:
722     st = common.jobDB.status(nj)
723 slacapra 1.12 if st == 'C': nj_list.append(nj)
724 slacapra 1.8 pass
725    
726     if len(nj_list) != 0:
727     # Instantiate Submitter object
728     self.actions[opt] = Checker(self.cfg_params, nj_list)
729    
730     # Create and initialize JobList
731    
732     if len(common.job_list) == 0 :
733     common.job_list = JobList(common.jobDB.nJobs(), None)
734     common.job_list.setJDLNames(self.job_type_name+'.jdl')
735     pass
736     pass
737    
738 slacapra 1.9 elif ( opt == '-postMortem' ):
739     jobs = self.parseRange_(val)
740     nj_list = []
741     for nj in jobs:
742     st = common.jobDB.status(nj)
743 fanzago 1.17 if st not in ['X', 'C']: nj_list.append(nj)
744 slacapra 1.9 pass
745    
746     if len(nj_list) != 0:
747     # Instantiate Submitter object
748 spiga 1.35 self.actions[opt] = PostMortem(self.cfg_params, nj_list,self.flag_useboss)
749 slacapra 1.9
750     # Create and initialize JobList
751    
752     if len(common.job_list) == 0 :
753     common.job_list = JobList(common.jobDB.nJobs(), None)
754     common.job_list.setJDLNames(self.job_type_name+'.jdl')
755     pass
756     pass
757 slacapra 1.33 else:
758     common.logger.message("No jobs to analyze")
759 slacapra 1.9
760     elif ( opt == '-clean' ):
761     if val != None:
762     raise CrabException("No range allowed for '-clean'")
763    
764 slacapra 1.36 theCleaner = Cleaner(self.scheduler_name == 'boss')
765     theCleaner.clean()
766 slacapra 1.9
767 nsmirnov 1.1 pass
768     return
769    
770 nsmirnov 1.3 def createWorkingSpace_(self):
771 slacapra 1.9 new_dir = ''
772    
773     try:
774     new_dir = self.cfg_params['USER.ui_working_dir']
775     except KeyError:
776     new_dir = common.prog_name + '_' + self.name + '_' + self.current_time
777     new_dir = self.cwd + new_dir
778     pass
779    
780 nsmirnov 1.1 common.work_space = WorkSpace(new_dir)
781     common.work_space.create()
782     return
783    
784 nsmirnov 1.3 def loadConfiguration_(self, opts):
785 nsmirnov 1.1
786     save_opts = common.work_space.loadSavedOptions()
787    
788     # Override saved options with new command-line options
789    
790     for k in opts.keys():
791     save_opts[k] = opts[k]
792     pass
793    
794     # Return updated options
795     return save_opts
796    
797 nsmirnov 1.3 def createLogger_(self, args):
798 nsmirnov 1.1
799     log = Logger()
800     log.quiet(self.flag_quiet)
801     log.setDebugLevel(self.debug_level)
802     log.write(args+'\n')
803 nsmirnov 1.3 log.message(self.headerString_())
804 nsmirnov 1.1 log.flush()
805     common.logger = log
806     return
807    
808 nsmirnov 1.3 def updateHistory_(self, args):
809 nsmirnov 1.1 history_fname = common.prog_name+'.history'
810     history_file = open(history_fname, 'a')
811     history_file.write(self.current_time+': '+args+'\n')
812     history_file.close()
813     return
814    
815 nsmirnov 1.3 def headerString_(self):
816 nsmirnov 1.1 """
817     Creates a string describing program options either given in
818     the command line or their default values.
819     """
820     header = common.prog_name + ' (version ' + common.prog_version_str + \
821     ') running on ' + \
822     time.ctime(time.time())+'\n\n' + \
823     common.prog_name+'. Working options:\n'
824     header = header +\
825     ' scheduler ' + self.scheduler_name + '\n'+\
826     ' job type ' + self.job_type_name + '\n'+\
827     ' working directory ' + common.work_space.topDir()\
828     + '\n'
829     return header
830    
831 nsmirnov 1.3 def createScheduler_(self):
832 nsmirnov 1.1 """
833     Creates a scheduler object instantiated by its name.
834     """
835     klass_name = 'Scheduler' + string.capitalize(self.scheduler_name)
836     file_name = klass_name
837     try:
838     klass = importName(file_name, klass_name)
839     except KeyError:
840     msg = 'No `class '+klass_name+'` found in file `'+file_name+'.py`'
841     raise CrabException(msg)
842     except ImportError, e:
843     msg = 'Cannot create scheduler '+self.scheduler_name
844     msg += ' (file: '+file_name+', class '+klass_name+'):\n'
845     msg += str(e)
846     raise CrabException(msg)
847    
848     common.scheduler = klass()
849     common.scheduler.configure(self.cfg_params)
850     return
851    
852     def run(self):
853     """
854     For each
855     """
856    
857     for act in self.main_actions:
858     if act in self.actions.keys(): self.actions[act].run()
859     pass
860    
861     for act in self.aux_actions:
862     if act in self.actions.keys(): self.actions[act].run()
863     pass
864     return
865    
866     ###########################################################################
867     def processHelpOptions(opts):
868    
869 slacapra 1.11 if len(opts):
870     for opt in opts.keys():
871     if opt in ('-v', '-version', '--version') :
872     print Crab.version()
873     return 1
874     if opt in ('-h','-help','--help') :
875     if opts[opt] : help(opts[opt])
876     else: help()
877     return 1
878     else:
879     usage()
880 nsmirnov 1.1
881     return 0
882    
883     ###########################################################################
884     if __name__ == '__main__':
885    
886 fanzago 1.18
887 fanzago 1.19 # # Initial settings for Python modules. Avoid appending manually lib paths.
888     # try:
889     # path=os.environ['EDG_WL_LOCATION']
890     # except:
891     # print "Error: Please set the EDG_WL_LOCATION environment variable pointing to the userinterface installation path"
892     # sys.exit(1)
893     #
894     # libPath=os.path.join(path, "lib")
895     # sys.path.append(libPath)
896     # libPath=os.path.join(path, "lib", "python")
897     # sys.path.append(libPath)
898 fanzago 1.18
899    
900 nsmirnov 1.1 # Parse command-line options and create a dictionary with
901     # key-value pairs.
902    
903     options = parseOptions(sys.argv[1:])
904    
905     # Process "help" options, such as '-help', '-version'
906    
907 slacapra 1.11 if processHelpOptions(options) : sys.exit(0)
908 nsmirnov 1.1
909     # Create, initialize, and run a Crab object
910    
911     try:
912 nsmirnov 1.3 crab = Crab(options)
913 nsmirnov 1.1 crab.run()
914     except CrabException, e:
915     print '\n' + common.prog_name + ': ' + str(e) + '\n'
916     if common.logger:
917     common.logger.write('ERROR: '+str(e)+'\n')
918     pass
919     pass
920    
921     pass