ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.385
Committed: Mon Jul 9 16:19:53 2012 UTC (12 years, 9 months ago) by fanzago
Content type: text/x-python
Branch: MAIN
Changes since 1.384: +8 -10 lines
Log Message:
fixed savannah bug 94491

File Contents

# User Rev Content
1 spiga 1.358
2 fanzago 1.385 __revision__ = "$Id: cms_cmssw.py,v 1.384 2012/06/17 15:38:50 belforte Exp $"
3     __version__ = "$Revision: 1.384 $"
4 spiga 1.358
5 slacapra 1.1 from JobType import JobType
6     from crab_exceptions import *
7     from crab_util import *
8     import common
9 ewv 1.363 import re
10 slacapra 1.1 import Scram
11 spiga 1.269 from Splitter import JobSplitter
12 ewv 1.355 from Downloader import Downloader
13 ewv 1.363 try:
14 fanzago 1.360 import json
15     except:
16     import simplejson as json
17 slacapra 1.1
18 spiga 1.293 from IMProv.IMProvNode import IMProvNode
19 ewv 1.355 from IMProv.IMProvLoader import loadIMProvFile
20 slacapra 1.105 import os, string, glob
21 ewv 1.355 from xml.dom import pulldom
22 slacapra 1.1
23     class Cmssw(JobType):
24 spiga 1.208 def __init__(self, cfg_params, ncjobs,skip_blocks, isNew):
25 slacapra 1.1 JobType.__init__(self, 'CMSSW')
26 spiga 1.304 common.logger.debug('CMSSW::__init__')
27 spiga 1.208 self.skip_blocks = skip_blocks
28 farinafa 1.346 self.argsList = 2
29 spiga 1.315 self.NumEvents=0
30 gutsche 1.3 self._params = {}
31     self.cfg_params = cfg_params
32 fanzago 1.368 ### FOR MULTI ###
33 fanzago 1.360 self.var_filter=''
34 ewv 1.254
35 spiga 1.234 ### Temporary patch to automatically skip the ISB size check:
36 ewv 1.319 self.server = self.cfg_params.get('CRAB.server_name',None) or \
37     self.cfg_params.get('CRAB.use_server',0)
38 mcinquil 1.340 self.local = common.scheduler.name().upper() in ['LSF','CAF','CONDOR','SGE','PBS']
39 ewv 1.250 size = 9.5
40 spiga 1.365 if self.server :
41 spiga 1.366 size = 100
42 spiga 1.365 elif self.local:
43     size = 9999999
44 spiga 1.306 self.MaxTarBallSize = float(self.cfg_params.get('GRID.maxtarballsize',size))
45 gutsche 1.72
46 gutsche 1.44 # number of jobs requested to be created, limit obj splitting
47 gutsche 1.38 self.ncjobs = ncjobs
48    
49 slacapra 1.1 self.scram = Scram.Scram(cfg_params)
50     self.additional_inbox_files = []
51     self.scriptExe = ''
52     self.executable = ''
53 slacapra 1.71 self.executable_arch = self.scram.getArch()
54 spiga 1.320 self.tgz_name = 'default.tgz'
55 corvo 1.56 self.scriptName = 'CMSSW.sh'
56 ewv 1.192 self.pset = ''
57 spiga 1.187 self.datasetPath = ''
58 gutsche 1.3
59 spiga 1.300 self.tgzNameWithPath = common.work_space.pathForTgz()+self.tgz_name
60 gutsche 1.50 # set FJR file name
61     self.fjrFileName = 'crab_fjr.xml'
62    
63 slacapra 1.1 self.version = self.scram.getSWVersion()
64 spiga 1.304 common.logger.log(10-1,"CMSSW version is: "+str(self.version))
65 spiga 1.324 version_array = self.version.split('_')
66     self.CMSSW_major = 0
67     self.CMSSW_minor = 0
68     self.CMSSW_patch = 0
69 ewv 1.182 try:
70 spiga 1.324 self.CMSSW_major = int(version_array[1])
71     self.CMSSW_minor = int(version_array[2])
72     self.CMSSW_patch = int(version_array[3])
73 ewv 1.182 except:
74 ewv 1.184 msg = "Cannot parse CMSSW version string: " + self.version + " for major and minor release number!"
75 ewv 1.182 raise CrabException(msg)
76    
77 ewv 1.334 if self.CMSSW_major < 2 or (self.CMSSW_major == 2 and self.CMSSW_minor < 1):
78     msg = "CRAB supports CMSSW >= 2_1_x only. Use an older CRAB version."
79 ewv 1.276 raise CrabException(msg)
80     """
81     As CMSSW versions are dropped we can drop more code:
82 ewv 1.334 2.x dropped: drop check for lumi range setting
83 ewv 1.276 """
84 ewv 1.355 self.checkCMSSWVersion()
85 slacapra 1.1 ### collect Data cards
86 gutsche 1.66
87 fanzago 1.221 ### Temporary: added to remove input file control in the case of PU
88 farinafa 1.224 self.dataset_pu = cfg_params.get('CMSSW.dataset_pu', None)
89 ewv 1.226
90 fanzago 1.368 if not cfg_params.has_key('CMSSW.datasetpath'):
91     msg = "Error: datasetpath not defined in the section [CMSSW] of crab.cfg file "
92 spiga 1.236 raise CrabException(msg)
93 fanzago 1.368 else:
94     tmp = cfg_params['CMSSW.datasetpath']
95     common.logger.log(10-1, "CMSSW::CMSSW(): datasetPath = "+tmp)
96     if string.lower(tmp)=='none':
97     self.datasetPath = None
98     self.selectNoInput = 1
99     self.primaryDataset = 'null'
100     else:
101     self.datasetPath = tmp
102     self.selectNoInput = 0
103     ll = len(self.datasetPath.split("/"))
104 belforte 1.381 if (ll != 4) or self.datasetPath[0] != '/' or self.datasetPath[-1] == '/':
105 fanzago 1.368 msg = 'Your datasetpath has a invalid format ' + self.datasetPath + '\n'
106 belforte 1.380 msg += 'Expected a path in format /PRIMARY/PROCESSED/TIER'
107 fanzago 1.368 raise CrabException(msg)
108     self.primaryDataset = self.datasetPath.split("/")[1]
109     self.dataTier = self.datasetPath.split("/")[2]
110 gutsche 1.5
111 ewv 1.326 # Analysis dataset is primary/processed/tier/definition
112 ewv 1.330 self.ads = False
113     if self.datasetPath:
114     self.ads = len(self.datasetPath.split("/")) > 4
115 spiga 1.354 self.lumiMask = self.cfg_params.get('CMSSW.lumi_mask',None)
116 ewv 1.356 self.lumiParams = self.cfg_params.get('CMSSW.total_number_of_lumis',None) or \
117     self.cfg_params.get('CMSSW.lumis_per_job',None)
118 spiga 1.358
119 ewv 1.327 # FUTURE: Can remove this check
120     if self.ads and self.CMSSW_major < 3:
121     common.logger.info('Warning: Analysis dataset support is incomplete in CMSSW 2_x.')
122     common.logger.info(' Only file level, not lumi level, granularity is supported.')
123    
124 spiga 1.288 self.debugWrap=''
125 fanzago 1.285 self.debug_wrapper = int(cfg_params.get('USER.debug_wrapper',0))
126     if self.debug_wrapper == 1: self.debugWrap='--debug'
127 slacapra 1.291
128 slacapra 1.1 ## now the application
129 ewv 1.313 self.managedGenerators = ['madgraph', 'comphep', 'lhe']
130 ewv 1.258 self.generator = cfg_params.get('CMSSW.generator','pythia').lower()
131 slacapra 1.153 self.executable = cfg_params.get('CMSSW.executable','cmsRun')
132 spiga 1.305 common.logger.log(10-1, "CMSSW::CMSSW(): executable = "+self.executable)
133 slacapra 1.1
134 slacapra 1.153 if not cfg_params.has_key('CMSSW.pset'):
135 slacapra 1.1 raise CrabException("PSet file missing. Cannot run cmsRun ")
136 slacapra 1.153 self.pset = cfg_params['CMSSW.pset']
137 spiga 1.305 common.logger.log(10-1, "Cmssw::Cmssw(): PSet file = "+self.pset)
138 slacapra 1.153 if self.pset.lower() != 'none' :
139     if (not os.path.exists(self.pset)):
140     raise CrabException("User defined PSet file "+self.pset+" does not exist")
141     else:
142     self.pset = None
143 slacapra 1.1
144     # output files
145 slacapra 1.53 ## stuff which must be returned always via sandbox
146     self.output_file_sandbox = []
147    
148     # add fjr report by default via sandbox
149     self.output_file_sandbox.append(self.fjrFileName)
150    
151     # other output files to be returned via sandbox or copied to SE
152 mcinquil 1.216 outfileflag = False
153 slacapra 1.153 self.output_file = []
154     tmp = cfg_params.get('CMSSW.output_file',None)
155     if tmp :
156 slacapra 1.207 self.output_file = [x.strip() for x in tmp.split(',')]
157 mcinquil 1.216 outfileflag = True #output found
158 slacapra 1.1
159 slacapra 1.153 self.scriptExe = cfg_params.get('USER.script_exe',None)
160     if self.scriptExe :
161 slacapra 1.176 if not os.path.isfile(self.scriptExe):
162     msg ="ERROR. file "+self.scriptExe+" not found"
163     raise CrabException(msg)
164     self.additional_inbox_files.append(string.strip(self.scriptExe))
165 slacapra 1.70
166 spiga 1.314 self.AdditionalArgs = cfg_params.get('USER.script_arguments',None)
167     if self.AdditionalArgs : self.AdditionalArgs = string.replace(self.AdditionalArgs,',',' ')
168    
169 spiga 1.42 if self.datasetPath == None and self.pset == None and self.scriptExe == '' :
170 slacapra 1.176 msg ="Error. script_exe not defined"
171     raise CrabException(msg)
172 spiga 1.42
173 ewv 1.226 # use parent files...
174 spiga 1.269 self.useParent = int(self.cfg_params.get('CMSSW.use_parent',0))
175 spiga 1.204
176 slacapra 1.1 ## additional input files
177 slacapra 1.153 if cfg_params.has_key('USER.additional_input_files'):
178 slacapra 1.29 tmpAddFiles = string.split(cfg_params['USER.additional_input_files'],',')
179 slacapra 1.70 for tmp in tmpAddFiles:
180     tmp = string.strip(tmp)
181     dirname = ''
182     if not tmp[0]=="/": dirname = "."
183 corvo 1.85 files = []
184     if string.find(tmp,"*")>-1:
185     files = glob.glob(os.path.join(dirname, tmp))
186     if len(files)==0:
187     raise CrabException("No additional input file found with this pattern: "+tmp)
188     else:
189     files.append(tmp)
190 slacapra 1.70 for file in files:
191     if not os.path.exists(file):
192     raise CrabException("Additional input file not found: "+file)
193 slacapra 1.45 pass
194 slacapra 1.105 self.additional_inbox_files.append(string.strip(file))
195 slacapra 1.1 pass
196     pass
197 spiga 1.304 common.logger.debug("Additional input files: "+str(self.additional_inbox_files))
198 slacapra 1.153 pass
199 gutsche 1.3
200 gutsche 1.35
201 ewv 1.160 ## New method of dealing with seeds
202     self.incrementSeeds = []
203     self.preserveSeeds = []
204     if cfg_params.has_key('CMSSW.preserve_seeds'):
205     tmpList = cfg_params['CMSSW.preserve_seeds'].split(',')
206     for tmp in tmpList:
207     tmp.strip()
208     self.preserveSeeds.append(tmp)
209     if cfg_params.has_key('CMSSW.increment_seeds'):
210     tmpList = cfg_params['CMSSW.increment_seeds'].split(',')
211     for tmp in tmpList:
212     tmp.strip()
213     self.incrementSeeds.append(tmp)
214    
215 fanzago 1.318 # Copy/return/publish
216 slacapra 1.153 self.copy_data = int(cfg_params.get('USER.copy_data',0))
217     self.return_data = int(cfg_params.get('USER.return_data',0))
218 fanzago 1.318 self.publish_data = int(cfg_params.get('USER.publish_data',0))
219     if (self.publish_data == 1):
220     if not cfg_params.has_key('USER.publish_data_name'):
221     raise CrabException('Cannot publish output data, because you did not specify USER.publish_data_name parameter in the crab.cfg file')
222     else:
223     self.processedDataset = cfg_params['USER.publish_data_name']
224 ewv 1.276
225     self.conf = {}
226     self.conf['pubdata'] = None
227 spiga 1.269 # number of jobs requested to be created, limit obj splitting DD
228 slacapra 1.1 #DBSDLS-start
229 ewv 1.131 ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
230 slacapra 1.1 self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
231     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
232 gutsche 1.35 self.jobDestination=[] # Site destination(s) for each job (list of lists)
233 slacapra 1.1 ## Perform the data location and discovery (based on DBS/DLS)
234 slacapra 1.9 ## SL: Don't if NONE is specified as input (pythia use case)
235 gutsche 1.35 blockSites = {}
236 spiga 1.342 #wmbs
237     self.automation = int(self.cfg_params.get('WMBS.automation',0))
238     if self.automation == 0:
239     if self.datasetPath:
240     blockSites = self.DataDiscoveryAndLocation(cfg_params)
241     #DBSDLS-end
242     self.conf['blockSites']=blockSites
243 ewv 1.347
244 spiga 1.342 ## Select Splitting
245     splitByRun = int(cfg_params.get('CMSSW.split_by_run',0))
246 ewv 1.347
247 spiga 1.342 if self.selectNoInput:
248     if self.pset == None:
249     self.algo = 'ForScript'
250     else:
251     self.algo = 'NoInput'
252     self.conf['managedGenerators']=self.managedGenerators
253     self.conf['generator']=self.generator
254 ewv 1.356 elif self.ads or self.lumiMask or self.lumiParams:
255 spiga 1.342 self.algo = 'LumiBased'
256 ewv 1.359 if splitByRun:
257     msg = "Cannot combine split by run with lumi_mask, ADS, " \
258     "or lumis_per_job. Use split by lumi mode instead."
259     raise CrabException(msg)
260    
261 spiga 1.342 elif splitByRun ==1:
262     self.algo = 'RunBased'
263 spiga 1.42 else:
264 spiga 1.342 self.algo = 'EventBased'
265     common.logger.debug("Job splitting method: %s" % self.algo)
266 ewv 1.347
267 spiga 1.342 splitter = JobSplitter(self.cfg_params,self.conf)
268     self.dict = splitter.Algos()[self.algo]()
269 gutsche 1.5
270 spiga 1.300 self.argsFile= '%s/arguments.xml'%common.work_space.shareDir()
271     self.rootArgsFilename= 'arguments'
272 spiga 1.208 # modify Pset only the first time
273 spiga 1.320 if isNew:
274     if self.pset != None: self.ModifyPset()
275 spiga 1.300
276 spiga 1.320 ## Prepare inputSandbox TarBall (only the first time)
277     self.tarNameWithPath = self.getTarBall(self.executable)
278 spiga 1.293
279    
280     def ModifyPset(self):
281     import PsetManipulator as pp
282 ewv 1.335
283     # If pycfg_params set, fake out the config script
284     # to make it think it was called with those args
285     pycfg_params = self.cfg_params.get('CMSSW.pycfg_params',None)
286     if pycfg_params:
287     trueArgv = sys.argv
288     sys.argv = [self.pset]
289     sys.argv.extend(pycfg_params.split(' '))
290 spiga 1.293 PsetEdit = pp.PsetManipulator(self.pset)
291 ewv 1.335 if pycfg_params: # Restore original sys.argv
292     sys.argv = trueArgv
293    
294 spiga 1.293 try:
295     # Add FrameworkJobReport to parameter-set, set max events.
296     # Reset later for data jobs by writeCFG which does all modifications
297 ewv 1.295 PsetEdit.maxEvent(1)
298 spiga 1.293 PsetEdit.skipEvent(0)
299     PsetEdit.psetWriter(self.configFilename())
300     ## If present, add TFileService to output files
301 slacapra 1.349 if not int(self.cfg_params.get('CMSSW.skip_tfileservice_output',0)):
302 spiga 1.293 tfsOutput = PsetEdit.getTFileService()
303     if tfsOutput:
304     if tfsOutput in self.output_file:
305 spiga 1.304 common.logger.debug("Output from TFileService "+tfsOutput+" already in output files")
306 spiga 1.293 else:
307     outfileflag = True #output found
308     self.output_file.append(tfsOutput)
309 spiga 1.304 common.logger.info("Adding "+tfsOutput+" (from TFileService) to list of output files")
310 spiga 1.293 pass
311     pass
312 fanzago 1.360
313     # If requested, add PoolOutputModule to output files
314 fanzago 1.368 ### FOR MULTI ###
315 fanzago 1.360 #edmOutput = PsetEdit.getPoolOutputModule()
316     edmOutputDict = PsetEdit.getPoolOutputModule()
317     common.logger.debug("(test) edmOutputDict = "+str(edmOutputDict))
318     filter_dict = {}
319     for key in edmOutputDict.keys():
320     filter_dict[key]=edmOutputDict[key]['dataset']
321     common.logger.debug("(test) filter_dict for multi = "+str(filter_dict))
322    
323     #### in CMSSW.sh: export var_filter
324    
325     self.var_filter = json.dumps(filter_dict)
326     common.logger.debug("(test) var_filter for multi = "+self.var_filter)
327 ewv 1.363
328 fanzago 1.360 edmOutput = edmOutputDict.keys()
329 spiga 1.293 if int(self.cfg_params.get('CMSSW.get_edm_output',0)):
330     if edmOutput:
331 ewv 1.321 for outputFile in edmOutput:
332     if outputFile in self.output_file:
333 ewv 1.325 common.logger.debug("Output from PoolOutputModule "+outputFile+" already in output files")
334 ewv 1.321 else:
335     self.output_file.append(outputFile)
336     common.logger.info("Adding "+outputFile+" (from PoolOutputModule) to list of output files")
337     # not requested, check anyhow to avoid accidental T2 overload
338 slacapra 1.297 else:
339 ewv 1.321 if edmOutput:
340     missedFiles = []
341     for outputFile in edmOutput:
342     if outputFile not in self.output_file:
343     missedFiles.append(outputFile)
344     if missedFiles:
345     msg = "ERROR: PoolOutputModule(s) are present in your ParameteSet %s \n"%self.pset
346     msg += " but the file(s) produced ( %s ) are not in the list of output files\n" % ', '.join(missedFiles)
347     msg += "WARNING: please remove them. If you want to keep them, add the file(s) to output_files or use CMSSW.get_edm_output = 1\n"
348     if int(self.cfg_params.get('CMSSW.ignore_edm_output',0)):
349     msg += " CMSSW.ignore_edm_output==1 : Hope you know what you are doing...\n"
350     common.logger.info(msg)
351 spiga 1.322 else :
352 ewv 1.321 raise CrabException(msg)
353 ewv 1.301
354     if (PsetEdit.getBadFilesSetting()):
355     msg = "WARNING: You have set skipBadFiles to True. This will continue processing on some errors and you may not be notified."
356 spiga 1.304 common.logger.info(msg)
357 ewv 1.301
358 slacapra 1.297 except CrabException, msg:
359 spiga 1.304 common.logger.info(str(msg))
360 slacapra 1.297 msg='Error while manipulating ParameterSet (see previous message, if any): exiting...'
361 spiga 1.293 raise CrabException(msg)
362    
363 ewv 1.363 valid = re.compile('^[\w\.\-]+$')
364     for fileName in self.output_file:
365     if not valid.match(fileName):
366     msg = "The file %s may only contain alphanumeric characters and -, _, ." % fileName
367     raise CrabException(msg)
368    
369 gutsche 1.3
370 slacapra 1.1 def DataDiscoveryAndLocation(self, cfg_params):
371    
372 slacapra 1.86 import DataDiscovery
373     import DataLocation
374 spiga 1.304 common.logger.log(10-1,"CMSSW::DataDiscoveryAndLocation()")
375 gutsche 1.3
376     datasetPath=self.datasetPath
377    
378 slacapra 1.1 ## Contact the DBS
379 spiga 1.304 common.logger.info("Contacting Data Discovery Services ...")
380 slacapra 1.1 try:
381 spiga 1.208 self.pubdata=DataDiscovery.DataDiscovery(datasetPath, cfg_params,self.skip_blocks)
382 slacapra 1.1 self.pubdata.fetchDBSInfo()
383    
384 slacapra 1.41 except DataDiscovery.NotExistingDatasetError, ex :
385 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
386     raise CrabException(msg)
387 slacapra 1.41 except DataDiscovery.NoDataTierinProvenanceError, ex :
388 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
389     raise CrabException(msg)
390 slacapra 1.41 except DataDiscovery.DataDiscoveryError, ex:
391 gutsche 1.66 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
392 slacapra 1.1 raise CrabException(msg)
393    
394 gutsche 1.35 self.filesbyblock=self.pubdata.getFiles()
395 spiga 1.269 self.conf['pubdata']=self.pubdata
396 gutsche 1.3
397 slacapra 1.1 ## get max number of events
398 ewv 1.192 self.maxEvents=self.pubdata.getMaxEvents()
399 slacapra 1.1
400     ## Contact the DLS and build a list of sites hosting the fileblocks
401     try:
402 slacapra 1.41 dataloc=DataLocation.DataLocation(self.filesbyblock.keys(),cfg_params)
403 gutsche 1.6 dataloc.fetchDLSInfo()
404 slacapra 1.263
405 slacapra 1.41 except DataLocation.DataLocationError , ex:
406 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
407     raise CrabException(msg)
408 ewv 1.131
409 slacapra 1.1
410 slacapra 1.270 unsorted_sites = dataloc.getSites()
411     sites = self.filesbyblock.fromkeys(self.filesbyblock,'')
412     for lfn in self.filesbyblock.keys():
413     if unsorted_sites.has_key(lfn):
414     sites[lfn]=unsorted_sites[lfn]
415     else:
416     sites[lfn]=[]
417    
418 slacapra 1.264 if len(sites)==0:
419 spiga 1.267 msg = 'ERROR ***: no location for any of the blocks of this dataset: \n\t %s \n'%datasetPath
420     msg += "\tMaybe the dataset is located only at T1's (or at T0), where analysis jobs are not allowed\n"
421     msg += "\tPlease check DataDiscovery page https://cmsweb.cern.ch/dbs_discovery/\n"
422 slacapra 1.264 raise CrabException(msg)
423    
424 gutsche 1.35 allSites = []
425     listSites = sites.values()
426 slacapra 1.63 for listSite in listSites:
427     for oneSite in listSite:
428 gutsche 1.35 allSites.append(oneSite)
429 slacapra 1.291 [allSites.append(it) for it in allSites if not allSites.count(it)]
430 ewv 1.295
431 gutsche 1.3
432 gutsche 1.92 # screen output
433 spiga 1.354 if self.ads or self.lumiMask:
434     common.logger.info("Requested (A)DS %s has %s block(s)." %
435 ewv 1.350 (datasetPath, len(self.filesbyblock.keys())))
436     else:
437     common.logger.info("Requested dataset: " + datasetPath + \
438     " has " + str(self.maxEvents) + " events in " + \
439     str(len(self.filesbyblock.keys())) + " blocks.\n")
440 gutsche 1.92
441 gutsche 1.35 return sites
442 ewv 1.131
443 spiga 1.42
444 spiga 1.208 def split(self, jobParams,firstJobID):
445 ewv 1.276
446 spiga 1.293 jobParams = self.dict['args']
447 spiga 1.269 njobs = self.dict['njobs']
448     self.jobDestination = self.dict['jobDestination']
449 ewv 1.131
450 ewv 1.333 if njobs == 0:
451     raise CrabException("Asked to split zero jobs: aborting")
452     if not self.server and not self.local and njobs > 500:
453 fanzago 1.377 msg = "Error: this task contains more than 500 jobs. \n"
454     msg += " The CRAB SA does not submit more than 500 jobs.\n"
455     msg += " Use the server mode. \n"
456 fanzago 1.376 raise CrabException(msg)
457 gutsche 1.3 # create the empty structure
458     for i in range(njobs):
459     jobParams.append("")
460 ewv 1.131
461 spiga 1.165 listID=[]
462     listField=[]
463 spiga 1.293 listDictions=[]
464 spiga 1.300 exist= os.path.exists(self.argsFile)
465 spiga 1.208 for id in range(njobs):
466     job = id + int(firstJobID)
467 spiga 1.167 listID.append(job+1)
468 spiga 1.162 job_ToSave ={}
469 spiga 1.169 concString = ' '
470 spiga 1.165 argu=''
471 spiga 1.293 str_argu = str(job+1)
472 spiga 1.208 if len(jobParams[id]):
473 ewv 1.295 argu = {'JobID': job+1}
474 spiga 1.293 for i in range(len(jobParams[id])):
475     argu[self.dict['params'][i]]=jobParams[id][i]
476 spiga 1.315 if len(jobParams[id])==1: self.NumEvents = jobParams[id][i]
477 ewv 1.295 # just for debug
478 spiga 1.293 str_argu += concString.join(jobParams[id])
479 spiga 1.314 if argu != '': listDictions.append(argu)
480 ewv 1.347 job_ToSave['arguments']= '%d %d'%( (job+1), 0)
481 spiga 1.208 job_ToSave['dlsDestination']= self.jobDestination[id]
482 spiga 1.165 listField.append(job_ToSave)
483 slacapra 1.311 from ProdCommon.SiteDB.CmsSiteMapper import CmsSEMap
484     cms_se = CmsSEMap()
485 ewv 1.295 msg="Job %s Arguments: %s\n"%(str(job+1),str_argu)
486 spiga 1.293 msg+="\t Destination: %s "%(str(self.jobDestination[id]))
487 slacapra 1.311 SEDestination = [cms_se[dest] for dest in self.jobDestination[id]]
488     msg+="\t CMSDestination: %s "%(str(SEDestination))
489 spiga 1.307 common.logger.log(10-1,msg)
490 spiga 1.293 # write xml
491 ewv 1.295 if len(listDictions):
492 spiga 1.293 if exist==False: self.CreateXML()
493     self.addEntry(listDictions)
494 spiga 1.187 common._db.updateJob_(listID,listField)
495 spiga 1.293 return
496 ewv 1.313
497 spiga 1.293 def CreateXML(self):
498     """
499 ewv 1.295 """
500 spiga 1.300 result = IMProvNode( self.rootArgsFilename )
501     outfile = file( self.argsFile, 'w').write(str(result))
502 ewv 1.295 return
503 spiga 1.293
504     def addEntry(self, listDictions):
505     """
506     _addEntry_
507 ewv 1.295
508 spiga 1.293 add an entry to the xml file
509     """
510     ## load xml
511 spiga 1.300 improvDoc = loadIMProvFile(self.argsFile)
512 spiga 1.293 entrname= 'Job'
513     for dictions in listDictions:
514     report = IMProvNode(entrname , None, **dictions)
515     improvDoc.addNode(report)
516 spiga 1.300 outfile = file( self.argsFile, 'w').write(str(improvDoc))
517 gutsche 1.3 return
518 ewv 1.131
519 gutsche 1.3 def numberOfJobs(self):
520 spiga 1.342 #wmbs
521 ewv 1.347 if self.automation==0:
522 spiga 1.342 return self.dict['njobs']
523     else:
524     return None
525 ewv 1.347
526 slacapra 1.1 def getTarBall(self, exe):
527     """
528     Return the TarBall with lib and exe
529     """
530 spiga 1.320 self.tgzNameWithPath = common.work_space.pathForTgz()+self.tgz_name
531     if os.path.exists(self.tgzNameWithPath):
532     return self.tgzNameWithPath
533 slacapra 1.1
534     # Prepare a tar gzipped file with user binaries.
535     self.buildTar_(exe)
536    
537 spiga 1.320 return string.strip(self.tgzNameWithPath)
538 slacapra 1.1
539     def buildTar_(self, executable):
540    
541     # First of all declare the user Scram area
542     swArea = self.scram.getSWArea_()
543     swReleaseTop = self.scram.getReleaseTop_()
544 ewv 1.131
545 slacapra 1.1 ## check if working area is release top
546     if swReleaseTop == '' or swArea == swReleaseTop:
547 spiga 1.304 common.logger.debug("swArea = "+swArea+" swReleaseTop ="+swReleaseTop)
548 slacapra 1.1 return
549    
550 slacapra 1.61 import tarfile
551     try: # create tar ball
552 spiga 1.320 tar = tarfile.open(self.tgzNameWithPath, "w:gz")
553 slacapra 1.61 ## First find the executable
554 slacapra 1.86 if (self.executable != ''):
555 slacapra 1.61 exeWithPath = self.scram.findFile_(executable)
556     if ( not exeWithPath ):
557     raise CrabException('User executable '+executable+' not found')
558 ewv 1.131
559 slacapra 1.61 ## then check if it's private or not
560     if exeWithPath.find(swReleaseTop) == -1:
561     # the exe is private, so we must ship
562 spiga 1.304 common.logger.debug("Exe "+exeWithPath+" to be tarred")
563 slacapra 1.61 path = swArea+'/'
564 corvo 1.85 # distinguish case when script is in user project area or given by full path somewhere else
565     if exeWithPath.find(path) >= 0 :
566     exe = string.replace(exeWithPath, path,'')
567 slacapra 1.129 tar.add(path+exe,exe)
568 corvo 1.85 else :
569     tar.add(exeWithPath,os.path.basename(executable))
570 slacapra 1.61 pass
571     else:
572     # the exe is from release, we'll find it on WN
573     pass
574 ewv 1.131
575 slacapra 1.61 ## Now get the libraries: only those in local working area
576 slacapra 1.256 tar.dereference=True
577 slacapra 1.61 libDir = 'lib'
578     lib = swArea+'/' +libDir
579 spiga 1.304 common.logger.debug("lib "+lib+" to be tarred")
580 slacapra 1.61 if os.path.exists(lib):
581     tar.add(lib,libDir)
582 ewv 1.131
583 slacapra 1.61 ## Now check if module dir is present
584     moduleDir = 'module'
585     module = swArea + '/' + moduleDir
586     if os.path.isdir(module):
587     tar.add(module,moduleDir)
588 slacapra 1.256 tar.dereference=False
589 slacapra 1.61
590     ## Now check if any data dir(s) is present
591 spiga 1.374 self.dataExist = False
592 slacapra 1.212 todo_list = [(i, i) for i in os.listdir(swArea+"/src")]
593 slacapra 1.206 while len(todo_list):
594     entry, name = todo_list.pop()
595 slacapra 1.211 if name.startswith('crab_0_') or name.startswith('.') or name == 'CVS':
596 slacapra 1.206 continue
597 slacapra 1.212 if os.path.isdir(swArea+"/src/"+entry):
598 slacapra 1.206 entryPath = entry + '/'
599 slacapra 1.212 todo_list += [(entryPath + i, i) for i in os.listdir(swArea+"/src/"+entry)]
600 spiga 1.374 if name == 'data':
601     self.dataExist=True
602     common.logger.debug("data "+entry+" to be tarred")
603     tar.add(swArea+"/src/"+entry,"src/"+entry)
604     pass
605 slacapra 1.206 pass
606 ewv 1.182
607 spiga 1.179 ### CMSSW ParameterSet
608     if not self.pset is None:
609     cfg_file = common.work_space.jobDir()+self.configFilename()
610 ewv 1.357 pickleFile = common.work_space.jobDir()+self.configFilename() + '.pkl'
611 ewv 1.182 tar.add(cfg_file,self.configFilename())
612 ewv 1.357 tar.add(pickleFile,self.configFilename() + '.pkl')
613 ewv 1.313
614 spiga 1.309 try:
615     crab_cfg_file = common.work_space.shareDir()+'/crab.cfg'
616     tar.add(crab_cfg_file,'crab.cfg')
617     except:
618     pass
619 fanzago 1.93
620 fanzago 1.152 ## Add ProdCommon dir to tar
621 slacapra 1.211 prodcommonDir = './'
622     prodcommonPath = os.environ['CRABDIR'] + '/' + 'external/'
623 spiga 1.244 neededStuff = ['ProdCommon/__init__.py','ProdCommon/FwkJobRep', 'ProdCommon/CMSConfigTools', \
624 spiga 1.298 'ProdCommon/Core', 'ProdCommon/MCPayloads', 'IMProv', 'ProdCommon/Storage', \
625     'WMCore/__init__.py','WMCore/Algorithms']
626 slacapra 1.214 for file in neededStuff:
627     tar.add(prodcommonPath+file,prodcommonDir+file)
628 spiga 1.179
629     ##### ML stuff
630     ML_file_list=['report.py', 'DashboardAPI.py', 'Logger.py', 'ProcInfo.py', 'apmon.py']
631     path=os.environ['CRABDIR'] + '/python/'
632     for file in ML_file_list:
633     tar.add(path+file,file)
634    
635     ##### Utils
636 belforte 1.382 Utils_file_list=['parseCrabFjr.py','writeCfg.py', 'fillCrabFjr.py','cmscp.py','crabWatchdog.sh']
637 spiga 1.179 for file in Utils_file_list:
638     tar.add(path+file,file)
639 ewv 1.131
640 ewv 1.182 ##### AdditionalFiles
641 slacapra 1.253 tar.dereference=True
642 spiga 1.179 for file in self.additional_inbox_files:
643     tar.add(file,string.split(file,'/')[-1])
644 slacapra 1.253 tar.dereference=False
645 spiga 1.320 common.logger.log(10-1,"Files in "+self.tgzNameWithPath+" : "+str(tar.getnames()))
646 ewv 1.182
647 slacapra 1.61 tar.close()
648 mcinquil 1.241 except IOError, exc:
649 spiga 1.320 msg = 'Could not create tar-ball %s \n'%self.tgzNameWithPath
650 spiga 1.304 msg += str(exc)
651     raise CrabException(msg)
652 mcinquil 1.241 except tarfile.TarError, exc:
653 spiga 1.320 msg = 'Could not create tar-ball %s \n'%self.tgzNameWithPath
654 spiga 1.304 msg += str(exc)
655     raise CrabException(msg)
656 spiga 1.300
657 gutsche 1.72 tarballinfo = os.stat(self.tgzNameWithPath)
658     if ( tarballinfo.st_size > self.MaxTarBallSize*1024*1024 ) :
659 fanzago 1.385 #### FEDE FOR SAVANNAH BUG 94491 ########
660     cmdOut = runCommand('tar -ztvf %s|sort -n -k3'%self.tgzNameWithPath)
661 spiga 1.365 if not self.server:
662     msg = 'Input sandbox size of ' + str(float(tarballinfo.st_size)/1024.0/1024.0) + ' MB is larger than the allowed ' + \
663     str(self.MaxTarBallSize) +'MB input sandbox limit \n'
664     msg += ' and not supported by the direct GRID submission system.\n'
665     msg += ' Please use the CRAB server mode by setting server_name=<NAME> in section [CRAB] of your crab.cfg.\n'
666     msg += ' For further infos please see https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideCrabServerForUsers#Server_available_for_users'
667 fanzago 1.385 msg += ' Content of your default.tgz archive is \n'
668     msg += cmdOut
669 ewv 1.367 else:
670 spiga 1.365 msg = 'Input sandbox size of ' + str(float(tarballinfo.st_size)/1024.0/1024.0) + ' MB is larger than the allowed ' + \
671     str(self.MaxTarBallSize) +'MB input sandbox limit in the server.'
672 fanzago 1.385 msg += 'Content of your default.tgz archive is \n'
673     msg += cmdOut
674 spiga 1.238 raise CrabException(msg)
675 gutsche 1.72
676 slacapra 1.61 ## create tar-ball with ML stuff
677 slacapra 1.97
678 spiga 1.165 def wsSetupEnvironment(self, nj=0):
679 slacapra 1.1 """
680     Returns part of a job script which prepares
681     the execution environment for the job 'nj'.
682     """
683 ewv 1.334 psetName = 'pset.py'
684    
685 slacapra 1.1 # Prepare JobType-independent part
686 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupEnvironment\n'
687 fanzago 1.133 txt += 'echo ">>> setup environment"\n'
688 ewv 1.347 txt += 'echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
689     txt += 'export SCRAM_ARCH=' + self.executable_arch + '\n'
690     txt += 'echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
691 spiga 1.290 txt += 'if [ $middleware == LCG ] || [ $middleware == CAF ] || [ $middleware == LSF ]; then \n'
692 gutsche 1.3 txt += self.wsSetupCMSLCGEnvironment_()
693 ewv 1.283 txt += 'elif [ $middleware == OSG ]; then\n'
694 gutsche 1.43 txt += ' WORKING_DIR=`/bin/mktemp -d $OSG_WN_TMP/cms_XXXXXXXXXXXX`\n'
695 ewv 1.132 txt += ' if [ ! $? == 0 ] ;then\n'
696 fanzago 1.161 txt += ' echo "ERROR ==> OSG $WORKING_DIR could not be created on WN `hostname`"\n'
697     txt += ' job_exit_code=10016\n'
698     txt += ' func_exit\n'
699 gutsche 1.3 txt += ' fi\n'
700 fanzago 1.133 txt += ' echo ">>> Created working directory: $WORKING_DIR"\n'
701 gutsche 1.3 txt += '\n'
702     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
703     txt += ' cd $WORKING_DIR\n'
704 fanzago 1.133 txt += ' echo ">>> current directory (WORKING_DIR): $WORKING_DIR"\n'
705 ewv 1.131 txt += self.wsSetupCMSOSGEnvironment_()
706 spiga 1.282 #Setup SGE Environment
707 ewv 1.283 txt += 'elif [ $middleware == SGE ]; then\n'
708 spiga 1.282 txt += self.wsSetupCMSLCGEnvironment_()
709    
710 edelmann 1.289 txt += 'elif [ $middleware == ARC ]; then\n'
711     txt += self.wsSetupCMSLCGEnvironment_()
712    
713 mcinquil 1.340 #Setup PBS Environment
714 mcinquil 1.343 txt += 'elif [ $middleware == PBS ]; then\n'
715 mcinquil 1.340 txt += self.wsSetupCMSLCGEnvironment_()
716    
717 gutsche 1.3 txt += 'fi\n'
718 slacapra 1.1
719     # Prepare JobType-specific part
720     scram = self.scram.commandName()
721     txt += '\n\n'
722 fanzago 1.133 txt += 'echo ">>> specific cmssw setup environment:"\n'
723     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
724 slacapra 1.1 txt += scram+' project CMSSW '+self.version+'\n'
725     txt += 'status=$?\n'
726     txt += 'if [ $status != 0 ] ; then\n'
727 fanzago 1.161 txt += ' echo "ERROR ==> CMSSW '+self.version+' not found on `hostname`" \n'
728     txt += ' job_exit_code=10034\n'
729 fanzago 1.163 txt += ' func_exit\n'
730 slacapra 1.1 txt += 'fi \n'
731     txt += 'cd '+self.version+'\n'
732 spiga 1.277 txt += 'SOFTWARE_DIR=`pwd`; export SOFTWARE_DIR\n'
733 fanzago 1.133 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
734 slacapra 1.1 txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
735 fanzago 1.180 txt += 'if [ $? != 0 ] ; then\n'
736     txt += ' echo "ERROR ==> Problem with the command: "\n'
737     txt += ' echo "eval \`'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME \` at `hostname`"\n'
738     txt += ' job_exit_code=10034\n'
739     txt += ' func_exit\n'
740     txt += 'fi \n'
741 slacapra 1.1 # Handle the arguments:
742     txt += "\n"
743 farinafa 1.346 txt += "## number of arguments (first argument always jobnumber, the second is the resubmission number)\n"
744 slacapra 1.1 txt += "\n"
745 spiga 1.165 txt += "if [ $nargs -lt "+str(self.argsList)+" ]\n"
746 slacapra 1.1 txt += "then\n"
747 fanzago 1.161 txt += " echo 'ERROR ==> Too few arguments' +$nargs+ \n"
748     txt += ' job_exit_code=50113\n'
749     txt += " func_exit\n"
750 slacapra 1.1 txt += "fi\n"
751     txt += "\n"
752    
753     # Prepare job-specific part
754     job = common.job_list[nj]
755 ewv 1.131 if (self.datasetPath):
756 fanzago 1.93 txt += '\n'
757     txt += 'DatasetPath='+self.datasetPath+'\n'
758    
759 spiga 1.238 txt += 'PrimaryDataset='+self.primaryDataset +'\n'
760 fanzago 1.318 txt += 'DataTier='+self.dataTier+'\n'
761 fanzago 1.96 txt += 'ApplicationFamily=cmsRun\n'
762 fanzago 1.93
763     else:
764     txt += 'DatasetPath=MCDataTier\n'
765     txt += 'PrimaryDataset=null\n'
766     txt += 'DataTier=null\n'
767     txt += 'ApplicationFamily=MCDataTier\n'
768 ewv 1.170 if self.pset != None:
769 spiga 1.42 pset = os.path.basename(job.configFilename())
770 ewv 1.357 pkl = os.path.basename(job.configFilename()) + '.pkl'
771 spiga 1.42 txt += '\n'
772 spiga 1.95 txt += 'cp $RUNTIME_AREA/'+pset+' .\n'
773 ewv 1.357 txt += 'cp $RUNTIME_AREA/'+pkl+' .\n'
774 spiga 1.296
775 ewv 1.295 txt += 'PreserveSeeds=' + ','.join(self.preserveSeeds) + '; export PreserveSeeds\n'
776     txt += 'IncrementSeeds=' + ','.join(self.incrementSeeds) + '; export IncrementSeeds\n'
777     txt += 'echo "PreserveSeeds: <$PreserveSeeds>"\n'
778     txt += 'echo "IncrementSeeds:<$IncrementSeeds>"\n'
779 slacapra 1.90
780 ewv 1.184 txt += 'mv -f ' + pset + ' ' + psetName + '\n'
781 fanzago 1.360 if self.var_filter:
782     #print "self.var_filter = ",self.var_filter
783     txt += "export var_filter="+"'"+self.var_filter+"'\n"
784     txt += 'echo $var_filter'
785 ewv 1.319 else:
786 spiga 1.314 txt += '\n'
787 spiga 1.331 if self.AdditionalArgs: txt += 'export AdditionalArgs=\"%s\"\n'%(self.AdditionalArgs)
788 spiga 1.315 if int(self.NumEvents) != 0: txt += 'export MaxEvents=%s\n'%str(self.NumEvents)
789 gutsche 1.3 return txt
790 slacapra 1.176
791 fanzago 1.166 def wsUntarSoftware(self, nj=0):
792 gutsche 1.3 """
793     Put in the script the commands to build an executable
794     or a library.
795     """
796    
797 fanzago 1.166 txt = '\n#Written by cms_cmssw::wsUntarSoftware\n'
798 gutsche 1.3
799     if os.path.isfile(self.tgzNameWithPath):
800 spiga 1.358 txt += 'echo ">>> tar xzf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+' :" \n'
801 belforte 1.382 txt += 'tar xzf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
802 fanzago 1.375 txt += 'untar_status=$? \n'
803 fanzago 1.285 if self.debug_wrapper==1 :
804 fanzago 1.375 txt += 'echo "----------------" \n'
805     txt += 'ls -AlR $RUNTIME_AREA \n'
806     txt += 'echo "----------------" \n'
807 gutsche 1.3 txt += 'if [ $untar_status -ne 0 ]; then \n'
808 fanzago 1.161 txt += ' echo "ERROR ==> Untarring .tgz file failed"\n'
809     txt += ' job_exit_code=$untar_status\n'
810     txt += ' func_exit\n'
811 gutsche 1.3 txt += 'else \n'
812     txt += ' echo "Successful untar" \n'
813 fanzago 1.375 txt += ' chmod a+w -R $RUNTIME_AREA \n'
814 belforte 1.379 txt += ' chmod 600 $X509_USER_PROXY \n'
815 fanzago 1.375 if self.debug_wrapper==1 :
816     txt += ' echo "changed in a+w the permission of $RUNTIME_AREA "\n'
817     txt += ' ls -AlR $RUNTIME_AREA \n'
818 gutsche 1.3 txt += 'fi \n'
819 gutsche 1.50 txt += '\n'
820 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
821 gutsche 1.50 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
822 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
823 gutsche 1.50 txt += 'else\n'
824 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
825 fanzago 1.93 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
826 gutsche 1.50 txt += 'fi\n'
827     txt += '\n'
828    
829 gutsche 1.3 pass
830 ewv 1.131
831 slacapra 1.1 return txt
832 ewv 1.170
833 fanzago 1.166 def wsBuildExe(self, nj=0):
834     """
835     Put in the script the commands to build an executable
836     or a library.
837     """
838    
839     txt = '\n#Written by cms_cmssw::wsBuildExe\n'
840     txt += 'echo ">>> moving CMSSW software directories in `pwd`" \n'
841 fanzago 1.375
842     txt += 'rm -rf lib/ module/ \n'
843 ewv 1.170 txt += 'mv $RUNTIME_AREA/lib/ . \n'
844     txt += 'mv $RUNTIME_AREA/module/ . \n'
845 spiga 1.374 if self.dataExist == True:
846 fanzago 1.375 txt += 'rm -rf src/ \n'
847 spiga 1.374 txt += 'mv $RUNTIME_AREA/src/ . \n'
848 ewv 1.182 if len(self.additional_inbox_files)>0:
849 spiga 1.179 for file in self.additional_inbox_files:
850 spiga 1.191 txt += 'mv $RUNTIME_AREA/'+os.path.basename(file)+' . \n'
851 ewv 1.170
852 slacapra 1.211 txt += 'echo ">>> Include $RUNTIME_AREA in PYTHONPATH:"\n'
853 fanzago 1.166 txt += 'if [ -z "$PYTHONPATH" ]; then\n'
854 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/\n'
855 fanzago 1.166 txt += 'else\n'
856 slacapra 1.211 txt += ' export PYTHONPATH=$RUNTIME_AREA/:${PYTHONPATH}\n'
857 fanzago 1.166 txt += 'echo "PYTHONPATH=$PYTHONPATH"\n'
858     txt += 'fi\n'
859     txt += '\n'
860    
861 slacapra 1.302 if self.pset != None:
862 ewv 1.334 psetName = 'pset.py'
863    
864 slacapra 1.302 txt += '\n'
865     if self.debug_wrapper == 1:
866     txt += 'echo "***** cat ' + psetName + ' *********"\n'
867     txt += 'cat ' + psetName + '\n'
868     txt += 'echo "****** end ' + psetName + ' ********"\n'
869     txt += '\n'
870     txt += 'echo "***********************" \n'
871     txt += 'which edmConfigHash \n'
872     txt += 'echo "***********************" \n'
873 ewv 1.334 txt += 'edmConfigHash ' + psetName + ' \n'
874     txt += 'PSETHASH=`edmConfigHash ' + psetName + '` \n'
875 slacapra 1.302 txt += 'echo "PSETHASH = $PSETHASH" \n'
876 fanzago 1.368 #### temporary fix for noEdm files #####
877 slacapra 1.302 txt += 'if [ -z "$PSETHASH" ]; then \n'
878     txt += ' export PSETHASH=null\n'
879     txt += 'fi \n'
880     #############################################
881     txt += '\n'
882 fanzago 1.166 return txt
883 slacapra 1.1
884 ewv 1.131
885 slacapra 1.1 def executableName(self):
886 ewv 1.192 if self.scriptExe:
887 spiga 1.42 return "sh "
888     else:
889     return self.executable
890 slacapra 1.1
891     def executableArgs(self):
892 ewv 1.276 if self.scriptExe:
893 spiga 1.370 return os.path.basename(self.scriptExe) + " $NJob $AdditionalArgs"
894 fanzago 1.115 else:
895 ewv 1.334 return " -j $RUNTIME_AREA/crab_fjr_$NJob.xml -p pset.py"
896 slacapra 1.1
897     def inputSandbox(self, nj):
898     """
899     Returns a list of filenames to be put in JDL input sandbox.
900     """
901     inp_box = []
902     if os.path.isfile(self.tgzNameWithPath):
903     inp_box.append(self.tgzNameWithPath)
904 spiga 1.320 if os.path.isfile(self.argsFile):
905     inp_box.append(self.argsFile)
906 spiga 1.243 inp_box.append(common.work_space.jobDir() + self.scriptName)
907 slacapra 1.1 return inp_box
908    
909     def outputSandbox(self, nj):
910     """
911     Returns a list of filenames to be put in JDL output sandbox.
912     """
913     out_box = []
914    
915     ## User Declared output files
916 slacapra 1.54 for out in (self.output_file+self.output_file_sandbox):
917 ewv 1.131 n_out = nj + 1
918 slacapra 1.207 out_box.append(numberFile(out,str(n_out)))
919 slacapra 1.1 return out_box
920    
921    
922     def wsRenameOutput(self, nj):
923     """
924     Returns part of a job script which renames the produced files.
925     """
926    
927 ewv 1.160 txt = '\n#Written by cms_cmssw::wsRenameOutput\n'
928 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
929     txt += 'echo ">>> current directory content:"\n'
930 fanzago 1.378 #if self.debug_wrapper==1:
931     txt += 'ls -Al\n'
932 fanzago 1.145 txt += '\n'
933 slacapra 1.54
934 fanzago 1.128 for fileWithSuffix in (self.output_file):
935 farinafa 1.346 output_file_num = numberFile(fileWithSuffix, '$OutUniqueID')
936 slacapra 1.1 txt += '\n'
937 gutsche 1.7 txt += '# check output file\n'
938 slacapra 1.106 txt += 'if [ -e ./'+fileWithSuffix+' ] ; then\n'
939 ewv 1.147 if (self.copy_data == 1): # For OSG nodes, file is in $WORKING_DIR, should not be moved to $RUNTIME_AREA
940     txt += ' mv '+fileWithSuffix+' '+output_file_num+'\n'
941 spiga 1.209 txt += ' ln -s `pwd`/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
942 ewv 1.147 else:
943     txt += ' mv '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
944     txt += ' ln -s $RUNTIME_AREA/'+output_file_num+' $RUNTIME_AREA/'+fileWithSuffix+'\n'
945 slacapra 1.106 txt += 'else\n'
946 fanzago 1.161 txt += ' job_exit_code=60302\n'
947     txt += ' echo "WARNING: Output file '+fileWithSuffix+' not found"\n'
948 ewv 1.156 if common.scheduler.name().upper() == 'CONDOR_G':
949 gutsche 1.7 txt += ' if [ $middleware == OSG ]; then \n'
950     txt += ' echo "prepare dummy output file"\n'
951     txt += ' echo "Processing of job output failed" > $RUNTIME_AREA/'+output_file_num+'\n'
952     txt += ' fi \n'
953 slacapra 1.1 txt += 'fi\n'
954 slacapra 1.105 file_list = []
955     for fileWithSuffix in (self.output_file):
956 farinafa 1.346 file_list.append(numberFile('$SOFTWARE_DIR/'+fileWithSuffix, '$OutUniqueID'))
957 ewv 1.131
958 spiga 1.245 txt += 'file_list="'+string.join(file_list,',')+'"\n'
959 fanzago 1.149 txt += '\n'
960 fanzago 1.148 txt += 'echo ">>> current directory (SOFTWARE_DIR): $SOFTWARE_DIR" \n'
961     txt += 'echo ">>> current directory content:"\n'
962 fanzago 1.378 #if self.debug_wrapper==1:
963     txt += 'ls -Al\n'
964 fanzago 1.148 txt += '\n'
965 gutsche 1.7 txt += 'cd $RUNTIME_AREA\n'
966 fanzago 1.133 txt += 'echo ">>> current directory (RUNTIME_AREA): $RUNTIME_AREA"\n'
967 slacapra 1.1 return txt
968    
969 slacapra 1.63 def getRequirements(self, nj=[]):
970 slacapra 1.1 """
971 ewv 1.131 return job requirements to add to jdl files
972 slacapra 1.1 """
973     req = ''
974 slacapra 1.47 if self.version:
975 slacapra 1.10 req='Member("VO-cms-' + \
976 slacapra 1.47 self.version + \
977 slacapra 1.10 '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
978 ewv 1.192 if self.executable_arch:
979 gutsche 1.107 req+=' && Member("VO-cms-' + \
980 slacapra 1.105 self.executable_arch + \
981     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
982 gutsche 1.35
983     req = req + ' && (other.GlueHostNetworkAdapterOutboundIP)'
984 spiga 1.353 if ( common.scheduler.name() in ["glite"] ):
985 slacapra 1.316 ## 25-Jun-2009 SL: patch to use Cream enabled WMS
986     if ( self.cfg_params.get('GRID.use_cream',None) ):
987     req += ' && (other.GlueCEStateStatus == "Production" || other.GlueCEStateStatus == "Special")'
988     else:
989     req += ' && other.GlueCEStateStatus == "Production" '
990 gutsche 1.35
991 slacapra 1.1 return req
992 gutsche 1.3
993     def configFilename(self):
994     """ return the config filename """
995 ewv 1.334 return self.name()+'.py'
996 gutsche 1.3
997     def wsSetupCMSOSGEnvironment_(self):
998     """
999     Returns part of a job script which is prepares
1000     the execution environment and which is common for all CMS jobs.
1001     """
1002 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSOSGEnvironment_\n'
1003     txt += ' echo ">>> setup CMS OSG environment:"\n'
1004 fanzago 1.133 txt += ' echo "set SCRAM ARCH to ' + self.executable_arch + '"\n'
1005     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1006 fanzago 1.136 txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1007 belforte 1.383 txt += ' echo "OSG_APP is $OSG_APP"\n'
1008 ewv 1.135 txt += ' if [ -f $OSG_APP/cmssoft/cms/cmsset_default.sh ] ;then\n'
1009 belforte 1.382 txt += ' cmsSetupFile=$OSG_APP/cmssoft/cms/cmsset_default.sh\n'
1010     txt += ' elif [ -f $CVMFS/cms.cern.ch/cmsset_default.sh ] ; then \n'
1011     txt += ' cmsSetupFile=$CVMFS/cms.cern.ch/cmsset_default.sh\n'
1012     txt += ' elif [ -f /cvmfs/cms.cern.ch/cmsset_default.sh ] ; then \n'
1013     txt += ' cmsSetupFile=/cvmfs/cms.cern.ch/cmsset_default.sh\n'
1014 fanzago 1.133 txt += ' else\n'
1015 belforte 1.383 txt += ' echo "CVMSF = $CVMFS"\n'
1016     txt += ' echo "/cvmfs/ is"\n'
1017     txt += ' echo "ls /"\n'
1018     txt += ' ls /\n'
1019     txt += ' echo "ls /cvmfs"\n'
1020     txt += ' ls /cvmfs\n'
1021     txt += ' echo "ls /cvmfs/cms.cern.ch"\n'
1022     txt += ' ls /cvmfs/cms.cern.ch\n'
1023     txt += ' ls /cvmfs/cms.cern.ch/cmsset*\n'
1024     txt += ' ls /cvmfs/cms.cern.ch/cmsset_default.sh\n'
1025 belforte 1.382 txt += ' echo "ERROR ==> cmsset_default.sh file not found"\n'
1026 fanzago 1.161 txt += ' job_exit_code=10020\n'
1027     txt += ' func_exit\n'
1028 fanzago 1.133 txt += ' fi\n'
1029 gutsche 1.3 txt += '\n'
1030 belforte 1.382 txt += ' echo "sourcing $cmsSetupFile ..."\n'
1031     txt += ' source $cmsSetupFile\n'
1032     txt += ' result=$?\n'
1033     txt += ' if [ $result -ne 0 ]; then\n'
1034     txt += ' echo "ERROR ==> problem sourcing $cmsSetupFile"\n'
1035     txt += ' job_exit_code=10032\n'
1036     txt += ' func_exit\n'
1037     txt += ' else\n'
1038     txt += ' echo "==> setup cms environment ok"\n'
1039     txt += ' echo "SCRAM_ARCH = $SCRAM_ARCH"\n'
1040     txt += ' fi\n'
1041 gutsche 1.3
1042     return txt
1043 ewv 1.131
1044 gutsche 1.3 def wsSetupCMSLCGEnvironment_(self):
1045     """
1046     Returns part of a job script which is prepares
1047     the execution environment and which is common for all CMS jobs.
1048     """
1049 ewv 1.160 txt = '\n#Written by cms_cmssw::wsSetupCMSLCGEnvironment_\n'
1050     txt += ' echo ">>> setup CMS LCG environment:"\n'
1051 fanzago 1.133 txt += ' echo "set SCRAM ARCH and BUILD_ARCH to ' + self.executable_arch + ' ###"\n'
1052     txt += ' export SCRAM_ARCH='+self.executable_arch+'\n'
1053     txt += ' export BUILD_ARCH='+self.executable_arch+'\n'
1054     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
1055 fanzago 1.161 txt += ' echo "ERROR ==> CMS software dir not found on WN `hostname`"\n'
1056     txt += ' job_exit_code=10031\n'
1057     txt += ' func_exit\n'
1058 fanzago 1.133 txt += ' else\n'
1059     txt += ' echo "Sourcing environment... "\n'
1060     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
1061 fanzago 1.161 txt += ' echo "ERROR ==> cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
1062     txt += ' job_exit_code=10020\n'
1063     txt += ' func_exit\n'
1064 fanzago 1.133 txt += ' fi\n'
1065     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1066     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
1067     txt += ' result=$?\n'
1068     txt += ' if [ $result -ne 0 ]; then\n'
1069 fanzago 1.161 txt += ' echo "ERROR ==> problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
1070     txt += ' job_exit_code=10032\n'
1071     txt += ' func_exit\n'
1072 fanzago 1.133 txt += ' fi\n'
1073     txt += ' fi\n'
1074     txt += ' \n'
1075 fanzago 1.161 txt += ' echo "==> setup cms environment ok"\n'
1076 gutsche 1.3 return txt
1077 gutsche 1.5
1078 spiga 1.238 def wsModifyReport(self, nj):
1079 fanzago 1.93 """
1080 ewv 1.131 insert the part of the script that modifies the FrameworkJob Report
1081 fanzago 1.93 """
1082 ewv 1.250
1083 fanzago 1.281 txt = ''
1084 fanzago 1.292 if (self.copy_data == 1):
1085 fanzago 1.281 txt = '\n#Written by cms_cmssw::wsModifyReport\n'
1086 ewv 1.283
1087 fanzago 1.175 txt += 'echo ">>> Modify Job Report:" \n'
1088 fanzago 1.217 txt += 'chmod a+x $RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py\n'
1089 fanzago 1.175 txt += 'echo "CMSSW_VERSION = $CMSSW_VERSION"\n\n'
1090 fanzago 1.344
1091 fanzago 1.360 args = 'fjr $RUNTIME_AREA/crab_fjr_$NJob.xml json $RUNTIME_AREA/resultCopyFile n_job $OutUniqueID PrimaryDataset $PrimaryDataset ApplicationFamily $ApplicationFamily ApplicationName $executable cmssw_version $CMSSW_VERSION psethash $PSETHASH'
1092 fanzago 1.281
1093 fanzago 1.318 if (self.publish_data == 1):
1094     txt += 'ProcessedDataset='+self.processedDataset+'\n'
1095 fanzago 1.292 txt += 'echo "ProcessedDataset = $ProcessedDataset"\n'
1096     args += ' UserProcessedDataset $USER-$ProcessedDataset-$PSETHASH'
1097 fanzago 1.281
1098 fanzago 1.247 txt += 'echo "$RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py '+str(args)+'"\n'
1099     txt += '$RUNTIME_AREA/ProdCommon/FwkJobRep/ModifyJobReport.py '+str(args)+'\n'
1100 fanzago 1.175 txt += 'modifyReport_result=$?\n'
1101     txt += 'if [ $modifyReport_result -ne 0 ]; then\n'
1102     txt += ' modifyReport_result=70500\n'
1103     txt += ' job_exit_code=$modifyReport_result\n'
1104     txt += ' echo "ModifyReportResult=$modifyReport_result" | tee -a $RUNTIME_AREA/$repo\n'
1105     txt += ' echo "WARNING: Problem with ModifyJobReport"\n'
1106     txt += 'else\n'
1107     txt += ' mv NewFrameworkJobReport.xml $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1108 spiga 1.103 txt += 'fi\n'
1109 fanzago 1.93 return txt
1110 ewv 1.283
1111 ewv 1.192 def wsParseFJR(self):
1112 spiga 1.189 """
1113 ewv 1.192 Parse the FrameworkJobReport to obtain useful infos
1114 spiga 1.189 """
1115     txt = '\n#Written by cms_cmssw::wsParseFJR\n'
1116     txt += 'echo ">>> Parse FrameworkJobReport crab_fjr.xml"\n'
1117     txt += 'if [ -s $RUNTIME_AREA/crab_fjr_$NJob.xml ]; then\n'
1118     txt += ' if [ -s $RUNTIME_AREA/parseCrabFjr.py ]; then\n'
1119 spiga 1.197 txt += ' cmd_out=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --dashboard $MonitorID,$MonitorJobID '+self.debugWrap+'`\n'
1120 fanzago 1.285 if self.debug_wrapper==1 :
1121 spiga 1.197 txt += ' echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out"\n'
1122 spiga 1.371 txt += ' cmd_out_1=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --popularity $MonitorID,$MonitorJobID,$RUNTIME_AREA/inputsReport.txt '+self.debugWrap+'`\n'
1123 spiga 1.372 # if self.debug_wrapper==1 :
1124     txt += ' echo "Result of parsing the FrameworkJobReport crab_fjr.xml: $cmd_out_1"\n'
1125 spiga 1.197 txt += ' executable_exit_status=`python $RUNTIME_AREA/parseCrabFjr.py --input $RUNTIME_AREA/crab_fjr_$NJob.xml --exitcode`\n'
1126 spiga 1.189 txt += ' if [ $executable_exit_status -eq 50115 ];then\n'
1127     txt += ' echo ">>> crab_fjr.xml contents: "\n'
1128 spiga 1.222 txt += ' cat $RUNTIME_AREA/crab_fjr_$NJob.xml\n'
1129 spiga 1.189 txt += ' echo "Wrong FrameworkJobReport --> does not contain useful info. ExitStatus: $executable_exit_status"\n'
1130 spiga 1.197 txt += ' elif [ $executable_exit_status -eq -999 ];then\n'
1131     txt += ' echo "ExitStatus from FrameworkJobReport not available. not available. Using exit code of executable from command line."\n'
1132 spiga 1.189 txt += ' else\n'
1133     txt += ' echo "Extracted ExitStatus from FrameworkJobReport parsing output: $executable_exit_status"\n'
1134     txt += ' fi\n'
1135     txt += ' else\n'
1136     txt += ' echo "CRAB python script to parse CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1137     txt += ' fi\n'
1138     #### Patch to check input data reading for CMSSW16x Hopefully we-ll remove it asap
1139 spiga 1.232 txt += ' if [ $executable_exit_status -eq 0 ];then\n'
1140 fanzago 1.273 txt += ' echo ">>> Executable succeded $executable_exit_status"\n'
1141 spiga 1.232 txt += ' fi\n'
1142 spiga 1.189 txt += 'else\n'
1143     txt += ' echo "CRAB FrameworkJobReport crab_fjr.xml is not available, using exit code of executable from command line."\n'
1144     txt += 'fi\n'
1145     txt += '\n'
1146 fanzago 1.364 txt += 'if [ $executable_exit_status -ne 0 ];then\n'
1147 fanzago 1.273 txt += ' echo ">>> Executable failed $executable_exit_status"\n'
1148     txt += ' echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1149     txt += ' echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1150     txt += ' job_exit_code=$executable_exit_status\n'
1151     txt += ' func_exit\n'
1152     txt += 'fi\n\n'
1153 spiga 1.189 txt += 'echo "ExeExitCode=$executable_exit_status" | tee -a $RUNTIME_AREA/$repo\n'
1154     txt += 'echo "EXECUTABLE_EXIT_STATUS = $executable_exit_status"\n'
1155     txt += 'job_exit_code=$executable_exit_status\n'
1156    
1157     return txt
1158    
1159 gutsche 1.5 def setParam_(self, param, value):
1160     self._params[param] = value
1161    
1162     def getParams(self):
1163     return self._params
1164 gutsche 1.8
1165 spiga 1.257 def outList(self,list=False):
1166 mcinquil 1.121 """
1167     check the dimension of the output files
1168     """
1169 spiga 1.169 txt = ''
1170     txt += 'echo ">>> list of expected files on output sandbox"\n'
1171 mcinquil 1.121 listOutFiles = []
1172 ewv 1.170 stdout = 'CMSSW_$NJob.stdout'
1173 spiga 1.169 stderr = 'CMSSW_$NJob.stderr'
1174 spiga 1.268 if len(self.output_file) <= 0:
1175     msg ="WARNING: no output files name have been defined!!\n"
1176     msg+="\tno output files will be reported back/staged\n"
1177 spiga 1.304 common.logger.info(msg)
1178 ewv 1.350
1179 fanzago 1.148 if (self.return_data == 1):
1180 farinafa 1.348 for file in (self.output_file):
1181     listOutFiles.append(numberFile(file, '$OutUniqueID'))
1182     for file in (self.output_file_sandbox):
1183     listOutFiles.append(numberFile(file, '$NJob'))
1184     listOutFiles.append(stdout)
1185     listOutFiles.append(stderr)
1186 belforte 1.384 listOutFiles.append('Watchdog_$NJob.log.gz')
1187 farinafa 1.348
1188 fanzago 1.161 txt += 'echo "output files: '+string.join(listOutFiles,' ')+'"\n'
1189 spiga 1.157 txt += 'filesToCheck="'+string.join(listOutFiles,' ')+'"\n'
1190 spiga 1.169 txt += 'export filesToCheck\n'
1191 spiga 1.341 taskinfo={}
1192     taskinfo['outfileBasename'] = self.output_file
1193     common._db.updateTask_(taskinfo)
1194 ewv 1.276
1195 spiga 1.257 if list : return self.output_file
1196 ewv 1.170 return txt
1197 ewv 1.355
1198 fanzago 1.369 def checkCMSSWVersion(self, url = "https://cmstags.cern.ch/tc/", fileName = "ReleasesXML"):
1199 ewv 1.355 """
1200     compare current CMSSW release and arch with allowed releases
1201     """
1202    
1203     downloader = Downloader(url)
1204     goodRelease = False
1205 ewv 1.367 tagCollectorUrl = url + fileName
1206 ewv 1.355
1207     try:
1208     result = downloader.config(fileName)
1209     except:
1210     common.logger.info("ERROR: Problem reading file of allowed CMSSW releases.")
1211    
1212     try:
1213     events = pulldom.parseString(result)
1214    
1215     arch = None
1216     release = None
1217     relState = None
1218     for (event, node) in events:
1219     if event == pulldom.START_ELEMENT:
1220     if node.tagName == 'architecture':
1221     arch = node.attributes.getNamedItem('name').nodeValue
1222     if node.tagName == 'project':
1223     relState = node.attributes.getNamedItem('state').nodeValue
1224 ewv 1.367 if relState == 'Announced':
1225 ewv 1.355 release = node.attributes.getNamedItem('label').nodeValue
1226     if self.executable_arch == arch and self.version == release:
1227     goodRelease = True
1228     return goodRelease
1229    
1230     if not goodRelease:
1231 ewv 1.367 msg = "WARNING: %s on %s is not among supported releases listed at %s ." % \
1232     (self.version, self.executable_arch, tagCollectorUrl)
1233 ewv 1.355 msg += "Submission may fail."
1234     common.logger.info(msg)
1235     except:
1236     common.logger.info("Problems parsing file of allowed CMSSW releases.")
1237    
1238     return goodRelease
1239