ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/crab.py
Revision: 1.96
Committed: Wed Nov 29 14:32:32 2006 UTC (18 years, 5 months ago) by fanzago
Content type: text/x-python
Branch: MAIN
Changes since 1.95: +25 -26 lines
Log Message:
removed some int and neadless lines

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