CMS 3D CMS Logo

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