Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ] 

001 #!/bin/env python
002 # AtlCoolCheckFiles.py <dbname> <topleveltag>
003 
004 import os,sys,commands,tempfile
005 from CoolConvUtilities.AtlCoolLib import pathResolver as pathResolver
006 
007 class FileError:
008     "Class to store details of errors in one file"
009     def __init__(self,code,guid,count,lfn,pfn,folders):
010         self.code=int(code)
011         self.guid=str(guid)
012         self.count=int(count)
013         self.lfn=str(lfn)
014         self.pfn=str(pfn)
015         self.folders=folders
016 
017 class checkFile:
018     "Wrapper for AtlCoolCopy command which does POOL file checking"
019     def __init__(self,dbname,taglist,runsince,rununtil,filename="",verbose=False,oracle=False,openfile=False,nocat=False,poolcats=[],magic=[],parfiles=[],passOpt=""):
020         self.dbname=dbname
021         self.taglist=taglist
022         self.runsince=runsince
023         self.rununtil=rununtil
024         self.filename=filename
025         self.verbose=verbose
026         self.oracle=oracle
027         self.openfile=openfile
028         self.nocat=nocat
029         self.poolcats=poolcats
030         self.magictags=magic
031         self.passOpt=passOpt
032         self.parfiles=parfiles
033         self.poollist=[]
034         self.guidlist=[]
035         # setup temporary output file
036         self.tfilename=tempfile.mktemp()
037         print "Analyse database %s runs from %i to %i" % (self.dbname,self.runsince,self.rununtil)
038         for tag in self.taglist: print "Top-level tag %s" % tag
039         if (self.openfile):
040             print "Files will be physically opened to check GUID consistency"
041         # setup list of DBs to check
042         self.dblist=[]
043         if (self.dbname.find('/')<0):
044             # no explict connection string
045             schemas=[]
046             if (self.oracle):
047                 # current list of databases needed
048                 # only include those which are using POOL files
049                 # this duplicates information in AtlCoolSchema.py
050                 if self.dbname.find('OFLP')>=0:
051                     schemas=['COOLONL_INDET','COOLONL_TRT','COOLONL_LAR',
052                              'COOLONL_CALO','COOLONL_GLOBAL','COOLOFL_GLOBAL']
053                 elif self.dbname.find('CMCP')>=0:
054                     schemas=['COOLONL_INDET','COOLONL_TRT','COOLONL_LAR',
055                              'COOLONL_CALO','COOLONL_GLOBAL']
056                 elif self.dbname.find('COMP')>=0:
057                     schemas=['COOLONL_INDET','COOLONL_TRT','COOLONL_LAR',
058                              'COOLONL_CALO','COOLONL_GLOBAL','COOLOFL_GLOBAL']
059                 elif self.dbname.find('TMCP')>=0:
060                     schemas=['COOLONL_LAR','COOLONL_CALO']
061             else:
062                 # only a single connection is needed if using DBRelease
063                 schemas=['COOLONL_GLOBAL']
064             for s in schemas:
065                 self.dblist+=['%s/%s' % (s,self.dbname)]
066         else:
067             # explicit connection string - use it
068             self.dblist=[self.dbname]
069 
070     def execute(self):
071         "Execute the checks, return non-zero code if some files are not OK"
072         # construct poolcat options
073         poolopts=""
074         print "List of POOL file catalogues to be checked:"
075         if (len(self.poolcats)==0 and not self.nocat):
076             # default POOL file catalogues
077             cats=[]
078             if self.dbname.find('OFLP')>=0:
079                 cats=['oflcond']
080             elif self.dbname.find('CMCP')>=0:
081                 cats=['cmccond']
082             elif self.dbname.find('COMP')>=0:
083                 cats=['comcond','oflcond']
084             elif self.dbname.find('TBDP')>=0:
085                 cats=['tbcond']
086             elif self.dbname.find('TMCP')>=0:
087                 cats=['tbcond','oflcond']
088             for cat in cats:
089                 fname=pathResolver('poolcond/PoolCat_%s.xml' % cat,
090                                       retFile=False)
091                 if (fname is not None):
092                     poolopts+=' -poolcat %s' % fname
093                     print fname
094                 else:
095                     print "Warning: Cannot find catalogue file for %s" % cat
096         else:
097             for i in self.poolcats:
098                 poolopts+=' -poolcat %s' % i
099                 print i
100 
101         sumret=0
102         nerr=0
103         for dbname in self.dblist:
104             comm='AtlCoolCopy.exe %s X -nocopy -excludehead -checkrefs -listpfn -hitag -rs %i -ru %i -checkoutput %s%s' % (dbname,self.runsince,self.rununtil,self.tfilename,poolopts)
105             for tag in self.taglist: comm+=' -tag %s' % tag
106             if (self.oracle): comm+=' -readoracle'
107             if (self.openfile):
108                 comm+=' -checkfiles'
109             else:
110                 comm+=' -checkrefs'
111             if (self.passOpt!=""): comm+=" %s" % self.passOpt
112             for mtag in self.magictags:
113                 comm+=" -magic %s" % mtag
114                 print "Adding magic tag %s" % mtag
115             for i in self.parfiles:
116                 comm+=" -parfile %s" % i
117             print "Opening database",dbname
118             (s,o)=commands.getstatusoutput(comm)
119             if (self.verbose): print o
120             if (s==111*256):
121                 print "Problems detected for files referenced by %s" % dbname
122             elif (s!=0):
123                 print "Problems with DB access, AtlCoolCopy error %i (try --debug to see more)" % (s/256)
124                 sumret+=s
125             # accumulate information from file
126             try:
127                 infile=open(self.tfilename,"r")
128                 for line in infile.readlines():
129                     tokens=line.split()
130                     if int(tokens[0])>0: nerr+=1
131                     guid=tokens[1]
132                     if (guid not in self.guidlist):
133                         self.poollist+=[FileError(int(tokens[0]),tokens[1],
134                                                   int(tokens[2]),tokens[3],
135                                                   tokens[4],tokens[5:])]
136                         self.guidlist+=[guid]
137                 infile.close()
138             except IOError:
139                 # catch file not existing gracefully
140                 pass
141         # end of loop over database instances
142         if (self.filename!=""):
143             opfile=open(self.filename,"w")
144         else:
145             opfile=None
146         print "Total of %i POOL files with problems" % nerr
147         if (len(self.poollist)>0):
148             print "ErrCode GUID Count LFN PFN Folders"
149             for ifile in self.poollist:
150                 print '%2i %36s %4i %s %s' % (ifile.code,ifile.guid,ifile.count,ifile.lfn,ifile.pfn) ,
151                 for j in ifile.folders:
152                     print j,' ',
153                 print
154                 if (opfile):
155                     opfile.write('%2i %36s %4i %s %s ' % (ifile.code,ifile.guid,ifile.count,ifile.lfn,ifile.pfn))
156                     for j in ifile.folders:
157                         opfile.write(j+' ')
158                     opfile.write('\n')
159         else:
160             print "All files resolved successfully"
161         if (opfile): opfile.close()
162         # remove temporary file if needed, don't assume it is there
163         try:
164             os.remove(self.tfilename)
165         except OSError:
166             pass
167         return sumret
168 
169     def makeCD(self,filename,ignoremissing=False):
170         "Make conditions release with the set of files which were found"
171         # first check that all files were found, and if any are in castor
172         nbad=0
173         prestagelist=[]
174         for ifile in self.poollist:
175             if (ifile.code!=0 or ifile.pfn=='' or ifile.pfn=='noPFN'):
176                 nbad+=1
177             idx=ifile.pfn.find('/castor/')
178             if (idx>=0):
179                 prestagelist+=[' -M %s' % ifile.pfn[idx:]]
180         if (nbad>0):
181             print "WARNING: %i files are bad/missing" % nbad
182             if (ignoremissing):
183                 print "Continuing build with missing files"
184             else:
185                 print "Cannot build conditions release - ABORT"
186                 return 1
187         # issue castor pre-stage commands if needed
188         if len(prestagelist)>0:
189             print "Pre-staging %i files from castor" % len(prestagelist)
190             # issue command in groups of 10
191             for i in range(0,len(prestagelist),10):
192                 comm='LD_LIBRARY_PATH="";stager_get'
193                 for j in range(i,min(i+10,len(prestagelist))):
194                     comm+=prestagelist[j]
195                 print "Staging files %i %s: " % (i,comm)
196                 os.system(comm)
197                 
198         print "Building conditions release with %i files to output file %s" % (len(self.poollist),filename)
199         # create a temporary area to link to the files and zip them
200         packdir=tempfile.mktemp()
201         os.mkdir(packdir)
202         reldir=packdir+'/CDRelease'
203         os.mkdir(reldir)
204         pooldir=reldir+'/poolcond'
205         os.mkdir(pooldir)
206         xmldir=reldir+'/XMLConfig'
207         os.mkdir(xmldir)
208         # determine catalogue name and any dummies required
209         dummies=[]
210         if (self.dbname.find('OFLP')>=0):
211             cat='oflcond'
212         elif (self.dbname.find('COMP')>=0):
213             cat='comcond'
214             dummies+=['oflcond','comcond_castor']
215         elif (self.dbname.find('CMCP')>=0):
216             cat='cmccond'
217         else:
218             cat='nocond'
219             print "Unknown database instance %s - cannot derive catalogue name" % self.dbname
220         # generate any dummy catalogues that are required
221         for dummy in dummies:
222             print "Making dummy catalogue for %s" % dummy
223             dcat=PoolCat('%s/PoolCat_%s.xml' % (pooldir,dummy))
224             dcat.close()
225         catname='%s/PoolCat_%s.xml' % (pooldir,cat)
226         print "POOL file catalogue will be generated at %s" % catname
227         catalog=PoolCat(catname)
228         print "Using temporary directory %s" % packdir
229         # generate copies of current dblookup.xml and authentication.xml
230         os.system('cp $CORAL_AUTH_PATH/authentication.xml %s' % xmldir)
231         os.system('cp $CORAL_DBLOOKUP_PATH/dblookup.xml %s' % xmldir)
232         nbad=0
233         for ifile in self.poollist:
234             if (ignoremissing and (ifile.pfn=='noPFN' or ifile.code!=0)):
235                 continue
236             idx=ifile.pfn.rfind('/')
237             if (idx>0):
238                 leafname=ifile.pfn[idx+1:]
239             else:
240                 print "Cannot extract leafname from file %s" % ifile.pfn
241                 leafname='BADFILE'
242             idx=ifile.pfn.find('/castor/')
243             if (idx>=0):
244                 # file is from castor - have to rfcp to temp area
245                 print "Copying from castor: %s" % ifile.pfn[idx:]
246                 rc=os.system('rfcp %s %s/%s' % (ifile.pfn[idx:],pooldir,leafname))
247             else:
248               os.symlink(ifile.pfn,'%s/%s' % (pooldir,leafname))
249               rc=0
250             if (rc!=0):
251                 print "Problems linking/copying %s" % ifile.pfn
252                 nbad+=1
253             catalog.makeEntry(ifile.guid,ifile.lfn,leafname)
254         catalog.close()
255         if (nbad>0):
256             print "ERRORs detected in linking/copying %i files - ABORT" % nbad
257             return 2
258 
259         # add the setup file setup.py
260         setupfile=open('%s/setup.py' % reldir,'w')
261         setupfile.write("""
262 import os, fileinput
263 
264 class Setup(object):
265     def __init__(self, dbdir = None):
266         if dbdir is None:
267             self.dbdir = os.getcwd()
268         else:
269             self.dbdir = dbdir
270         print "Setting up CDRelease:"
271         self.custom()
272         self.env()
273 
274     def custom(self):
275         fns = ['PoolCat_oflcond.xml', 'PoolCat_tbcond.xml',
276                'PoolCat_cmccond.xml', 'PoolCat_comcond.xml']
277         fps=[]
278         for fn in fns:
279             f=os.path.join(self.dbdir,'poolcond',fn)
280             if os.path.exists(f):
281                 fps+=[f]
282         print "  Editing pool catalogs ... "
283         print fps
284         for line in fileinput.input(fps, inplace=1):
285             print line.replace('--GENERATED--',
286                                os.path.join(self.dbdir, 'poolcond') + os.sep),
287 
288     def env(self):
289         datapath = os.environ.get('DATAPATH')
290         if datapath:
291             datapath = datapath.split(os.pathsep)
292         else:
293             datapath = []
294         datapath = [d for d in datapath if 'DBRelease' not in d.split(os.sep)]
295         datapath.insert(0, self.dbdir)
296         coralpath=os.path.join(self.dbdir,'XMLConfig')
297             
298         print "  Setting up environment ..."
299         self.dbenv = { 'DATAPATH'            : os.pathsep.join(datapath) ,
300                        'CDRELEASE'           : os.path.basename(self.dbdir),
301                        'CORAL_DBLOOKUP_PATH' : os.path.join(self.dbdir, 'XMLConfig'),
302                        'CORAL_AUTH_PATH'     : os.path.join(self.dbdir,'XMLConfig')}
303         os.environ.update(self.dbenv)
304 
305     def __str__(self):
306         return '\\n'.join(['%s=%s' % i for i in self.dbenv.iteritems()])
307 
308 if __name__ != 'setup':
309     print Setup()
310 
311         """)
312         setupfile.close()
313         
314         # create the tar file
315         print "Creating tar file"
316         rc=os.system('cd %s;tar cvf %s.tar CDRelease -h' % (packdir,filename))
317         if (rc==0):
318             rc=os.system('gzip %s.tar' % filename)
319             if (rc!=0):
320                 print "Non-zero return code %i from gzipping" % rc
321                 return 3
322         else:
323             print "Non-zero return code %i from tarfile creation" % rc
324             return 2
325         # remove the temporary file
326         os.system('rm -rf %s' % packdir)
327         print "All done"
328         return 0
329 
330 class PoolCat:
331     "Class to output POOL file catalogue"
332     def __init__(self,catname):
333         "Open the catalogue file and write headers"
334         self.catfile=open(catname,'w')
335         self.catfile.write("""<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
336 <!-- Edited By POOL -->
337 <!DOCTYPE POOLFILECATALOG SYSTEM "InMemory">
338 <POOLFILECATALOG>\n""")
339 
340     def makeEntry(self,guid,lfn,pfnleaf):
341         "Make one entry in the file catalogue"
342         self.catfile.write("""
343   <File ID="%s">
344     <physical>
345       <pfn filetype="ROOT_All" name="--GENERATED--%s"/>
346     </physical>
347     <logical>
348       <lfn name="%s"/>
349     </logical>
350   </File>
351 """ % (guid,pfnleaf,lfn))
352 
353     def close(self):
354         "Close the file, writing trailer"
355         self.catfile.write('</POOLFILECATALOG>\n')
356         self.catfile.close()
357     
358         
359 
360 if __name__=='__main__':
361     # command line driver
362     import getopt
363     def usage():
364         print"usage: AtlCoolCheckFiles.py {<options>} dbname top-level-tag {top-level-tag}"
365         print "  dbname is instance e.g. OFLP200 or full COOL connect-string"
366         print "  top-level-tag(s) is global tag in the database instance"
367         print "Options are:"
368         print "--help :      Display this help"
369         print "--debug :     Dump full output from AtlCoolCopy command"
370         print "--rs=<run>    First run to consider"
371         print "--ru=<run>    Last run to consider (inclusive)"
372         print "--r=<run>     Consider single run"
373         print "--geo=<geometry tag>: Only include magic tags for given geometry"
374         print "--readoracle: Read data from Oracle rather than DBrelease"
375         print "--open: Actually open POOL files to check GUID"
376         print "--output=<file>: Output POOL catalogue data on <file>"
377         print "--poolall: List all POOL files referenced, not only those with errors"
378         print "--poolcat=<cat>: Use specific catalogue rather than defaults"
379         print "--nocat :     Do not attach any POOL file catalogues"
380         print "--makecd <file> : Make CDRelease POOL file tarball with given name"
381         print "--ignoremissing : Ignore missing files when making CDRelease"
382         print "--passopt=\"<options>\": Pass additional options to AtlCoolCopy"
383         print "--parfile <file> : Pass file as additional options to AtlCoolCopy"
384     try:
385         longopts=['r=','rs=','ru=','readoracle','open','nocat','output=',
386                   'poolcat=','debug','passopt=','parfile=','makecd=','geo=',
387                   'poolall','ignoremissing','help']
388         opts,args=getopt.getopt(sys.argv[1:],'',longopts)
389     except getopt.GetoptError,e:
390         print e
391         usage()
392         sys.exit(-1)
393     if (len(args)<2):
394         usage()
395         sys.exit(-1)
396     dbname=args[0]
397     tags=args[1:]
398     # set defaults
399     runsince=0
400     rununtil=(2 << 31)-1
401     filename=""
402     oracle=False
403     openfile=False
404     nocat=False
405     verbose=False
406     parfiles=[]
407     poolcats=[]
408     geo=[]
409     makecd=""
410     passopt=""
411     ignoremissing=False
412     # process options
413     for o,a in opts:
414         if (o=='--rs'):
415             runsince=int(a)
416         if (o=='--ru'):
417             rununtil=int(a)
418         if (o=='--r'):
419             runsince=int(a)
420             rununtil=runsince
421         if (o=='--open'):
422             openfile=True
423         if (o=='--nocat'):
424             nocat=True
425         if (o=='--output'):
426             filename=str(a)
427         if (o=='--readoracle'):
428             oracle=True
429         if (o=='--poolcat'):
430             poolcats+=[str(a)]
431         if (o=='--parfile'):
432             parfiles+=[str(a)]
433         if (o=='--debug'):
434             verbose=True
435         if (o=='--passopt'):
436             passopt+=str(a)+" "
437         if (o=='--poolall'):
438             passopt+='-poolall '
439         if (o=='--geo'):
440             geo+=[str(a)]
441         if (o=='--makecd'):
442             makecd=str(a)
443             passopt+='-poolall -listpfn '
444         if (o=='--ignoremissing'):
445             ignoremissing=True
446         if (o=='--help'):
447             usage()
448             sys.exit()
449     # consider all geometry magic tags if none given
450     if len(geo)==0: geo=['ATLAS-']
451     
452     myCheck=checkFile(dbname,tags,runsince,rununtil,filename,
453                       verbose,oracle,openfile,nocat,poolcats,geo,parfiles,passopt)
454     rc=myCheck.execute()
455     if (makecd!=""): myCheck.makeCD(makecd,ignoremissing)
456     

source navigation ] diff markup ] identifier search ] general search ]

Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems
This page was automatically generated by the LXR engine. Valid HTML 4.01!