ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/crab.py
Revision: 1.161
Committed: Fri Apr 11 14:54:23 2008 UTC (17 years ago) by slacapra
Content type: text/x-python
Branch: MAIN
Changes since 1.160: +4 -2 lines
Log Message:
Many changes to have LSF working with BossLite
Introduce Killer class to handle -kill which works again
Work_space::res() return the correct output directory also in case user has set a non default one, Likewise for logDir()
USER.outputdir is not to be used anywhere outside workspace class
Some cleanup in submit logic, to reduce call of Scheduler specific classes from Submitter.py
crab -clean works as well (well, almost, still need to remove twice the directory)
Fill startDirectory and outputDirectory to Task
GetOuput check status and not schedulerStatus (not stantard)
Some cleanup in the use of BlackWhiteListParser
No explicit check of scheduler concrete type in Submitter at listMatch level: move different behaviour in SchedulerXYZ implementation
Plus other things I'm forgetting...

Stefano

File Contents

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