ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.4
Committed: Tue May 30 00:48:37 2006 UTC (18 years, 11 months ago) by afanfani
Content type: text/x-python
Branch: MAIN
Changes since 1.3: +4 -3 lines
Log Message:
add optional (secret) switches for DLS type (both in ORCA and CMSSW jobtype) and for DBS instances (in CMSSW jobtype).

File Contents

# User Rev Content
1 slacapra 1.1 from JobType import JobType
2     from crab_logger import Logger
3     from crab_exceptions import *
4     from crab_util import *
5     import common
6 gutsche 1.3 import PsetManipulator
7 slacapra 1.1
8 gutsche 1.3 import DBSInfo_EDM
9     #from DataDiscovery_EDM import DataDiscovery_EDM
10     import DataDiscovery_EDM
11     #from DataLocation_EDM import DataLocation_EDM
12     import DataLocation_EDM
13 slacapra 1.1 import Scram
14    
15     import os, string, re
16    
17     class Cmssw(JobType):
18     def __init__(self, cfg_params):
19     JobType.__init__(self, 'CMSSW')
20     common.logger.debug(3,'CMSSW::__init__')
21    
22     self.analisys_common_info = {}
23 gutsche 1.3 # Marco.
24     self._params = {}
25     self.cfg_params = cfg_params
26 slacapra 1.1
27     log = common.logger
28    
29     self.scram = Scram.Scram(cfg_params)
30     scramArea = ''
31     self.additional_inbox_files = []
32     self.scriptExe = ''
33     self.executable = ''
34     self.tgz_name = 'default.tgz'
35    
36 gutsche 1.3
37 slacapra 1.1 self.version = self.scram.getSWVersion()
38     common.analisys_common_info['sw_version'] = self.version
39 gutsche 1.3 ### FEDE
40     common.analisys_common_info['copy_input_data'] = 0
41     common.analisys_common_info['events_management'] = 1
42 slacapra 1.1
43     ### collect Data cards
44     try:
45 gutsche 1.3 # self.owner = cfg_params['CMSSW.owner']
46     # log.debug(6, "CMSSW::CMSSW(): owner = "+self.owner)
47     # self.dataset = cfg_params['CMSSW.dataset']
48     self.datasetPath = cfg_params['CMSSW.datasetpath']
49     log.debug(6, "CMSSW::CMSSW(): datasetPath = "+self.datasetPath)
50 slacapra 1.1 except KeyError:
51 gutsche 1.3 # msg = "Error: owner and/or dataset not defined "
52     msg = "Error: datasetpath not defined "
53 slacapra 1.1 raise CrabException(msg)
54     self.dataTiers = []
55 gutsche 1.3 # try:
56     # tmpDataTiers = string.split(cfg_params['CMSSW.data_tier'],',')
57     # for tmp in tmpDataTiers:
58     # tmp=string.strip(tmp)
59     # self.dataTiers.append(tmp)
60     # pass
61     # pass
62     # except KeyError:
63     # pass
64     # log.debug(6, "Cmssw::Cmssw(): dataTiers = "+str(self.dataTiers))
65 slacapra 1.1
66     ## now the application
67     try:
68     self.executable = cfg_params['CMSSW.executable']
69     log.debug(6, "CMSSW::CMSSW(): executable = "+self.executable)
70     msg = "Default executable cmsRun overridden. Switch to " + self.executable
71     log.debug(3,msg)
72     except KeyError:
73     self.executable = 'cmsRun'
74     msg = "User executable not defined. Use cmsRun"
75     log.debug(3,msg)
76     pass
77    
78     try:
79     self.pset = cfg_params['CMSSW.pset']
80     log.debug(6, "Cmssw::Cmssw(): PSet file = "+self.pset)
81     if (not os.path.exists(self.pset)):
82     raise CrabException("User defined PSet file "+self.pset+" does not exist")
83     except KeyError:
84     raise CrabException("PSet file missing. Cannot run cmsRun ")
85    
86     # output files
87     try:
88     self.output_file = []
89    
90     tmp = cfg_params['CMSSW.output_file']
91     if tmp != '':
92     tmpOutFiles = string.split(cfg_params['CMSSW.output_file'],',')
93     log.debug(7, 'cmssw::cmssw(): output files '+str(tmpOutFiles))
94     for tmp in tmpOutFiles:
95     tmp=string.strip(tmp)
96     self.output_file.append(tmp)
97     pass
98     else:
99     log.message("No output file defined: only stdout/err will be available")
100     pass
101     pass
102     except KeyError:
103     log.message("No output file defined: only stdout/err will be available")
104     pass
105    
106     # script_exe file as additional file in inputSandbox
107     try:
108 gutsche 1.3 self.scriptExe = cfg_params['USER.script_exe']
109 slacapra 1.1 self.additional_inbox_files.append(self.scriptExe)
110     except KeyError:
111     pass
112     if self.scriptExe != '':
113     if os.path.isfile(self.scriptExe):
114     pass
115     else:
116     log.message("WARNING. file "+self.scriptExe+" not found")
117     sys.exit()
118    
119     ## additional input files
120     try:
121     tmpAddFiles = string.split(cfg_params['CMSSW.additional_input_files'],',')
122     for tmp in tmpAddFiles:
123 gutsche 1.3 if not os.path.exists(tmp):
124     raise CrabException("Additional input file not found: "+tmp)
125 slacapra 1.1 tmp=string.strip(tmp)
126     self.additional_inbox_files.append(tmp)
127     pass
128     pass
129     except KeyError:
130     pass
131    
132     try:
133 gutsche 1.3 self.filesPerJob = int(cfg_params['CMSSW.files_per_jobs']) #Daniele
134     except KeyError:
135     self.filesPerJob = 1
136    
137     ## Max event will be total_number_of_events ??? Daniele
138     try:
139     self.maxEv = cfg_params['CMSSW.event_per_job']
140     except KeyError:
141     self.maxEv = "-1"
142     ##
143     try:
144 slacapra 1.1 self.total_number_of_events = int(cfg_params['CMSSW.total_number_of_events'])
145     except KeyError:
146 gutsche 1.3 msg = 'Must define total_number_of_events'
147 slacapra 1.1 raise CrabException(msg)
148    
149     CEBlackList = []
150     try:
151     tmpBad = string.split(cfg_params['EDG.ce_black_list'],',')
152     for tmp in tmpBad:
153     tmp=string.strip(tmp)
154     CEBlackList.append(tmp)
155     except KeyError:
156     pass
157    
158     self.reCEBlackList=[]
159     for bad in CEBlackList:
160     self.reCEBlackList.append(re.compile( bad ))
161    
162     common.logger.debug(5,'CEBlackList: '+str(CEBlackList))
163    
164     CEWhiteList = []
165     try:
166     tmpGood = string.split(cfg_params['EDG.ce_white_list'],',')
167     for tmp in tmpGood:
168     tmp=string.strip(tmp)
169     CEWhiteList.append(tmp)
170     except KeyError:
171     pass
172    
173     #print 'CEWhiteList: ',CEWhiteList
174     self.reCEWhiteList=[]
175     for Good in CEWhiteList:
176     self.reCEWhiteList.append(re.compile( Good ))
177    
178     common.logger.debug(5,'CEWhiteList: '+str(CEWhiteList))
179    
180 gutsche 1.3 self.PsetEdit = PsetManipulator.PsetManipulator(self.pset) #Daniele Pset
181    
182 slacapra 1.1 #DBSDLS-start
183     ## Initialize the variables that are extracted from DBS/DLS and needed in other places of the code
184     self.maxEvents=0 # max events available ( --> check the requested nb. of evts in Creator.py)
185     self.DBSPaths={} # all dbs paths requested ( --> input to the site local discovery script)
186     ## Perform the data location and discovery (based on DBS/DLS)
187     self.DataDiscoveryAndLocation(cfg_params)
188     #DBSDLS-end
189    
190     self.tgzNameWithPath = self.getTarBall(self.executable)
191    
192 gutsche 1.3 self.jobSplitting() #Daniele job Splitting
193     self.PsetEdit.maxEvent(self.maxEv) #Daniele
194     self.PsetEdit.inputModule("INPUT") #Daniele
195     self.PsetEdit.psetWriter(self.configFilename())
196    
197 slacapra 1.1 def DataDiscoveryAndLocation(self, cfg_params):
198    
199 gutsche 1.3 common.logger.debug(10,"CMSSW::DataDiscoveryAndLocation()")
200    
201     #datasetPath = "/"+self.owner+"/"+self.dataTiers[0]+"/"+self.dataset
202    
203     datasetPath=self.datasetPath
204    
205     ## TODO
206     dataTiersList = ""
207     dataTiers = dataTiersList.split(',')
208 slacapra 1.1
209     ## Contact the DBS
210     try:
211 afanfani 1.4 self.pubdata=DataDiscovery_EDM.DataDiscovery_EDM(datasetPath, dataTiers, cfg_params)
212 slacapra 1.1 self.pubdata.fetchDBSInfo()
213    
214 gutsche 1.3 except DataDiscovery_EDM.NotExistingDatasetError, ex :
215 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
216     raise CrabException(msg)
217    
218 gutsche 1.3 except DataDiscovery_EDM.NoDataTierinProvenanceError, ex :
219 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS : %s'%ex.getErrorMessage()
220     raise CrabException(msg)
221 gutsche 1.3 except DataDiscovery_EDM.DataDiscoveryError, ex:
222 slacapra 1.1 msg = 'ERROR ***: failed Data Discovery in DBS %s'%ex.getErrorMessage()
223     raise CrabException(msg)
224    
225     ## get list of all required data in the form of dbs paths (dbs path = /dataset/datatier/owner)
226 gutsche 1.3 ## self.DBSPaths=self.pubdata.getDBSPaths()
227     common.logger.message("Required data are :"+self.datasetPath)
228    
229     filesbyblock=self.pubdata.getFiles()
230     self.AllInputFiles=filesbyblock.values()
231     self.files = self.AllInputFiles
232    
233     ## TEMP
234     # self.filesTmp = filesbyblock.values()
235     # self.files = []
236     # locPath='rfio:cmsbose2.bo.infn.it:/flatfiles/SE00/cms/fanfani/ProdTest/'
237     # locPath=''
238     # tmp = []
239     # for file in self.filesTmp[0]:
240     # tmp.append(locPath+file)
241     # self.files.append(tmp)
242     ## END TEMP
243 slacapra 1.1
244     ## get max number of events
245 gutsche 1.3 #common.logger.debug(10,"number of events for primary fileblocks %i"%self.pubdata.getMaxEvents())
246 slacapra 1.1 self.maxEvents=self.pubdata.getMaxEvents() ## self.maxEvents used in Creator.py
247     common.logger.message("\nThe number of available events is %s"%self.maxEvents)
248    
249     ## Contact the DLS and build a list of sites hosting the fileblocks
250     try:
251 afanfani 1.4 dataloc=DataLocation_EDM.DataLocation_EDM(filesbyblock.keys(),cfg_params)
252     dataloc.fetchDLSInfo()
253    
254 gutsche 1.3 except DataLocation_EDM.DataLocationError , ex:
255 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
256     raise CrabException(msg)
257    
258     allsites=dataloc.getSites()
259     common.logger.debug(5,"sites are %s"%allsites)
260     sites=self.checkBlackList(allsites)
261     common.logger.debug(5,"sites are (after black list) %s"%sites)
262     sites=self.checkWhiteList(sites)
263     common.logger.debug(5,"sites are (after white list) %s"%sites)
264    
265     if len(sites)==0:
266     msg = 'No sites hosting all the needed data! Exiting... '
267     raise CrabException(msg)
268 gutsche 1.3
269 slacapra 1.1 common.logger.message("List of Sites hosting the data : "+str(sites))
270     common.logger.debug(6, "List of Sites: "+str(sites))
271     common.analisys_common_info['sites']=sites ## used in SchedulerEdg.py in createSchScript
272     return
273 gutsche 1.3
274     def jobSplitting(self):
275     """
276     first implemntation for job splitting
277     """
278     # print 'eventi totali '+str(self.maxEvents)
279     # print 'eventi totali richiesti dallo user '+str(self.total_number_of_events)
280     #print 'files per job '+str(self.filesPerJob)
281     common.logger.message('Required '+str(self.filesPerJob)+' files per job ')
282     common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
283    
284     ## TODO: SL need to have (from DBS) a detailed list of how many events per each file
285     n_tot_files = (len(self.files[0]))
286     ## SL: this is wrong if the files have different number of events
287     evPerFile = int(self.maxEvents)/n_tot_files
288    
289     common.logger.debug(5,'Events per File '+str(evPerFile))
290    
291     ## if asked to process all events, do it
292     if self.total_number_of_events == -1:
293     self.total_number_of_events=self.maxEvents
294     self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
295     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for all available events '+str(self.total_number_of_events)+' events')
296    
297     else:
298     self.total_number_of_files = int(self.total_number_of_events/evPerFile)
299     ## SL: if ask for less event than what is computed to be available on a
300     ## file, process the first file anyhow.
301     if self.total_number_of_files == 0:
302     self.total_number_of_files = self.total_number_of_files + 1
303    
304     common.logger.debug(5,'N files '+str(self.total_number_of_files))
305    
306     check = 0
307    
308     ## Compute the number of jobs
309     #self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
310     self.total_number_of_jobs = int(self.total_number_of_files/self.filesPerJob)
311     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
312    
313     ## is there any remainder?
314     check = int(self.total_number_of_files) - (int(self.total_number_of_jobs)*self.filesPerJob)
315    
316     common.logger.debug(5,'Check '+str(check))
317    
318     if check > 0:
319     self.total_number_of_jobs = self.total_number_of_jobs + 1
320     common.logger.message('Warning: last job will be created with '+str(check)+' files')
321    
322     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for a total of '+str((self.total_number_of_jobs-1)*self.filesPerJob*evPerFile + check*evPerFile)+' events')
323     pass
324    
325     list_of_lists = []
326     for i in xrange(0, int(n_tot_files), self.filesPerJob):
327     list_of_lists.append(self.files[0][i: i+self.filesPerJob])
328    
329     self.list_of_files = list_of_lists
330    
331     return
332    
333     def split(self, jobParams):
334    
335     common.jobDB.load()
336     #### Fabio
337     njobs = self.total_number_of_jobs
338     filelist = self.list_of_files
339     # create the empty structure
340     for i in range(njobs):
341     jobParams.append("")
342    
343     for job in range(njobs):
344     jobParams[job] = filelist[job]
345     common.jobDB.setArguments(job, jobParams[job])
346    
347     common.jobDB.save()
348     return
349    
350     def getJobTypeArguments(self, nj, sched):
351     params = common.jobDB.arguments(nj)
352     #print params
353     parString = "\\{"
354    
355     for i in range(len(params) - 1):
356     parString += '\\\"' + params[i] + '\\\"\,'
357 slacapra 1.1
358 gutsche 1.3 parString += '\\\"' + params[len(params) - 1] + '\\\"\\}'
359     return parString
360    
361     def numberOfJobs(self):
362     # Fabio
363    
364     return self.total_number_of_jobs
365    
366    
367    
368 slacapra 1.1 def checkBlackList(self, allSites):
369     if len(self.reCEBlackList)==0: return allSites
370     sites = []
371     for site in allSites:
372     common.logger.debug(10,'Site '+site)
373     good=1
374     for re in self.reCEBlackList:
375     if re.search(site):
376     common.logger.message('CE in black list, skipping site '+site)
377     good=0
378     pass
379     if good: sites.append(site)
380     if len(sites) == 0:
381     common.logger.debug(3,"No sites found after BlackList")
382     return sites
383    
384 gutsche 1.3 def checkWhiteList(self, allSites):
385 slacapra 1.1
386 gutsche 1.3 if len(self.reCEWhiteList)==0: return allSites
387 slacapra 1.1 sites = []
388 gutsche 1.3 for site in allSites:
389 slacapra 1.1 good=0
390     for re in self.reCEWhiteList:
391     if re.search(site):
392     common.logger.debug(5,'CE in white list, adding site '+site)
393     good=1
394     if not good: continue
395     sites.append(site)
396     if len(sites) == 0:
397     common.logger.message("No sites found after WhiteList\n")
398     else:
399     common.logger.debug(5,"Selected sites via WhiteList are "+str(sites)+"\n")
400     return sites
401    
402     def getTarBall(self, exe):
403     """
404     Return the TarBall with lib and exe
405     """
406    
407     # if it exist, just return it
408     self.tgzNameWithPath = common.work_space.shareDir()+self.tgz_name
409     if os.path.exists(self.tgzNameWithPath):
410     return self.tgzNameWithPath
411    
412     # Prepare a tar gzipped file with user binaries.
413     self.buildTar_(exe)
414    
415     return string.strip(self.tgzNameWithPath)
416    
417     def buildTar_(self, executable):
418    
419     # First of all declare the user Scram area
420     swArea = self.scram.getSWArea_()
421     #print "swArea = ", swArea
422     swVersion = self.scram.getSWVersion()
423     #print "swVersion = ", swVersion
424     swReleaseTop = self.scram.getReleaseTop_()
425     #print "swReleaseTop = ", swReleaseTop
426    
427     ## check if working area is release top
428     if swReleaseTop == '' or swArea == swReleaseTop:
429     return
430    
431     filesToBeTarred = []
432     ## First find the executable
433     if (self.executable != ''):
434     exeWithPath = self.scram.findFile_(executable)
435     # print exeWithPath
436     if ( not exeWithPath ):
437     raise CrabException('User executable '+executable+' not found')
438    
439     ## then check if it's private or not
440     if exeWithPath.find(swReleaseTop) == -1:
441     # the exe is private, so we must ship
442     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
443     path = swArea+'/'
444     exe = string.replace(exeWithPath, path,'')
445     filesToBeTarred.append(exe)
446     pass
447     else:
448     # the exe is from release, we'll find it on WN
449     pass
450    
451     ## Now get the libraries: only those in local working area
452     libDir = 'lib'
453     lib = swArea+'/' +libDir
454     common.logger.debug(5,"lib "+lib+" to be tarred")
455     if os.path.exists(lib):
456     filesToBeTarred.append(libDir)
457    
458 gutsche 1.3 ## Now check if module dir is present
459     moduleDir = 'module'
460     if os.path.isdir(swArea+'/'+moduleDir):
461     filesToBeTarred.append(moduleDir)
462    
463 slacapra 1.1 ## Now check if the Data dir is present
464     dataDir = 'src/Data/'
465     if os.path.isdir(swArea+'/'+dataDir):
466     filesToBeTarred.append(dataDir)
467    
468     ## Create the tar-ball
469     if len(filesToBeTarred)>0:
470     cwd = os.getcwd()
471     os.chdir(swArea)
472     tarcmd = 'tar zcvf ' + self.tgzNameWithPath + ' '
473     for line in filesToBeTarred:
474     tarcmd = tarcmd + line + ' '
475     cout = runCommand(tarcmd)
476     if not cout:
477     raise CrabException('Could not create tar-ball')
478     os.chdir(cwd)
479     else:
480     common.logger.debug(5,"No files to be to be tarred")
481    
482     return
483    
484     def wsSetupEnvironment(self, nj):
485     """
486     Returns part of a job script which prepares
487     the execution environment for the job 'nj'.
488     """
489     # Prepare JobType-independent part
490 gutsche 1.3 txt = ''
491    
492     ## OLI_Daniele at this level middleware already known
493    
494     txt += 'if [ $middleware == LCG ]; then \n'
495     txt += self.wsSetupCMSLCGEnvironment_()
496     txt += 'elif [ $middleware == OSG ]; then\n'
497     txt += ' time=`date -u +"%s"`\n'
498     txt += ' WORKING_DIR=$OSG_WN_TMP/cms_$time\n'
499     txt += ' echo "Creating working directory: $WORKING_DIR"\n'
500     txt += ' /bin/mkdir -p $WORKING_DIR\n'
501     txt += ' if [ ! -d $WORKING_DIR ] ;then\n'
502     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be created on on WN `hostname`"\n'
503    
504     txt += ' echo "JOB_EXIT_STATUS = 1"\n'
505     txt += ' exit 1\n'
506     txt += ' fi\n'
507     txt += '\n'
508     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
509     txt += ' cd $WORKING_DIR\n'
510     txt += self.wsSetupCMSOSGEnvironment_()
511     txt += 'fi\n'
512 slacapra 1.1
513     # Prepare JobType-specific part
514     scram = self.scram.commandName()
515     txt += '\n\n'
516     txt += 'echo "### SPECIFIC JOB SETUP ENVIRONMENT ###"\n'
517     txt += scram+' project CMSSW '+self.version+'\n'
518     txt += 'status=$?\n'
519     txt += 'if [ $status != 0 ] ; then\n'
520     txt += ' echo "SET_EXE_ENV 1 ==>ERROR CMSSW '+self.version+' not found on `hostname`" \n'
521 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10034"\n'
522     txt += ' echo "SanityCheckCode = 10034" | tee -a $RUNTIME_AREA/$repo\n'
523 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
524 gutsche 1.3 ## OLI_Daniele
525     txt += ' if [ $middleware == OSG ]; then \n'
526     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
527     txt += ' cd $RUNTIME_AREA\n'
528     txt += ' /bin/rm -rf $WORKING_DIR\n'
529     txt += ' if [ -d $WORKING_DIR ] ;then\n'
530     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
531     txt += ' fi\n'
532     txt += ' fi \n'
533     txt += ' exit 1 \n'
534 slacapra 1.1 txt += 'fi \n'
535     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
536     txt += 'cd '+self.version+'\n'
537     ### needed grep for bug in scramv1 ###
538     txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
539    
540     # Handle the arguments:
541     txt += "\n"
542     txt += "## ARGUMNETS: $1 Job Number\n"
543     # txt += "## ARGUMNETS: $2 First Event for this job\n"
544     # txt += "## ARGUMNETS: $3 Max Event for this job\n"
545     txt += "\n"
546     txt += "narg=$#\n"
547 gutsche 1.3 txt += "if [ $narg -lt 2 ]\n"
548 slacapra 1.1 txt += "then\n"
549     txt += " echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$narg+ \n"
550 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 50113"\n'
551     txt += ' echo "SanityCheckCode = 50113" | tee -a $RUNTIME_AREA/$repo\n'
552 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
553 gutsche 1.3 ## OLI_Daniele
554     txt += ' if [ $middleware == OSG ]; then \n'
555     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
556     txt += ' cd $RUNTIME_AREA\n'
557     txt += ' /bin/rm -rf $WORKING_DIR\n'
558     txt += ' if [ -d $WORKING_DIR ] ;then\n'
559     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
560     txt += ' fi\n'
561     txt += ' fi \n'
562 slacapra 1.1 txt += " exit 1\n"
563     txt += "fi\n"
564     txt += "\n"
565     txt += "NJob=$1\n"
566 gutsche 1.3 txt += "InputFiles=$2\n"
567     txt += "echo \"<$InputFiles>\"\n"
568     # txt += "Args = ` cat $2 | sed -e \'s/\\\\//g\' -e \'s/\"/\\x27/g\' `"
569    
570     ### OLI_DANIELE
571     txt += 'if [ $middleware == LCG ]; then \n'
572     txt += ' echo "MonitorJobID=`echo ${NJob}_$EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
573     txt += ' echo "SyncGridJobId=`echo $EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
574     txt += ' echo "SyncCE=`edg-brokerinfo getCE`" | tee -a $RUNTIME_AREA/$repo\n'
575     txt += 'elif [ $middleware == OSG ]; then\n'
576    
577     # OLI: added monitoring for dashbord, use hash of crab.cfg
578     if common.scheduler.boss_scheduler_name == 'condor_g':
579     # create hash of cfg file
580     hash = makeCksum(common.work_space.cfgFileName())
581     txt += ' echo "MonitorJobID=`echo ${NJob}_'+hash+'_$GLOBUS_GRAM_JOB_CONTACT`" | tee -a $RUNTIME_AREA/$repo\n'
582     txt += ' echo "SyncGridJobId=`echo $GLOBUS_GRAM_JOB_CONTACT`" | tee -a $RUNTIME_AREA/$repo\n'
583     txt += ' echo "SyncCE=`echo $hostname`" | tee -a $RUNTIME_AREA/$repo\n'
584     else :
585     txt += ' echo "MonitorJobID=`echo ${NJob}_$EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
586     txt += ' echo "SyncGridJobId=`echo $EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
587     txt += ' echo "SyncCE=`$EDG_WL_LOG_DESTINATION`" | tee -a $RUNTIME_AREA/$repo\n'
588    
589     txt += 'fi\n'
590     txt += 'dumpStatus $RUNTIME_AREA/$repo\n'
591 slacapra 1.1
592     # Prepare job-specific part
593     job = common.job_list[nj]
594     pset = os.path.basename(job.configFilename())
595     txt += '\n'
596 gutsche 1.3 #txt += 'echo sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' \n'
597     txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
598     #txt += 'sed "s#{\'INPUT\'}#${InputFiles}#" $RUNTIME_AREA/'+pset+' > pset1.cfg\n'
599 slacapra 1.1
600     if len(self.additional_inbox_files) > 0:
601     for file in self.additional_inbox_files:
602     txt += 'if [ -e $RUNTIME_AREA/'+file+' ] ; then\n'
603     txt += ' cp $RUNTIME_AREA/'+file+' .\n'
604     txt += ' chmod +x '+file+'\n'
605     txt += 'fi\n'
606     pass
607    
608     txt += 'echo "### END JOB SETUP ENVIRONMENT ###"\n\n'
609    
610     txt += '\n'
611     txt += 'echo "***** cat pset.cfg *********"\n'
612     txt += 'cat pset.cfg\n'
613     txt += 'echo "****** end pset.cfg ********"\n'
614 gutsche 1.3 txt += '\n'
615     # txt += 'echo "***** cat pset1.cfg *********"\n'
616     # txt += 'cat pset1.cfg\n'
617     # txt += 'echo "****** end pset1.cfg ********"\n'
618     return txt
619    
620     def wsBuildExe(self, nj):
621     """
622     Put in the script the commands to build an executable
623     or a library.
624     """
625    
626     txt = ""
627    
628     if os.path.isfile(self.tgzNameWithPath):
629     txt += 'echo "tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'"\n'
630     txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
631     txt += 'untar_status=$? \n'
632     txt += 'if [ $untar_status -ne 0 ]; then \n'
633     txt += ' echo "SET_EXE 1 ==> ERROR Untarring .tgz file failed"\n'
634     txt += ' echo "JOB_EXIT_STATUS = $untar_status" \n'
635     txt += ' echo "SanityCheckCode = $untar_status" | tee -a $repo\n'
636     txt += ' if [ $middleware == OSG ]; then \n'
637     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
638     txt += ' cd $RUNTIME_AREA\n'
639     txt += ' /bin/rm -rf $WORKING_DIR\n'
640     txt += ' if [ -d $WORKING_DIR ] ;then\n'
641     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
642     txt += ' fi\n'
643     txt += ' fi \n'
644     txt += ' \n'
645     txt += ' exit $untar_status \n'
646     txt += 'else \n'
647     txt += ' echo "Successful untar" \n'
648     txt += 'fi \n'
649     pass
650    
651 slacapra 1.1 return txt
652    
653     def modifySteeringCards(self, nj):
654     """
655     modify the card provided by the user,
656     writing a new card into share dir
657     """
658    
659     def executableName(self):
660     return self.executable
661    
662     def executableArgs(self):
663 gutsche 1.3 return " -p pset.cfg"
664 slacapra 1.1
665     def inputSandbox(self, nj):
666     """
667     Returns a list of filenames to be put in JDL input sandbox.
668     """
669     inp_box = []
670     # dict added to delete duplicate from input sandbox file list
671     seen = {}
672     ## code
673     if os.path.isfile(self.tgzNameWithPath):
674     inp_box.append(self.tgzNameWithPath)
675     ## config
676     inp_box.append(common.job_list[nj].configFilename())
677     ## additional input files
678 gutsche 1.3 #for file in self.additional_inbox_files:
679     # inp_box.append(common.work_space.cwdDir()+file)
680 slacapra 1.1 return inp_box
681    
682     def outputSandbox(self, nj):
683     """
684     Returns a list of filenames to be put in JDL output sandbox.
685     """
686     out_box = []
687    
688     stdout=common.job_list[nj].stdout()
689     stderr=common.job_list[nj].stderr()
690    
691     ## User Declared output files
692     for out in self.output_file:
693     n_out = nj + 1
694     out_box.append(self.numberFile_(out,str(n_out)))
695     return out_box
696     return []
697    
698     def prepareSteeringCards(self):
699     """
700     Make initial modifications of the user's steering card file.
701     """
702     return
703    
704     def wsRenameOutput(self, nj):
705     """
706     Returns part of a job script which renames the produced files.
707     """
708    
709     txt = '\n'
710     file_list = ''
711 gutsche 1.3 check = len(self.output_file)
712     i = 0
713 slacapra 1.1 for fileWithSuffix in self.output_file:
714 gutsche 1.3 i= i + 1
715 slacapra 1.1 output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
716 gutsche 1.3 file_list=file_list+output_file_num+''
717 slacapra 1.1 txt += '\n'
718     txt += 'ls \n'
719     txt += '\n'
720     txt += 'ls '+fileWithSuffix+'\n'
721     txt += 'exe_result=$?\n'
722     txt += 'if [ $exe_result -ne 0 ] ; then\n'
723     txt += ' echo "ERROR: No output file to manage"\n'
724 gutsche 1.3 ### OLI_DANIELE
725     txt += ' if [ $middleware == OSG ]; then \n'
726     txt += ' echo "prepare dummy output file"\n'
727     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
728     txt += ' fi \n'
729 slacapra 1.1 txt += 'else\n'
730     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
731     txt += 'fi\n'
732 gutsche 1.3 if i == check:
733     txt += 'cd $RUNTIME_AREA\n'
734     pass
735 slacapra 1.1 pass
736    
737     file_list=file_list[:-1]
738 slacapra 1.2 txt += 'file_list="'+file_list+'"\n'
739 gutsche 1.3 ### OLI_DANIELE
740     txt += 'if [ $middleware == OSG ]; then\n'
741     txt += ' cd $RUNTIME_AREA\n'
742     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
743     txt += ' /bin/rm -rf $WORKING_DIR\n'
744     txt += ' if [ -d $WORKING_DIR ] ;then\n'
745     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
746     txt += ' fi\n'
747     txt += 'fi\n'
748     txt += '\n'
749 slacapra 1.1 return txt
750    
751     def numberFile_(self, file, txt):
752     """
753     append _'txt' before last extension of a file
754     """
755     p = string.split(file,".")
756     # take away last extension
757     name = p[0]
758     for x in p[1:-1]:
759     name=name+"."+x
760     # add "_txt"
761     if len(p)>1:
762     ext = p[len(p)-1]
763     #result = name + '_' + str(txt) + "." + ext
764     result = name + '_' + txt + "." + ext
765     else:
766     #result = name + '_' + str(txt)
767     result = name + '_' + txt
768    
769     return result
770    
771     def getRequirements(self):
772     """
773     return job requirements to add to jdl files
774     """
775     req = ''
776     if common.analisys_common_info['sites']:
777     if common.analisys_common_info['sw_version']:
778     req='Member("VO-cms-' + \
779     common.analisys_common_info['sw_version'] + \
780     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
781     if len(common.analisys_common_info['sites'])>0:
782     req = req + ' && ('
783     for i in range(len(common.analisys_common_info['sites'])):
784     req = req + 'other.GlueCEInfoHostName == "' \
785     + common.analisys_common_info['sites'][i] + '"'
786     if ( i < (int(len(common.analisys_common_info['sites']) - 1)) ):
787     req = req + ' || '
788     req = req + ')'
789     #print "req = ", req
790     return req
791 gutsche 1.3
792     def configFilename(self):
793     """ return the config filename """
794     return self.name()+'.cfg'
795    
796     ### OLI_DANIELE
797     def wsSetupCMSOSGEnvironment_(self):
798     """
799     Returns part of a job script which is prepares
800     the execution environment and which is common for all CMS jobs.
801     """
802     txt = '\n'
803     txt += ' echo "### SETUP CMS OSG ENVIRONMENT ###"\n'
804     txt += ' if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
805     txt += ' # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
806     txt += ' source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
807     txt += ' elif [ -f $OSG_APP/cmssoft/cmsset_default.sh ] ;then\n'
808     txt += ' # Use $OSG_APP/cmssoft/cmsset_default.sh to setup cms software\n'
809     txt += ' source $OSG_APP/cmssoft/cmsset_default.sh '+self.version+'\n'
810     txt += ' else\n'
811     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR $GRID3_APP_DIR/cmssoft/cmsset_default.sh and $OSG_APP/cmssoft/cmsset_default.sh file not found"\n'
812     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
813     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
814     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
815     txt += ' exit\n'
816     txt += '\n'
817     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
818     txt += ' cd $RUNTIME_AREA\n'
819     txt += ' /bin/rm -rf $WORKING_DIR\n'
820     txt += ' if [ -d $WORKING_DIR ] ;then\n'
821     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
822     txt += ' fi\n'
823     txt += '\n'
824     txt += ' exit\n'
825     txt += ' fi\n'
826     txt += '\n'
827     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
828     txt += ' echo " END SETUP CMS OSG ENVIRONMENT "\n'
829    
830     return txt
831    
832     ### OLI_DANIELE
833     def wsSetupCMSLCGEnvironment_(self):
834     """
835     Returns part of a job script which is prepares
836     the execution environment and which is common for all CMS jobs.
837     """
838     txt = ' \n'
839     txt += ' echo " ### SETUP CMS LCG ENVIRONMENT ### "\n'
840     txt += ' echo "JOB_EXIT_STATUS = 0"\n'
841     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
842     txt += ' echo "SET_CMS_ENV 10031 ==> ERROR CMS software dir not found on WN `hostname`"\n'
843     txt += ' echo "JOB_EXIT_STATUS = 10031" \n'
844     txt += ' echo "JobExitCode=10031" | tee -a $RUNTIME_AREA/$repo\n'
845     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
846     txt += ' exit\n'
847     txt += ' else\n'
848     txt += ' echo "Sourcing environment... "\n'
849     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
850     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
851     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
852     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
853     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
854     txt += ' exit\n'
855     txt += ' fi\n'
856     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
857     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
858     txt += ' result=$?\n'
859     txt += ' if [ $result -ne 0 ]; then\n'
860     txt += ' echo "SET_CMS_ENV 10032 ==> ERROR problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
861     txt += ' echo "JOB_EXIT_STATUS = 10032"\n'
862     txt += ' echo "JobExitCode=10032" | tee -a $RUNTIME_AREA/$repo\n'
863     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
864     txt += ' exit\n'
865     txt += ' fi\n'
866     txt += ' fi\n'
867     txt += ' \n'
868     txt += ' string=`cat /etc/redhat-release`\n'
869     txt += ' echo $string\n'
870     txt += ' if [[ $string = *alhalla* ]]; then\n'
871     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
872     txt += ' elif [[ $string = *Enterprise* ]] || [[ $string = *cientific* ]]; then\n'
873     txt += ' export SCRAM_ARCH=slc3_ia32_gcc323\n'
874     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
875     txt += ' else\n'
876     txt += ' echo "SET_CMS_ENV 1 ==> ERROR OS unknown, LCG environment not initialized"\n'
877     txt += ' echo "JOB_EXIT_STATUS = 10033"\n'
878     txt += ' echo "JobExitCode=10033" | tee -a $RUNTIME_AREA/$repo\n'
879     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
880     txt += ' exit\n'
881     txt += ' fi\n'
882     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
883     txt += ' echo "### END SETUP CMS LCG ENVIRONMENT ###"\n'
884     return txt