ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/crab.py
Revision: 1.101
Committed: Tue Feb 27 13:44:01 2007 UTC (18 years, 2 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.100: +5 -8 lines
Log Message:
enable the choice of scheduler also from command line

File Contents

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