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