ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/cms_cmssw.py
Revision: 1.3
Committed: Sun May 28 02:27:52 2006 UTC (18 years, 11 months ago) by gutsche
Content type: text/x-python
Branch: MAIN
CVS Tags: post_cmssw_integration_20060527
Changes since 1.2: +418 -111 lines
Log Message:
Integrate CMSSW: added OSG capabilities

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 gutsche 1.3 self.pubdata=DataDiscovery_EDM.DataDiscovery_EDM(datasetPath, dataTiers, dataTiers)
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 gutsche 1.3 dataloc=DataLocation_EDM.DataLocation_EDM(filesbyblock.keys(),cfg_params)
252 slacapra 1.1 dataloc.fetchDLSInfo()
253 gutsche 1.3 except DataLocation_EDM.DataLocationError , ex:
254 slacapra 1.1 msg = 'ERROR ***: failed Data Location in DLS \n %s '%ex.getErrorMessage()
255     raise CrabException(msg)
256    
257     allsites=dataloc.getSites()
258     common.logger.debug(5,"sites are %s"%allsites)
259     sites=self.checkBlackList(allsites)
260     common.logger.debug(5,"sites are (after black list) %s"%sites)
261     sites=self.checkWhiteList(sites)
262     common.logger.debug(5,"sites are (after white list) %s"%sites)
263    
264     if len(sites)==0:
265     msg = 'No sites hosting all the needed data! Exiting... '
266     raise CrabException(msg)
267 gutsche 1.3
268 slacapra 1.1 common.logger.message("List of Sites hosting the data : "+str(sites))
269     common.logger.debug(6, "List of Sites: "+str(sites))
270     common.analisys_common_info['sites']=sites ## used in SchedulerEdg.py in createSchScript
271     return
272 gutsche 1.3
273     def jobSplitting(self):
274     """
275     first implemntation for job splitting
276     """
277     # print 'eventi totali '+str(self.maxEvents)
278     # print 'eventi totali richiesti dallo user '+str(self.total_number_of_events)
279     #print 'files per job '+str(self.filesPerJob)
280     common.logger.message('Required '+str(self.filesPerJob)+' files per job ')
281     common.logger.message('Required '+str(self.total_number_of_events)+' events in total ')
282    
283     ## TODO: SL need to have (from DBS) a detailed list of how many events per each file
284     n_tot_files = (len(self.files[0]))
285     ## SL: this is wrong if the files have different number of events
286     evPerFile = int(self.maxEvents)/n_tot_files
287    
288     common.logger.debug(5,'Events per File '+str(evPerFile))
289    
290     ## if asked to process all events, do it
291     if self.total_number_of_events == -1:
292     self.total_number_of_events=self.maxEvents
293     self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
294     common.logger.message(str(self.total_number_of_jobs)+' jobs will be created for all available events '+str(self.total_number_of_events)+' events')
295    
296     else:
297     self.total_number_of_files = int(self.total_number_of_events/evPerFile)
298     ## SL: if ask for less event than what is computed to be available on a
299     ## file, process the first file anyhow.
300     if self.total_number_of_files == 0:
301     self.total_number_of_files = self.total_number_of_files + 1
302    
303     common.logger.debug(5,'N files '+str(self.total_number_of_files))
304    
305     check = 0
306    
307     ## Compute the number of jobs
308     #self.total_number_of_jobs = int(n_tot_files)*1/int(self.filesPerJob)
309     self.total_number_of_jobs = int(self.total_number_of_files/self.filesPerJob)
310     common.logger.debug(5,'N jobs '+str(self.total_number_of_jobs))
311    
312     ## is there any remainder?
313     check = int(self.total_number_of_files) - (int(self.total_number_of_jobs)*self.filesPerJob)
314    
315     common.logger.debug(5,'Check '+str(check))
316    
317     if check > 0:
318     self.total_number_of_jobs = self.total_number_of_jobs + 1
319     common.logger.message('Warning: last job will be created with '+str(check)+' files')
320    
321     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')
322     pass
323    
324     list_of_lists = []
325     for i in xrange(0, int(n_tot_files), self.filesPerJob):
326     list_of_lists.append(self.files[0][i: i+self.filesPerJob])
327    
328     self.list_of_files = list_of_lists
329    
330     return
331    
332     def split(self, jobParams):
333    
334     common.jobDB.load()
335     #### Fabio
336     njobs = self.total_number_of_jobs
337     filelist = self.list_of_files
338     # create the empty structure
339     for i in range(njobs):
340     jobParams.append("")
341    
342     for job in range(njobs):
343     jobParams[job] = filelist[job]
344     common.jobDB.setArguments(job, jobParams[job])
345    
346     common.jobDB.save()
347     return
348    
349     def getJobTypeArguments(self, nj, sched):
350     params = common.jobDB.arguments(nj)
351     #print params
352     parString = "\\{"
353    
354     for i in range(len(params) - 1):
355     parString += '\\\"' + params[i] + '\\\"\,'
356 slacapra 1.1
357 gutsche 1.3 parString += '\\\"' + params[len(params) - 1] + '\\\"\\}'
358     return parString
359    
360     def numberOfJobs(self):
361     # Fabio
362    
363     return self.total_number_of_jobs
364    
365    
366    
367 slacapra 1.1 def checkBlackList(self, allSites):
368     if len(self.reCEBlackList)==0: return allSites
369     sites = []
370     for site in allSites:
371     common.logger.debug(10,'Site '+site)
372     good=1
373     for re in self.reCEBlackList:
374     if re.search(site):
375     common.logger.message('CE in black list, skipping site '+site)
376     good=0
377     pass
378     if good: sites.append(site)
379     if len(sites) == 0:
380     common.logger.debug(3,"No sites found after BlackList")
381     return sites
382    
383 gutsche 1.3 def checkWhiteList(self, allSites):
384 slacapra 1.1
385 gutsche 1.3 if len(self.reCEWhiteList)==0: return allSites
386 slacapra 1.1 sites = []
387 gutsche 1.3 for site in allSites:
388 slacapra 1.1 good=0
389     for re in self.reCEWhiteList:
390     if re.search(site):
391     common.logger.debug(5,'CE in white list, adding site '+site)
392     good=1
393     if not good: continue
394     sites.append(site)
395     if len(sites) == 0:
396     common.logger.message("No sites found after WhiteList\n")
397     else:
398     common.logger.debug(5,"Selected sites via WhiteList are "+str(sites)+"\n")
399     return sites
400    
401     def getTarBall(self, exe):
402     """
403     Return the TarBall with lib and exe
404     """
405    
406     # if it exist, just return it
407     self.tgzNameWithPath = common.work_space.shareDir()+self.tgz_name
408     if os.path.exists(self.tgzNameWithPath):
409     return self.tgzNameWithPath
410    
411     # Prepare a tar gzipped file with user binaries.
412     self.buildTar_(exe)
413    
414     return string.strip(self.tgzNameWithPath)
415    
416     def buildTar_(self, executable):
417    
418     # First of all declare the user Scram area
419     swArea = self.scram.getSWArea_()
420     #print "swArea = ", swArea
421     swVersion = self.scram.getSWVersion()
422     #print "swVersion = ", swVersion
423     swReleaseTop = self.scram.getReleaseTop_()
424     #print "swReleaseTop = ", swReleaseTop
425    
426     ## check if working area is release top
427     if swReleaseTop == '' or swArea == swReleaseTop:
428     return
429    
430     filesToBeTarred = []
431     ## First find the executable
432     if (self.executable != ''):
433     exeWithPath = self.scram.findFile_(executable)
434     # print exeWithPath
435     if ( not exeWithPath ):
436     raise CrabException('User executable '+executable+' not found')
437    
438     ## then check if it's private or not
439     if exeWithPath.find(swReleaseTop) == -1:
440     # the exe is private, so we must ship
441     common.logger.debug(5,"Exe "+exeWithPath+" to be tarred")
442     path = swArea+'/'
443     exe = string.replace(exeWithPath, path,'')
444     filesToBeTarred.append(exe)
445     pass
446     else:
447     # the exe is from release, we'll find it on WN
448     pass
449    
450     ## Now get the libraries: only those in local working area
451     libDir = 'lib'
452     lib = swArea+'/' +libDir
453     common.logger.debug(5,"lib "+lib+" to be tarred")
454     if os.path.exists(lib):
455     filesToBeTarred.append(libDir)
456    
457 gutsche 1.3 ## Now check if module dir is present
458     moduleDir = 'module'
459     if os.path.isdir(swArea+'/'+moduleDir):
460     filesToBeTarred.append(moduleDir)
461    
462 slacapra 1.1 ## Now check if the Data dir is present
463     dataDir = 'src/Data/'
464     if os.path.isdir(swArea+'/'+dataDir):
465     filesToBeTarred.append(dataDir)
466    
467     ## Create the tar-ball
468     if len(filesToBeTarred)>0:
469     cwd = os.getcwd()
470     os.chdir(swArea)
471     tarcmd = 'tar zcvf ' + self.tgzNameWithPath + ' '
472     for line in filesToBeTarred:
473     tarcmd = tarcmd + line + ' '
474     cout = runCommand(tarcmd)
475     if not cout:
476     raise CrabException('Could not create tar-ball')
477     os.chdir(cwd)
478     else:
479     common.logger.debug(5,"No files to be to be tarred")
480    
481     return
482    
483     def wsSetupEnvironment(self, nj):
484     """
485     Returns part of a job script which prepares
486     the execution environment for the job 'nj'.
487     """
488     # Prepare JobType-independent part
489 gutsche 1.3 txt = ''
490    
491     ## OLI_Daniele at this level middleware already known
492    
493     txt += 'if [ $middleware == LCG ]; then \n'
494     txt += self.wsSetupCMSLCGEnvironment_()
495     txt += 'elif [ $middleware == OSG ]; then\n'
496     txt += ' time=`date -u +"%s"`\n'
497     txt += ' WORKING_DIR=$OSG_WN_TMP/cms_$time\n'
498     txt += ' echo "Creating working directory: $WORKING_DIR"\n'
499     txt += ' /bin/mkdir -p $WORKING_DIR\n'
500     txt += ' if [ ! -d $WORKING_DIR ] ;then\n'
501     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be created on on WN `hostname`"\n'
502    
503     txt += ' echo "JOB_EXIT_STATUS = 1"\n'
504     txt += ' exit 1\n'
505     txt += ' fi\n'
506     txt += '\n'
507     txt += ' echo "Change to working directory: $WORKING_DIR"\n'
508     txt += ' cd $WORKING_DIR\n'
509     txt += self.wsSetupCMSOSGEnvironment_()
510     txt += 'fi\n'
511 slacapra 1.1
512     # Prepare JobType-specific part
513     scram = self.scram.commandName()
514     txt += '\n\n'
515     txt += 'echo "### SPECIFIC JOB SETUP ENVIRONMENT ###"\n'
516     txt += scram+' project CMSSW '+self.version+'\n'
517     txt += 'status=$?\n'
518     txt += 'if [ $status != 0 ] ; then\n'
519     txt += ' echo "SET_EXE_ENV 1 ==>ERROR CMSSW '+self.version+' not found on `hostname`" \n'
520 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 10034"\n'
521     txt += ' echo "SanityCheckCode = 10034" | tee -a $RUNTIME_AREA/$repo\n'
522 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
523 gutsche 1.3 ## OLI_Daniele
524     txt += ' if [ $middleware == OSG ]; then \n'
525     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
526     txt += ' cd $RUNTIME_AREA\n'
527     txt += ' /bin/rm -rf $WORKING_DIR\n'
528     txt += ' if [ -d $WORKING_DIR ] ;then\n'
529     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
530     txt += ' fi\n'
531     txt += ' fi \n'
532     txt += ' exit 1 \n'
533 slacapra 1.1 txt += 'fi \n'
534     txt += 'echo "CMSSW_VERSION = '+self.version+'"\n'
535     txt += 'cd '+self.version+'\n'
536     ### needed grep for bug in scramv1 ###
537     txt += 'eval `'+scram+' runtime -sh | grep -v SCRAMRT_LSB_JOBNAME`\n'
538    
539     # Handle the arguments:
540     txt += "\n"
541     txt += "## ARGUMNETS: $1 Job Number\n"
542     # txt += "## ARGUMNETS: $2 First Event for this job\n"
543     # txt += "## ARGUMNETS: $3 Max Event for this job\n"
544     txt += "\n"
545     txt += "narg=$#\n"
546 gutsche 1.3 txt += "if [ $narg -lt 2 ]\n"
547 slacapra 1.1 txt += "then\n"
548     txt += " echo 'SET_EXE_ENV 1 ==> ERROR Too few arguments' +$narg+ \n"
549 gutsche 1.3 txt += ' echo "JOB_EXIT_STATUS = 50113"\n'
550     txt += ' echo "SanityCheckCode = 50113" | tee -a $RUNTIME_AREA/$repo\n'
551 slacapra 1.1 txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
552 gutsche 1.3 ## OLI_Daniele
553     txt += ' if [ $middleware == OSG ]; then \n'
554     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
555     txt += ' cd $RUNTIME_AREA\n'
556     txt += ' /bin/rm -rf $WORKING_DIR\n'
557     txt += ' if [ -d $WORKING_DIR ] ;then\n'
558     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
559     txt += ' fi\n'
560     txt += ' fi \n'
561 slacapra 1.1 txt += " exit 1\n"
562     txt += "fi\n"
563     txt += "\n"
564     txt += "NJob=$1\n"
565 gutsche 1.3 txt += "InputFiles=$2\n"
566     txt += "echo \"<$InputFiles>\"\n"
567     # txt += "Args = ` cat $2 | sed -e \'s/\\\\//g\' -e \'s/\"/\\x27/g\' `"
568    
569     ### OLI_DANIELE
570     txt += 'if [ $middleware == LCG ]; then \n'
571     txt += ' echo "MonitorJobID=`echo ${NJob}_$EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
572     txt += ' echo "SyncGridJobId=`echo $EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
573     txt += ' echo "SyncCE=`edg-brokerinfo getCE`" | tee -a $RUNTIME_AREA/$repo\n'
574     txt += 'elif [ $middleware == OSG ]; then\n'
575    
576     # OLI: added monitoring for dashbord, use hash of crab.cfg
577     if common.scheduler.boss_scheduler_name == 'condor_g':
578     # create hash of cfg file
579     hash = makeCksum(common.work_space.cfgFileName())
580     txt += ' echo "MonitorJobID=`echo ${NJob}_'+hash+'_$GLOBUS_GRAM_JOB_CONTACT`" | tee -a $RUNTIME_AREA/$repo\n'
581     txt += ' echo "SyncGridJobId=`echo $GLOBUS_GRAM_JOB_CONTACT`" | tee -a $RUNTIME_AREA/$repo\n'
582     txt += ' echo "SyncCE=`echo $hostname`" | tee -a $RUNTIME_AREA/$repo\n'
583     else :
584     txt += ' echo "MonitorJobID=`echo ${NJob}_$EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
585     txt += ' echo "SyncGridJobId=`echo $EDG_WL_JOBID`" | tee -a $RUNTIME_AREA/$repo\n'
586     txt += ' echo "SyncCE=`$EDG_WL_LOG_DESTINATION`" | tee -a $RUNTIME_AREA/$repo\n'
587    
588     txt += 'fi\n'
589     txt += 'dumpStatus $RUNTIME_AREA/$repo\n'
590 slacapra 1.1
591     # Prepare job-specific part
592     job = common.job_list[nj]
593     pset = os.path.basename(job.configFilename())
594     txt += '\n'
595 gutsche 1.3 #txt += 'echo sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' \n'
596     txt += 'sed "s#{\'INPUT\'}#$InputFiles#" $RUNTIME_AREA/'+pset+' > pset.cfg\n'
597     #txt += 'sed "s#{\'INPUT\'}#${InputFiles}#" $RUNTIME_AREA/'+pset+' > pset1.cfg\n'
598 slacapra 1.1
599     if len(self.additional_inbox_files) > 0:
600     for file in self.additional_inbox_files:
601     txt += 'if [ -e $RUNTIME_AREA/'+file+' ] ; then\n'
602     txt += ' cp $RUNTIME_AREA/'+file+' .\n'
603     txt += ' chmod +x '+file+'\n'
604     txt += 'fi\n'
605     pass
606    
607     txt += 'echo "### END JOB SETUP ENVIRONMENT ###"\n\n'
608    
609     txt += '\n'
610     txt += 'echo "***** cat pset.cfg *********"\n'
611     txt += 'cat pset.cfg\n'
612     txt += 'echo "****** end pset.cfg ********"\n'
613 gutsche 1.3 txt += '\n'
614     # txt += 'echo "***** cat pset1.cfg *********"\n'
615     # txt += 'cat pset1.cfg\n'
616     # txt += 'echo "****** end pset1.cfg ********"\n'
617     return txt
618    
619     def wsBuildExe(self, nj):
620     """
621     Put in the script the commands to build an executable
622     or a library.
623     """
624    
625     txt = ""
626    
627     if os.path.isfile(self.tgzNameWithPath):
628     txt += 'echo "tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'"\n'
629     txt += 'tar xzvf $RUNTIME_AREA/'+os.path.basename(self.tgzNameWithPath)+'\n'
630     txt += 'untar_status=$? \n'
631     txt += 'if [ $untar_status -ne 0 ]; then \n'
632     txt += ' echo "SET_EXE 1 ==> ERROR Untarring .tgz file failed"\n'
633     txt += ' echo "JOB_EXIT_STATUS = $untar_status" \n'
634     txt += ' echo "SanityCheckCode = $untar_status" | tee -a $repo\n'
635     txt += ' if [ $middleware == OSG ]; then \n'
636     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
637     txt += ' cd $RUNTIME_AREA\n'
638     txt += ' /bin/rm -rf $WORKING_DIR\n'
639     txt += ' if [ -d $WORKING_DIR ] ;then\n'
640     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
641     txt += ' fi\n'
642     txt += ' fi \n'
643     txt += ' \n'
644     txt += ' exit $untar_status \n'
645     txt += 'else \n'
646     txt += ' echo "Successful untar" \n'
647     txt += 'fi \n'
648     pass
649    
650 slacapra 1.1 return txt
651    
652     def modifySteeringCards(self, nj):
653     """
654     modify the card provided by the user,
655     writing a new card into share dir
656     """
657    
658     def executableName(self):
659     return self.executable
660    
661     def executableArgs(self):
662 gutsche 1.3 return " -p pset.cfg"
663 slacapra 1.1
664     def inputSandbox(self, nj):
665     """
666     Returns a list of filenames to be put in JDL input sandbox.
667     """
668     inp_box = []
669     # dict added to delete duplicate from input sandbox file list
670     seen = {}
671     ## code
672     if os.path.isfile(self.tgzNameWithPath):
673     inp_box.append(self.tgzNameWithPath)
674     ## config
675     inp_box.append(common.job_list[nj].configFilename())
676     ## additional input files
677 gutsche 1.3 #for file in self.additional_inbox_files:
678     # inp_box.append(common.work_space.cwdDir()+file)
679 slacapra 1.1 return inp_box
680    
681     def outputSandbox(self, nj):
682     """
683     Returns a list of filenames to be put in JDL output sandbox.
684     """
685     out_box = []
686    
687     stdout=common.job_list[nj].stdout()
688     stderr=common.job_list[nj].stderr()
689    
690     ## User Declared output files
691     for out in self.output_file:
692     n_out = nj + 1
693     out_box.append(self.numberFile_(out,str(n_out)))
694     return out_box
695     return []
696    
697     def prepareSteeringCards(self):
698     """
699     Make initial modifications of the user's steering card file.
700     """
701     return
702    
703     def wsRenameOutput(self, nj):
704     """
705     Returns part of a job script which renames the produced files.
706     """
707    
708     txt = '\n'
709     file_list = ''
710 gutsche 1.3 check = len(self.output_file)
711     i = 0
712 slacapra 1.1 for fileWithSuffix in self.output_file:
713 gutsche 1.3 i= i + 1
714 slacapra 1.1 output_file_num = self.numberFile_(fileWithSuffix, '$NJob')
715 gutsche 1.3 file_list=file_list+output_file_num+''
716 slacapra 1.1 txt += '\n'
717     txt += 'ls \n'
718     txt += '\n'
719     txt += 'ls '+fileWithSuffix+'\n'
720     txt += 'exe_result=$?\n'
721     txt += 'if [ $exe_result -ne 0 ] ; then\n'
722     txt += ' echo "ERROR: No output file to manage"\n'
723 gutsche 1.3 ### OLI_DANIELE
724     txt += ' if [ $middleware == OSG ]; then \n'
725     txt += ' echo "prepare dummy output file"\n'
726     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
727     txt += ' fi \n'
728 slacapra 1.1 txt += 'else\n'
729     txt += ' cp '+fileWithSuffix+' $RUNTIME_AREA/'+output_file_num+'\n'
730     txt += 'fi\n'
731 gutsche 1.3 if i == check:
732     txt += 'cd $RUNTIME_AREA\n'
733     pass
734 slacapra 1.1 pass
735    
736     file_list=file_list[:-1]
737 slacapra 1.2 txt += 'file_list="'+file_list+'"\n'
738 gutsche 1.3 ### OLI_DANIELE
739     txt += 'if [ $middleware == OSG ]; then\n'
740     txt += ' cd $RUNTIME_AREA\n'
741     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
742     txt += ' /bin/rm -rf $WORKING_DIR\n'
743     txt += ' if [ -d $WORKING_DIR ] ;then\n'
744     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
745     txt += ' fi\n'
746     txt += 'fi\n'
747     txt += '\n'
748 slacapra 1.1 return txt
749    
750     def numberFile_(self, file, txt):
751     """
752     append _'txt' before last extension of a file
753     """
754     p = string.split(file,".")
755     # take away last extension
756     name = p[0]
757     for x in p[1:-1]:
758     name=name+"."+x
759     # add "_txt"
760     if len(p)>1:
761     ext = p[len(p)-1]
762     #result = name + '_' + str(txt) + "." + ext
763     result = name + '_' + txt + "." + ext
764     else:
765     #result = name + '_' + str(txt)
766     result = name + '_' + txt
767    
768     return result
769    
770     def getRequirements(self):
771     """
772     return job requirements to add to jdl files
773     """
774     req = ''
775     if common.analisys_common_info['sites']:
776     if common.analisys_common_info['sw_version']:
777     req='Member("VO-cms-' + \
778     common.analisys_common_info['sw_version'] + \
779     '", other.GlueHostApplicationSoftwareRunTimeEnvironment)'
780     if len(common.analisys_common_info['sites'])>0:
781     req = req + ' && ('
782     for i in range(len(common.analisys_common_info['sites'])):
783     req = req + 'other.GlueCEInfoHostName == "' \
784     + common.analisys_common_info['sites'][i] + '"'
785     if ( i < (int(len(common.analisys_common_info['sites']) - 1)) ):
786     req = req + ' || '
787     req = req + ')'
788     #print "req = ", req
789     return req
790 gutsche 1.3
791     def configFilename(self):
792     """ return the config filename """
793     return self.name()+'.cfg'
794    
795     ### OLI_DANIELE
796     def wsSetupCMSOSGEnvironment_(self):
797     """
798     Returns part of a job script which is prepares
799     the execution environment and which is common for all CMS jobs.
800     """
801     txt = '\n'
802     txt += ' echo "### SETUP CMS OSG ENVIRONMENT ###"\n'
803     txt += ' if [ -f $GRID3_APP_DIR/cmssoft/cmsset_default.sh ] ;then\n'
804     txt += ' # Use $GRID3_APP_DIR/cmssoft/cmsset_default.sh to setup cms software\n'
805     txt += ' source $GRID3_APP_DIR/cmssoft/cmsset_default.sh '+self.version+'\n'
806     txt += ' elif [ -f $OSG_APP/cmssoft/cmsset_default.sh ] ;then\n'
807     txt += ' # Use $OSG_APP/cmssoft/cmsset_default.sh to setup cms software\n'
808     txt += ' source $OSG_APP/cmssoft/cmsset_default.sh '+self.version+'\n'
809     txt += ' else\n'
810     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'
811     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
812     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
813     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
814     txt += ' exit\n'
815     txt += '\n'
816     txt += ' echo "Remove working directory: $WORKING_DIR"\n'
817     txt += ' cd $RUNTIME_AREA\n'
818     txt += ' /bin/rm -rf $WORKING_DIR\n'
819     txt += ' if [ -d $WORKING_DIR ] ;then\n'
820     txt += ' echo "OSG WORKING DIR ==> $WORKING_DIR could not be deleted on on WN `hostname`"\n'
821     txt += ' fi\n'
822     txt += '\n'
823     txt += ' exit\n'
824     txt += ' fi\n'
825     txt += '\n'
826     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
827     txt += ' echo " END SETUP CMS OSG ENVIRONMENT "\n'
828    
829     return txt
830    
831     ### OLI_DANIELE
832     def wsSetupCMSLCGEnvironment_(self):
833     """
834     Returns part of a job script which is prepares
835     the execution environment and which is common for all CMS jobs.
836     """
837     txt = ' \n'
838     txt += ' echo " ### SETUP CMS LCG ENVIRONMENT ### "\n'
839     txt += ' echo "JOB_EXIT_STATUS = 0"\n'
840     txt += ' if [ ! $VO_CMS_SW_DIR ] ;then\n'
841     txt += ' echo "SET_CMS_ENV 10031 ==> ERROR CMS software dir not found on WN `hostname`"\n'
842     txt += ' echo "JOB_EXIT_STATUS = 10031" \n'
843     txt += ' echo "JobExitCode=10031" | tee -a $RUNTIME_AREA/$repo\n'
844     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
845     txt += ' exit\n'
846     txt += ' else\n'
847     txt += ' echo "Sourcing environment... "\n'
848     txt += ' if [ ! -s $VO_CMS_SW_DIR/cmsset_default.sh ] ;then\n'
849     txt += ' echo "SET_CMS_ENV 10020 ==> ERROR cmsset_default.sh file not found into dir $VO_CMS_SW_DIR"\n'
850     txt += ' echo "JOB_EXIT_STATUS = 10020"\n'
851     txt += ' echo "JobExitCode=10020" | tee -a $RUNTIME_AREA/$repo\n'
852     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
853     txt += ' exit\n'
854     txt += ' fi\n'
855     txt += ' echo "sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
856     txt += ' source $VO_CMS_SW_DIR/cmsset_default.sh\n'
857     txt += ' result=$?\n'
858     txt += ' if [ $result -ne 0 ]; then\n'
859     txt += ' echo "SET_CMS_ENV 10032 ==> ERROR problem sourcing $VO_CMS_SW_DIR/cmsset_default.sh"\n'
860     txt += ' echo "JOB_EXIT_STATUS = 10032"\n'
861     txt += ' echo "JobExitCode=10032" | tee -a $RUNTIME_AREA/$repo\n'
862     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
863     txt += ' exit\n'
864     txt += ' fi\n'
865     txt += ' fi\n'
866     txt += ' \n'
867     txt += ' string=`cat /etc/redhat-release`\n'
868     txt += ' echo $string\n'
869     txt += ' if [[ $string = *alhalla* ]]; then\n'
870     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
871     txt += ' elif [[ $string = *Enterprise* ]] || [[ $string = *cientific* ]]; then\n'
872     txt += ' export SCRAM_ARCH=slc3_ia32_gcc323\n'
873     txt += ' echo "SCRAM_ARCH= $SCRAM_ARCH"\n'
874     txt += ' else\n'
875     txt += ' echo "SET_CMS_ENV 1 ==> ERROR OS unknown, LCG environment not initialized"\n'
876     txt += ' echo "JOB_EXIT_STATUS = 10033"\n'
877     txt += ' echo "JobExitCode=10033" | tee -a $RUNTIME_AREA/$repo\n'
878     txt += ' dumpStatus $RUNTIME_AREA/$repo\n'
879     txt += ' exit\n'
880     txt += ' fi\n'
881     txt += ' echo "SET_CMS_ENV 0 ==> setup cms environment ok"\n'
882     txt += ' echo "### END SETUP CMS LCG ENVIRONMENT ###"\n'
883     return txt