CMS 3D CMS Logo

cond2xml.py
Go to the documentation of this file.
1 
2 import os
3 import shutil
4 import sys
5 import time
6 import glob
7 import importlib
8 import logging
9 import subprocess
10 
11 # as we need to load the shared lib from here, make sure it's in our path:
12 if os.path.join( os.environ['CMSSW_BASE'], 'src') not in sys.path:
13  sys.path.append( os.path.join( os.environ['CMSSW_BASE'], 'src') )
14 
15 # -------------------------------------------------------------------------------------------------------
16 
17 payload2xmlCodeTemplate = """
18 
19 #include "CondCore/Utilities/interface/Payload2XMLModule.h"
20 #include "CondCore/Utilities/src/CondFormats.h"
21 
22 PAYLOAD_2XML_MODULE( %s ){
23  PAYLOAD_2XML_CLASS( %s );
24 }
25 
26 """
27 
28 buildFileTemplate = """
29 <flags CXXFLAGS="-Wno-sign-compare -Wno-unused-variable -Os"/>
30 <library file="%s" name="%s">
31  <use name="CondCore/Utilities"/>
32  <use name="boost_python"/>
33 </library>
34 <export>
35  <lib name="1"/>
36 </export>
37 """
38 
39 # helper function
40 def sanitize(typeName):
41  return typeName.replace(' ','').replace('<','_').replace('>','')
42 
43 def localLibName( payloadType ):
44  # required to avoid ( unlikely ) clashes between lib names from templates and lib names from classes
45  prefix = ''
46  if '<' in payloadType and '>' in payloadType:
47  prefix = 't'
48  return "%s_%spayload2xml" %(sanitize(payloadType),prefix)
49 
51 
52  def __init__(self, condDBIn):
53  self.conddb = condDBIn
54 
55  if not os.path.exists( os.path.join( os.environ['CMSSW_BASE'], 'src') ):
56  raise Exception("Looks like you are not running in a CMSSW developer area, $CMSSW_BASE/src/ does not exist")
57 
58  self.fakePkgName = "fakeSubSys4pl/fakePkg4pl"
59  self._pl2xml_tmpDir = os.path.join( os.environ['CMSSW_BASE'], 'src', self.fakePkgName )
60 
61  self.doCleanup = False
62 
63  def __del__(self):
64 
65  if self.doCleanup:
66  shutil.rmtree( '/'.join( self._pl2xml_tmpDir.split('/')[:-1] ) )
67  return
68 
69  def discover(self, payloadType):
70 
71  libName = 'pluginUtilities_payload2xml.so'
72  # first search: developer area or main release
73  libDir = os.path.join( os.environ["CMSSW_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
74  devLibDir = libDir
75  libPath = os.path.join( devLibDir, libName )
76  releaseBase = os.environ["CMSSW_RELEASE_BASE"]
77  devCheckout = (releaseBase != '')
78  if not devCheckout:
79  logging.debug('Looks like the current working environment is a read-only release')
80  if not os.path.exists( libPath ) and devCheckout:
81  # main release ( for dev checkouts )
82  libDir = os.path.join( releaseBase, 'lib', os.environ["SCRAM_ARCH"] )
83  libPath = os.path.join( libDir, libName )
84  if not os.path.exists( libPath ):
85  if "CMSSW_FULL_RELEASE_BASE" in os.environ:
86  libDir = os.path.join( os.environ["CMSSW_FULL_RELEASE_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
87  libPath = os.path.join( libDir, libName )
88  if not os.path.exists( libPath ):
89  # it should never happen!
90  raise Exception('No built-in library %s found with XML converters.' %libPath)
91  logging.debug("Importing built-in library %s" %libPath)
92  module = importlib.import_module( libName.replace('.so', '') )
93  functors = dir(module)
94  funcName = payloadType+'2xml'
95  if funcName in functors:
96  logging.info('XML converter for payload class %s found in the built-in library.' %payloadType)
97  return getattr( module, funcName)
98  if not devCheckout:
99  # give-up if it is a read-only release...
100  raise Exception('No XML converter suitable for payload class %s has been found in the built-in library.')
101  libName = 'plugin%s.so' %localLibName( payloadType )
102  libPath = os.path.join( devLibDir, libName )
103  if os.path.exists( libPath ):
104  logging.info('Found local library with XML converter for class %s' %payloadType )
105  module = importlib.import_module( libName.replace('.so', '') )
106  return getattr( module, funcName)
107  logging.warning('No XML converter for payload class %s found in the built-in library.' %payloadType)
108  return None
109 
110  def prepPayload2xml(self, payloadType):
111 
112  converter = self.discover(payloadType)
113  if converter: return converter
114 
115  #otherwise, go for the code generation in the local checkout area.
116  startTime = time.time()
117 
118  libName = localLibName( payloadType )
119  pluginName = 'plugin%s' % libName
120  tmpLibName = "Tmp_payload2xml"
121  tmpPluginName = 'plugin%s' %tmpLibName
122 
123  libDir = os.path.join( os.environ["CMSSW_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
124  tmpLibFile = os.path.join( libDir,tmpPluginName+'.so' )
125  code = payload2xmlCodeTemplate %(pluginName,payloadType)
126 
127  tmpSrcFileName = 'Local_2XML.cpp'
128  tmpDir = self._pl2xml_tmpDir
129  if ( os.path.exists( tmpDir ) ) :
130  msg = '\nERROR: %s already exists, please remove if you did not create that manually !!' % tmpDir
131  raise Exception(msg)
132 
133  logging.debug('Creating temporary package %s' %self._pl2xml_tmpDir)
134  os.makedirs( tmpDir+'/plugins' )
135 
136  buildFileName = "%s/plugins/BuildFile.xml" % (tmpDir,)
137  with open(buildFileName, 'w') as buildFile:
138  buildFile.write( buildFileTemplate %(tmpSrcFileName,tmpLibName) )
139  buildFile.close()
140 
141  tmpSrcFilePath = "%s/plugins/%s" % (tmpDir, tmpSrcFileName,)
142  with open(tmpSrcFilePath, 'w') as codeFile:
143  codeFile.write(code)
144  codeFile.close()
145 
146  cmd = "source /afs/cern.ch/cms/cmsset_default.sh;"
147  cmd += "(cd %s ; scram b 2>&1 >build.log)" %tmpDir
148  pipe = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
149  out, err = pipe.communicate()
150  ret = pipe.returncode
151 
152  buildTime = time.time()-startTime
153  logging.info("Building done in %s sec., return code from build: %s" %(buildTime,ret) )
154 
155  if (ret != 0):
156  return None
157 
158  libFile = os.path.join(libDir,pluginName + '.so')
159  shutil.copyfile(tmpLibFile,libFile)
160 
161  module = importlib.import_module( pluginName )
162  funcName = payloadType+'2xml'
163  functor = getattr( module, funcName )
164  self.doCleanup = True
165  return functor
166 
167  def payload2xml(self, session, payloadHash, destFile):
168 
169  Payload = session.get_dbtype(self.conddb.Payload)
170  # get payload from DB:
171  result = session.query(Payload.data, Payload.object_type).filter(Payload.hash == payloadHash).one()
172  data, plType = result
173  logging.info('Found payload of type %s' %plType)
174 
175  convFuncName = sanitize(plType)+'2xml'
176  xmlConverter = self.prepPayload2xml(plType)
177 
178  obj = xmlConverter()
179  resultXML = obj.write( str(data) )
180  if destFile is None:
181  print resultXML
182  else:
183  with open(destFile, 'w') as outFile:
184  outFile.write(resultXML)
185  outFile.close()
def __init__(self, condDBIn)
Definition: cond2xml.py:52
def localLibName(payloadType)
Definition: cond2xml.py:43
def payload2xml(self, session, payloadHash, destFile)
Definition: cond2xml.py:167
def replace(string, replacements)
def sanitize(typeName)
Definition: cond2xml.py:40
def prepPayload2xml(self, payloadType)
Definition: cond2xml.py:110
def discover(self, payloadType)
Definition: cond2xml.py:69
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
dbl *** dir
Definition: mlp_gen.cc:35