CMS 3D CMS Logo

conddb_migrate.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 '''CMS Conditions DB migration script.
3 '''
4 
5 
6 import os
7 import sys
8 import logging
9 import argparse
10 import subprocess
11 import time
12 import multiprocessing
13 
14 import cx_Oracle
15 
16 
17 accounts = [
18  #'CMS_COND_TEMP', # not in payloadInspector
19  'CMS_COND_31X_ALIGNMENT',
20  'CMS_COND_31X_BEAMSPOT',
21  'CMS_COND_31X_BTAU',
22  'CMS_COND_31X_CSC',
23  'CMS_COND_31X_DQM_SUMMARY',
24  'CMS_COND_31X_DT',
25  'CMS_COND_31X_ECAL',
26  'CMS_COND_31X_FROM21X',
27  'CMS_COND_31X_GEOMETRY',
28  'CMS_COND_31X_HCAL',
29  'CMS_COND_31X_HLT',
30  'CMS_COND_31X_L1T',
31  'CMS_COND_31X_PHYSICSTOOLS',
32  'CMS_COND_31X_PIXEL',
33  'CMS_COND_31X_PRESHOWER',
34  'CMS_COND_31X_RPC',
35  'CMS_COND_31X_RUN_INFO',
36  'CMS_COND_31X_STRIP',
37  'CMS_COND_34X_DQM',
38  'CMS_COND_34X_ECAL',
39  'CMS_COND_34X_ECAL_PED',
40  'CMS_COND_34X_GEOMETRY',
41  'CMS_COND_36X_RPC',
42  'CMS_COND_38X_HCAL',
43  #'CMS_COND_38X_PIXEL', # not in payloadInspector
44  'CMS_COND_39X_PRESHOWER',
45  #'CMS_COND_310X_ALIGN', # FIXME: Segmentation fault
46  'CMS_COND_310X_CSC',
47  'CMS_COND_310X_ECAL_PED',
48  'CMS_COND_311X_ECAL_LAS',
49  'CMS_COND_311X_PRESH',
50  'CMS_COND_42X_DQM',
51  'CMS_COND_42X_ECAL_LAS',
52  'CMS_COND_42X_ECAL_LASP',
53  'CMS_COND_42X_GEOMETRY',
54  'CMS_COND_42X_HCAL',
55  'CMS_COND_42X_RUN_INFO',
56  'CMS_COND_43X_ECAL',
57  #'CMS_COND_43X_RPC_NOISE', # not in payloadInspector
58  'CMS_COND_44X_ECAL',
59  'CMS_COND_44X_GEOMETRY',
60  'CMS_COND_44X_HCAL',
61  'CMS_COND_44X_PHYSICSTOOLS',
62  #'CMS_COND_44X_RPC', # not in payloadInspector
63  'CMS_COND_ALIGN_000',
64  'CMS_COND_BEAMSPOT_000',
65  'CMS_COND_BTAU_000',
66  'CMS_COND_CSC_000',
67  'CMS_COND_DQM_000',
68  'CMS_COND_DT_000',
69  'CMS_COND_ECAL_000',
70  'CMS_COND_ECAL_LAS_000',
71  'CMS_COND_ECAL_PED_000',
72  'CMS_COND_GEOMETRY_000',
73  'CMS_COND_HCAL_000',
74  'CMS_COND_HLT_000',
75  'CMS_COND_L1T_000',
76  'CMS_COND_MC_000',
77  'CMS_COND_PAT_000',
78  'CMS_COND_PIXEL_000',
79  'CMS_COND_PRESH_000',
80  'CMS_COND_RPC_000',
81  'CMS_COND_RUNINFO_000',
82  'CMS_COND_STRIP_000',
83 ]
84 
85 
86 def run_command(command, output_file):
87  command = '%s > %s 2>&1' % (command, output_file)
88  logging.info('Running %s', command)
89  try:
90  subprocess.check_call(command, shell=True)
91  except subprocess.CalledProcessError as e:
92  logging.error('Error while running %s: return code %s', command, e.returncode)
93 
94 
95 def migrate_account(args):
96  command_template = '$CMSSW_BASE/bin/$SCRAM_ARCH/conddb_migrate -s oracle://cms_orcon_adg/%s -d %s'
97  command = command_template % (args.account, args.db)
98  run_command(command, os.path.join(args.output, args.account))
99 
100 
102  def _make_args(args, account):
103  newargs = argparse.Namespace(**vars(args))
104  newargs.account = account
105  return newargs
106 
107  multiprocessing.Pool(args.jobs).map(migrate_account, [_make_args(args, account) for account in accounts])
108 
109 
110 def migrate_gt(args):
111  command_template = '$CMSSW_BASE/bin/$SCRAM_ARCH/conddb_migrate_gt -s oracle://cms_orcon_adg/CMS_COND_31X_GLOBALTAG -d %s -g %s'
112  command = command_template % (args.db, args.gt)
113  run_command(command, os.path.join(args.output, args.gt))
114 
115 
117  logging.info('Fetching global tag list...')
118  password = subprocess.check_output('''cat %s | grep -F 'CMS_COND_31X_GLOBALTAG' -2 | tail -1 | cut -d'"' -f4''' % os.path.join(args.authpath, 'readOnlyProd.xml'), shell=True).strip()
119  return cx_Oracle.connect('CMS_COND_GENERAL_R', password, 'cms_orcon_adg')
120 
121 
122 def fetch_gts(connection):
123  logging.info('Fetching global tag list...')
124  cursor = connection.cursor()
125  cursor.execute('''
126  select substr(table_name, length('tagtree_table_') + 1) gt
127  from all_tables
128  where owner = 'CMS_COND_31X_GLOBALTAG'
129  and table_name like 'TAGTREE_TABLE_%'
130  order by gt
131  ''')
132  gts = zip(*cursor.fetchall())[0]
133  logging.info('Fetching global tag list... Done: %s global tags found.', len(gts))
134  return gts
135 
136 
137 def migrate_gts(args):
138  gts = fetch_gts(make_gt_connection(args))
139 
140  def _make_args(args, gt):
141  newargs = argparse.Namespace(**vars(args))
142  newargs.gt = gt
143  return newargs
144 
145  multiprocessing.Pool(args.jobs).map(migrate_gt, [_make_args(args, gt) for gt in gts])
146 
147 
148 def tags_in_gts(args):
149  # Dynamic SQL is used due to the schema
150  # This is OK since we trust the input,
151  # which is the GT database's tables.
152 
153  connection = make_gt_connection(args)
154  gts = fetch_gts(connection)
155  account_tags = {}
156 
157  for i, gt in enumerate(gts):
158  logging.info('[%s/%s] Reading %s ...', i+1, len(gts), gt)
159  cursor = connection.cursor()
160  cursor.execute('''
161  select "pfn", "tagname"
162  from CMS_COND_31X_GLOBALTAG.TAGINVENTORY_TABLE
163  where "tagid" in (
164  select "tagid"
165  from CMS_COND_31X_GLOBALTAG.TAGTREE_TABLE_%s
166  )
167  ''' % gt)
168 
169  for account, tag in cursor:
170  account_tags.setdefault(account, set([])).add(tag)
171 
172  for account in sorted(account_tags):
173  print account
174  for tag in sorted(account_tags[account]):
175  print ' ', tag
176  print
177 
178 
179 def check_and_run(args):
180  if 'SCRAM_ARCH' not in os.environ:
181  raise Exception('SCRAM_ARCH needs to be set: run cmsenv within a newish release.')
182 
183  if 'CMSSW_BASE' not in os.environ:
184  raise Exception('CMSSW_BASE needs to be set: run cmsenv within a newish release.')
185 
186  if 'jobs' in args and args.jobs <= 0:
187  raise Exception('If set, --jobs needs to be >= 1.')
188 
189  aliases = {
190  'root': 'oracle://cms_orcoff_prep/CMS_R5_CONDITIONS',
191  'boost': 'oracle://cms_orcoff_prep/CMS_CONDITIONS',
192  }
193 
194  if args.db in aliases:
195  args.db = aliases[args.db]
196 
197  # Check that the release and database match to prevent mistakes...
198  if args.db == 'oracle://cms_orcoff_prep/CMS_CONDITIONS' and \
199  not 'BOOST' in os.environ['CMSSW_VERSION']:
200  raise Exception('Boost database without a Boost release -- mistake?')
201 
202  if args.db == 'oracle://cms_orcoff_prep/CMS_R5_CONDITIONS' and \
203  'BOOST' in os.environ['CMSSW_VERSION']:
204  raise Exception('ROOT database with a Boost release -- mistake?')
205 
206  # Create output log folder
207  os.makedirs(args.output)
208 
209  args.func(args)
210 
211 
212 def main():
213  '''Entry point.
214  '''
215 
216  parser = argparse.ArgumentParser(description='conddb_migrate - the CMS Conditions DB migration script')
217  parser.add_argument('--verbose', '-v', action='count', help='Verbosity level. -v prints debugging information of this tool, like tracebacks in case of errors.')
218  parser.add_argument('--output', '-o', default=time.strftime('%Y-%m-%d-%H-%M-%S'), help='Output folder. Default: {current_timestamp}, i.e. %(default)s')
219  parser.add_argument('db', help='Destination database. Aliases: "root" (CMS_CONDITIONS), "boost" (CMS_TEST_CONDITIONS), both in prep. *Make sure the database kind matches the code, i.e. use a BOOST IB when uploading to a Boost database; and a normal release when uploading to the ROOT database -- this script checks the CMSSW_VERSION when using the two official aliases in prep to prevent mistakes, but not for other databases.*')
220  parser_subparsers = parser.add_subparsers(title='Available subcommands')
221 
222  parser_account = parser_subparsers.add_parser('account', description='Migrates all (non-migrated) tags, IOVs and payloads, from an account.')
223  parser_account.add_argument('account', help='The account to migrate.')
224  parser_account.set_defaults(func=migrate_account)
225 
226  parser_accounts = parser_subparsers.add_parser('accounts', description='Migrates all accounts (see "account" command).')
227  parser_accounts.add_argument('--jobs', '-j', type=int, default=4, help='Number of jobs.')
228  parser_accounts.set_defaults(func=migrate_accounts)
229 
230  parser_gt = parser_subparsers.add_parser('gt', description='Migrates a single global tag.')
231  parser_gt.add_argument('gt', help='The global tag to migrate.')
232  parser_gt.set_defaults(func=migrate_gt)
233 
234  parser_gts = parser_subparsers.add_parser('gts', description='Migrates all global tags (see "gt" command).')
235  parser_gts.add_argument('authpath', help='Authentication path.')
236  parser_gts.add_argument('--jobs', '-j', type=int, default=4, help='Number of jobs.')
237  parser_gts.set_defaults(func=migrate_gts)
238 
239  parser_tags_in_gts = parser_subparsers.add_parser('tags_in_gts', description='Dumps the set of tags (including account name) which are in each global tag.')
240  parser_tags_in_gts.add_argument('authpath', help='Authentication path.')
241  parser_tags_in_gts.set_defaults(func=tags_in_gts)
242 
243  args = parser.parse_args()
244 
245  logging.basicConfig(
246  format = '[%(asctime)s] %(levelname)s: %(message)s',
247  level = logging.DEBUG if args.verbose >= 1 else logging.INFO,
248  )
249 
250  if args.verbose >= 1:
251  # Include the traceback
252  check_and_run(args)
253  else:
254  # Only one error line
255  try:
256  check_and_run(args)
257  except Exception as e:
258  logging.error(e)
259  sys.exit(1)
260 
261 
262 if __name__ == '__main__':
263  main()
264 
def fetch_gts(connection)
def migrate_account(args)
def make_gt_connection(args)
def tags_in_gts(args)
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
def check_and_run(args)
def migrate_gts(args)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def migrate_gt(args)
def migrate_accounts(args)
Definition: main.py:1
def run_command(command, output_file)