CMS 3D CMS Logo

confdbOfflineConverter.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 import sys, os
3 import os.path
4 import tempfile
5 import urllib.request
6 import shutil
7 import subprocess
8 import atexit
9 from collections import Counter
10 
12 
13  # the machine aliases and interfaces for the *online* database are
14  # cmsonr1-s.cms, cmsonr2-s.cms, cmsonr3-s.cms
15  # cmsonr1-v.cms, cmsonr2-v.cms, cmsonr3-v.cms
16  # but the -s and -v interfaces resolve to the same hosts.
17  # The actual machines and interfaces are
18  # CMSRAC11-S.cms, CMSRAC12-S.cms, CMSRAC21-S.cms
19  # CMSRAC11-V.cms, CMSRAC12-V.cms, CMSRAC21-V.cms
20 
21  # the possible machines and interfaces for the *offline* database are
22  # cmsr1-s.cms, cmsr2-s.cms, cmsr3-s.cms
23  # cmsr1-v.cms, cmsr2-v.cms, cmsr3-v.cms
24  # but the -s and -v interfaces resolve to the same hosts
25  # The actual machines and interfaces are
26  # itrac50011-s.cern.ch, itrac50063-s.cern.ch, itrac50078-s.cern.ch
27  # itrac50011-v.cern.ch, itrac50063-v.cern.ch, itrac50078-v.cern.ch
28 
29  databases = {}
30  databases['v1'] = {}
31  databases['v1']['offline'] = ( '-t', 'oracle', '-h', 'cmsr1-s.cern.ch', '-d', 'cms_cond.cern.ch', '-u', 'cms_hltdev_reader', '-s', 'convertMe!' )
32  databases['v1']['hltdev'] = databases['v1']['offline'] # for backwards compatibility
33  databases['v1']['online'] = ( '-t', 'oracle', '-h', 'cmsonr1-s.cms', '-d', 'cms_rcms.cern.ch', '-u', 'cms_hlt_r', '-s', 'convertMe!' )
34  databases['v1']['adg'] = ( '-t', 'oracle', '-h', 'cmsr1-s.cern.ch', '-d', 'cms_cond.cern.ch', '-u', 'cms_hlt_gui_r', '-s', 'convertMe!' )
35  databases['v1']['orcoff'] = databases['v1']['adg'] # for backwards compatibility
36  databases['v3'] = {}
37  databases['v3']['run2'] = ( '-t', 'oracle', '-h', 'cmsr1-s.cern.ch,cmsr2-s.cern.ch,cmsr3-s.cern.ch', '-d', 'cms_hlt.cern.ch', '-u', 'cms_hlt_gdr_r', '-s', 'convertMe!' )
38  databases['v3']['run3'] = ( '-t', 'oracle', '-h', 'cmsr1-s.cern.ch,cmsr2-s.cern.ch,cmsr3-s.cern.ch', '-d', 'cms_hlt.cern.ch', '-u', 'cms_hlt_v3_r', '-s', 'convertMe!' )
39  databases['v3']['dev'] = ( '-t', 'oracle', '-h', 'cmsr1-s.cern.ch,cmsr2-s.cern.ch,cmsr3-s.cern.ch', '-d', 'cms_hlt.cern.ch', '-u', 'cms_hlt_gdrdev_r', '-s', 'convertMe1!' )
40  databases['v3']['online'] = ( '-t', 'oracle', '-h', 'cmsonr1-s.cms', '-d', 'cms_rcms.cern.ch', '-u', 'cms_hlt_gdr_r', '-s', 'convertMe!' )
41  databases['v3']['adg'] = ( '-t', 'oracle', '-h', 'cmsonr1-adg1-s.cern.ch', '-d', 'cms_orcon_adg.cern.ch', '-u', 'cms_hlt_gdr_r', '-s', 'convertMe!' )
42  databases['v3-beta'] = dict(databases['v3'])
43  databases['v3-test'] = dict(databases['v3'])
44  databases['v2'] = dict(databases['v3'])
45  #old converter can only handle a single host so we modify the params accordingly
46  for dbkey in databases['v2']:
47  dbparams = databases['v2'][dbkey]
48  if dbparams[3]=='cmsr1-s.cern.ch,cmsr2-s.cern.ch,cmsr3-s.cern.ch':
49  databases['v2'][dbkey] = dbparams[0:3]+('cmsr1-s.cern.ch',)+dbparams[4:]
50 
51  @staticmethod
53  dir = os.path.realpath(dir)
54  if not os.path.isdir(dir):
55  try:
56  os.makedirs(dir)
57  except:
58  return None
59  return dir
60 
61 
62  def __init__(self, version = 'v3', database = 'run3', url = None, verbose = False):
63  self.verbose = verbose
64  self.version = version
65  self.baseDir = '/afs/cern.ch/user/c/confdb/www/%s/lib' % version
66  self.baseUrl = 'https://confdb.web.cern.ch/confdb/%s/lib' % version
67  self.jars = ( 'ojdbc8.jar', 'cmssw-evf-confdb-converter.jar' )
68  if version=='v2':
69  #legacy driver for run2 gui
70  self.jars = ( 'ojdbc6.jar', 'cmssw-evf-confdb-converter.jar' )
71  self.workDir = ''
72 
73  # check the schema version
74  if version not in self.databases:
75  # unsupported database version
76  sys.stderr.write( "ERROR: unsupported database version \"%s\"\n" % version)
77 
78  # check the database
79  if database in self.databases[version]:
80  # load the connection parameters for the given database
81  self.connect = self.databases[version][database]
82  else:
83  # unsupported database
84  sys.stderr.write( "ERROR: unknown database \"%s\" for version \"%s\"\n" % (database, version))
85  sys.exit(1)
86 
87  # check for a custom base URL
88  if url is not None:
89  self.baseUrl = url
90 
91  # try to read the .jar files from AFS, or download them
92  if os.path.isdir(self.baseDir) and all(os.path.isfile(self.baseDir + '/' + jar) for jar in self.jars):
93  # read the .jar fles from AFS
94  self.workDir = self.baseDir
95  else:
96  # try to use $CMSSW_BASE/tmp
97  self.workDir = OfflineConverter.CheckTempDirectory(os.environ['CMSSW_BASE'] + '/tmp/confdb')
98  if not self.workDir:
99  # try to use $TMP
100  self.workDir = OfflineConverter.CheckTempDirectory(os.environ['TMP'] + '/confdb')
101  if not self.workDir:
102  # create a new temporary directory, and install a cleanup callback
103  self.workDir = tempfile.mkdtemp()
104  atexit.register(shutil.rmtree, self.workDir)
105  # download the .jar files
106  for jar in self.jars:
107  # check if the file is already present
108  if os.path.exists(self.workDir + '/' + jar):
109  continue
110  # download to a temporay name and use an atomic rename (in case an other istance is downloading the same file
111  handle, temp = tempfile.mkstemp(dir = self.workDir, prefix = jar + '.')
112  os.close(handle)
113  urllib.request.urlretrieve(self.baseUrl + '/' + jar, temp)
114  if not os.path.exists(self.workDir + '/' + jar):
115  os.rename(temp, self.workDir + '/' + jar)
116  else:
117  os.unlink(temp)
118 
119  # setup the java command line and CLASSPATH
120  if self.verbose:
121  sys.stderr.write("workDir = %s\n" % self.workDir)
122  # use non-blocking random number source /dev/urandom (instead of /dev/random), see:
123  # http://blockdump.blogspot.fr/2012/07/connection-problems-inbound-connection.html
124  # deal with timezone region not found
125  # http://stackoverflow.com/questions/9156379/ora-01882-timezone-region-not-found
126  # increase the thread stack size from the default of 1 MB to work around java.lang.StackOverflowError errors, see
127  # man java
128  self.javaCmd = ( 'java', '-cp', ':'.join(self.workDir + '/' + jar for jar in self.jars), '-Djava.security.egd=file:///dev/urandom', '-Doracle.jdbc.timezoneAsRegion=false', '-Xss32M', 'confdb.converter.BrowserConverter' )
129 
130 
131  def query(self, *args):
132  args = self.javaCmd + self.connect + args
133  if self.verbose:
134  sys.stderr.write("\n" + ' '.join(args) + "\n\n" )
135  sub = subprocess.Popen(
136  args,
137  stdin = None,
138  stdout = subprocess.PIPE,
139  stderr = subprocess.PIPE,
140  shell = False,
141  universal_newlines = True )
142  return sub.communicate()
143 
144 def help():
145  sys.stdout.write("""Usage: %s OPTIONS
146 
147  --v1|--v2|--v3|--v3-beta|--v3-test (specify the ConfDB version [default: v3])
148 
149  --run3|--run2|--dev|--online|--adg (specify the target db [default: run3], online will only work inside p5 network)
150 
151  Note that for v1
152  --orcoff is a synonim of --adg
153  --offline is a synonim of --hltdev
154 
155  --configId <id> (specify the configuration by id)
156  --configName <name> (specify the configuration by name)
157  --runNumber <run> (specify the configuration by run number)
158  [exactly one of --configId OR --configName OR --runNumber is required]
159 
160  --cff (retrieve configuration *fragment*)
161  --input <f1.root[,f2.root]> (insert PoolSource with specified fileNames)
162  --input <files.list> (read a text file which lists input ROOT files)
163  --output <out.root> (insert PoolOutputModule w/ specified fileName)
164  --nopsets (exclude all globale psets)
165  --noedsources (exclude all edsources)
166  --noes (exclude all essources *and* esmodules)
167  --noessources (exclude all essources)
168  --noesmodules (exclude all esmodules)
169  --noservices (exclude all services)
170  --nooutput (exclude all output modules)
171  --nopaths (exclude all paths [+=referenced seqs&mods])
172  --nosequences (don't define sequences [+=referenced s&m])
173  --nomodules (don't define modules)
174  --psets <pset1[,pset2]> (include only specified global psets)
175  --psets <-pset1[,-pset2]> (include all global psets but the specified)
176  --essources <ess1[,ess2]> (include only specified essources)
177  --essources <-ess1[,-ess2]> (include all essources but the specified)
178  --esmodules <esm1[,esm2]> (include only specified esmodules)
179  --esmodules <-esm1[,-esm2]> (include all esmodules but the specified)
180  --services <svc1[,svc2]> (include only specified services)
181  --services <-svc1[,-svc2]> (include all services but the specified)
182  --paths <p1[,p2]> (include only specified paths)
183  --paths <-p1[,-p2]> (include all paths but the specified)
184  --streams <s1[,s2]> (include only specified streams)
185  --datasets <d1[,d2]> (include only specified datasets)
186  --sequences <s1[,s2]> (include sequences, referenced or not!)
187  --modules <p1[,p2]> (include modules, referenced or not!)
188  --blocks <m1::p1[,p2][,m2]> (generate parameter blocks)
189 
190  --verbose (print additional details)
191 """)
192 
193 
194 def main():
195  args = sys.argv[1:]
196  version = 'v3'
197  db = 'run3'
198  verbose = False
199 
200  if not args:
201  help()
202  sys.exit(1)
203 
204  if '--help' in args or '-h' in args:
205  help()
206  sys.exit(0)
207 
208  if '--verbose' in args:
209  verbose = True
210  args.remove('--verbose')
211 
212  arg_count = Counter(args)
213  db_count = arg_count['--v1'] + arg_count['--v2'] + arg_count['--v3'] + arg_count['--v3-beta'] + arg_count['--v3-test']
214  if db_count>1:
215  sys.stderr.write( 'ERROR: conflicting database version specifications: "--v1", "--v2", "--v3", "--v3-beta", and "--v3-test" are mutually exclusive options' )
216  sys.exit(1)
217 
218  if '--v1' in args:
219  version = 'v1'
220  db = 'offline'
221  args.remove('--v1')
222 
223  if '--v2' in args:
224  version = 'v2'
225  db = 'run2'
226  args.remove('--v2')
227 
228  if '--v3' in args:
229  version = 'v3'
230  db = 'run3'
231  args.remove('--v3')
232 
233  if '--v3-beta' in args:
234  version = 'v3-beta'
235  db = 'run3'
236  args.remove('--v3-beta')
237 
238  if '--v3-test' in args:
239  version = 'v3-test'
240  db = 'dev'
241  args.remove('--v3-test')
242 
243  _dbs = {}
244  _dbs['v1'] = [ '--%s' % _db for _db in OfflineConverter.databases['v1'] ] + [ '--runNumber' ]
245  _dbs['v2'] = [ '--%s' % _db for _db in OfflineConverter.databases['v2'] ] + [ '--runNumber' ]
246  _dbs['v3'] = [ '--%s' % _db for _db in OfflineConverter.databases['v3'] ] + [ '--runNumber']
247  _dbs['v3-beta'] = [ '--%s' % _db for _db in OfflineConverter.databases['v3-beta'] ] + [ '--runNumber' ]
248  _dbs['v3-test'] = [ '--%s' % _db for _db in OfflineConverter.databases['v3-test'] ] + [ '--runNumber' ]
249  _dbargs = set(args) & set(sum(_dbs.values(), []))
250 
251  if _dbargs:
252  if len(_dbargs) > 1:
253  sys.stderr.write( "ERROR: too many database specifications: \"" + "\", \"".join( _dbargs) + "\"\n" )
254  sys.exit(1)
255 
256  _arg = _dbargs.pop()
257  db = _arg[2:]
258  if db == 'runNumber':
259  db = 'adg'
260  else:
261  args.remove(_arg)
262 
263  if not db in OfflineConverter.databases[version]:
264  sys.stderr.write( "ERROR: database version \"%s\" incompatible with specification \"%s\"\n" % (version, db) )
265  sys.exit(1)
266 
267  converter = OfflineConverter(version = version, database = db, verbose = verbose)
268  out, err = converter.query( * args )
269  if 'ERROR' in err:
270  sys.stderr.write( "%s: error while retriving the HLT menu\n\n%s\n\n" % (sys.argv[0], err) )
271  sys.exit(1)
272  else:
273  sys.stdout.write( out )
274 
275 
276 if __name__ == "__main__":
277  main()
align::Counter
std::function< unsigned int(align::ID)> Counter
Definition: AlignableIndexer.h:31
confdbOfflineConverter.OfflineConverter.baseUrl
baseUrl
Definition: confdbOfflineConverter.py:66
confdbOfflineConverter.OfflineConverter.javaCmd
javaCmd
Definition: confdbOfflineConverter.py:128
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
python.cmstools.all
def all(container)
workaround iterator generators for ROOT classes
Definition: cmstools.py:25
confdbOfflineConverter.OfflineConverter.verbose
verbose
Definition: confdbOfflineConverter.py:63
confdbOfflineConverter.OfflineConverter
Definition: confdbOfflineConverter.py:11
confdbOfflineConverter.OfflineConverter.version
version
Definition: confdbOfflineConverter.py:64
confdbOfflineConverter.OfflineConverter.connect
connect
Definition: confdbOfflineConverter.py:81
confdbOfflineConverter.OfflineConverter.jars
jars
Definition: confdbOfflineConverter.py:67
confdbOfflineConverter.main
def main()
Definition: confdbOfflineConverter.py:194
confdbOfflineConverter.OfflineConverter.databases
databases
Definition: confdbOfflineConverter.py:29
confdbOfflineConverter.OfflineConverter.__init__
def __init__(self, version='v3', database='run3', url=None, verbose=False)
Definition: confdbOfflineConverter.py:62
main
Definition: main.py:1
confdbOfflineConverter.OfflineConverter.query
def query(self, *args)
Definition: confdbOfflineConverter.py:131
confdbOfflineConverter.help
def help()
Definition: confdbOfflineConverter.py:144
confdbOfflineConverter.OfflineConverter.workDir
workDir
Definition: confdbOfflineConverter.py:71
confdbOfflineConverter.OfflineConverter.CheckTempDirectory
def CheckTempDirectory(dir)
Definition: confdbOfflineConverter.py:52
confdbOfflineConverter.OfflineConverter.baseDir
baseDir
Definition: confdbOfflineConverter.py:65