Skip to content
This repository was archived by the owner on Sep 12, 2024. It is now read-only.

Commit a4c664d

Browse files
authored
Merge branch 'master' into step_core_log
2 parents 49034ba + 401f0e7 commit a4c664d

18 files changed

Lines changed: 296 additions & 163 deletions

RucioClient.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python
2+
"""
3+
Encapsulates requests to Rucio API
4+
Requieres:
5+
rucio-client
6+
Environment:
7+
export X509_USER_PROXY=/tmp/x509up_$UID
8+
export RUCIO_HOME=~/.local/
9+
${RUCIO_HOME}/rucio.cfg
10+
"""
11+
12+
from rucio.client import Client
13+
14+
class RucioClient(Client):
15+
"""
16+
A wrapper class for the Rucio client.
17+
"""
18+
def __init__(self, **kwargs):
19+
"""
20+
Default configuration provided directly into the constructor to avoid
21+
the need of an external configuration file.
22+
All arguments passed to the constructor supersede the defaults.
23+
"""
24+
25+
defaultConfig = {
26+
'rucio_host': 'http://cms-rucio.cern.ch',
27+
'auth_host': 'https://cms-rucio-auth.cern.ch',
28+
'auth_type': 'x509_proxy',
29+
'ca_cert': '/etc/grid-security/certificates/',
30+
'account': 'unified'
31+
}
32+
33+
defaultConfig.update(kwargs)
34+
35+
super(RucioClient, self).__init__(**defaultConfig)
36+
self.scope = 'cms'
37+
38+
def getFileCountDataset(self, dataset):
39+
"""
40+
Returns the number of files registered in Rucio
41+
"""
42+
try:
43+
files = list(self.list_files(self.scope, dataset))
44+
except Exception as e:
45+
print(str(e))
46+
return 0
47+
return len(files)
48+
49+
def getFileNamesDataset(self, dataset):
50+
"""
51+
Returns a set of file names in a dataset registered in Rucio
52+
"""
53+
try:
54+
files = list(self.list_files(self.scope, dataset))
55+
except Exception as e:
56+
print(str(e))
57+
return []
58+
fileNames = [_file['name'] for _file in files]
59+
return fileNames
60+
61+
def getBlockNamesDataset(self, dataset):
62+
"""
63+
Returns a set of block names in a dataset registerd in Rucio
64+
"""
65+
try:
66+
blockNames = [block['name'] for block in self.list_content(self.scope, dataset)]
67+
except Exception as e:
68+
print(str(e))
69+
return []
70+
return blockNames
71+
72+
def getFileCountBlock(self, block):
73+
"""
74+
Returns the number of files in a block registered in Rucio
75+
"""
76+
try:
77+
numFiles = self.get_metadata(self.scope, block)['length']
78+
except Exception as e:
79+
print(str(e))
80+
return 0
81+
return numFiles
82+
83+
def getFileCountPerBlock(self, dataset):
84+
"""
85+
Returns the number of files per block in a dataset registered in Rucio
86+
"""
87+
# we need blocks to be a list of tuples so we can create a set out of this
88+
try:
89+
blocks = []
90+
for block in self.getBlockNamesDataset(dataset):
91+
blocks.append((block, self.getFileCountBlock(block)))
92+
except Exception as e:
93+
print(str(e))
94+
return 0
95+
return blocks
96+

Unified/RucioClient.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../RucioClient.py

Unified/addHoc.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,6 @@
150150
else:
151151
#print d,"is still in use"
152152
pass
153-
154-
## protected lfn list
155-
os.system('python listProtectedLFN.py')
156153

157154
### dump the knonw thresholds
158155
si = siteInfo()

Unified/cachor.py

Lines changed: 0 additions & 58 deletions
This file was deleted.

Unified/checkor.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import time
1616
import random
1717
import math
18+
from RucioClient import RucioClient
1819
from McMClient import McMClient
1920
from JIRAClient import JIRAClient
2021
from htmlor import htmlor
@@ -1012,10 +1013,43 @@ def upward( ns ):
10121013

10131014
time_point("checked custodiality", sub_lap=True)
10141015

1015-
## presence in phedex
1016+
## presence in phedex and/or rucio
10161017
phedex_presence ={}
1018+
rucioClient = RucioClient()
10171019
for output in wfi.request['OutputDatasets']:
1018-
phedex_presence[output] = phedexClient.getFileCountDataset(url, output )
1020+
_,dsn,process_string,tier = output.split('/')
1021+
if tier in set(UC.get('tiers_to_rucio_relval')) | set(UC.get('tiers_to_rucio_nonrelval')):
1022+
# - creates lists of tuples ot the type: ('blockName', numFiles)
1023+
# for all blockNames per Dataset known to both Phedex and Rucio
1024+
# - creates the union of the two sets in order to avoid any duplicates
1025+
# (files present in both systems)
1026+
# - sums the number of files for the union set
1027+
# - assigns the value to 'phedex_presence' even though the full sum
1028+
# of the files is present in both systems - this way we avoid
1029+
# changing the code for the rest of the consistency checks
1030+
phedex_filecount_pb = phedexClient.getFileCountPerBlock(url, output)
1031+
rucio_filecount_pb = rucioClient.getFileCountPerBlock(output)
1032+
all_filecount_pb = set(phedex_filecount_pb) | set(rucio_filecount_pb)
1033+
all_blocks = set(map(lambda x: x[0], phedex_filecount_pb)) | set(map(lambda x: x[0], rucio_filecount_pb))
1034+
1035+
# bellow we will misscount in case there are same blocks in both
1036+
# Rucio and Phedex but with different number of files in the two
1037+
# systems - they will enter the sum twice, because the two tuples
1038+
# will be concidered as two different blocks from the two subsets
1039+
# hence the following check:
1040+
if len(all_blocks) == len(all_filecount_pb):
1041+
phedex_presence[output] = sum(map(lambda x: x[1], all_filecount_pb))
1042+
else:
1043+
# TODO: to check if we need to rise a higher level of alarm here.
1044+
msg = "There are inconsistences of number of files per block"
1045+
msg += "between Phedex and Rucio for dataset: {}".format(output)
1046+
wfi.sendLog('checkor', msg)
1047+
phedex_presence[output] = 0
1048+
# we do not announce this output untill the discrepancy from above is resolved
1049+
del(all_filecount_pb)
1050+
del(all_blocks)
1051+
else:
1052+
phedex_presence[output] = phedexClient.getFileCountDataset(url, output)
10191053

10201054
one_output_not_in_phedex = any([Nfiles==0 for Nfiles in phedex_presence.values()])
10211055
if one_output_not_in_phedex and 'announce' in assistance_tags:
@@ -1055,7 +1089,16 @@ def upward( ns ):
10551089
assistance_tags.add('filemismatch')
10561090
#print this for show and tell if no recovery on-going
10571091
for out in dbs_presence:
1058-
_,_,missing_phedex,missing_dbs = getDatasetFiles(url, out)
1092+
dbs_filenames,phedex_filenames,missing_phedex,missing_dbs = getDatasetFiles(url, out)
1093+
1094+
# Corrections to the lists of files present in Phedex for the data Tiers managed by Rucio
1095+
_,dsn,process_string,tier = output.split('/')
1096+
if tier in set(UC.get('tiers_to_rucio_relval')) | set(UC.get('tiers_to_rucio_nonrelval')):
1097+
# Here recalculating the filenames as a union of the phedex_files | rucio_files
1098+
all_filenames = set(phedex_filenames) | set(rucioClient.getFileNamesDataset(out))
1099+
missing_phedex = list(set(dbs_filenames) - all_filenames)
1100+
missing_dbs = list(all_filenames - set(dbs_filenames))
1101+
10591102
if missing_phedex:
10601103
wfi.sendLog('checkor',"These %d files are missing in phedex, or extra in dbs, showing %s only\n%s"%(len(missing_phedex),show_N_only,
10611104
"\n".join( missing_phedex[:show_N_only] )))

Unified/closor.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ def close(self):
500500
## make the specific relval rules and the replicas
501501
## figure the destination(s) out
502502
destinations = set()
503+
if tier in UC.get("tiers_to_rucio_relval"):
504+
wfi.sendLog('closor', "Data Tier: %s is blacklisted, so skipping dataset placement for: %s" % (tier,out))
505+
continue
503506
if tier != "RECO" and tier != "ALCARECO":
504507
destinations.add('T2_CH_CERN')
505508
if tier == "GEN-SIM":
@@ -541,6 +544,10 @@ def close(self):
541544
to_DDM = True
542545

543546
## by typical enabling
547+
if tier in UC.get("tiers_to_rucio_nonrelval"):
548+
sendLog("Data Tier: %s is blacklisted, so skipping dataset placement for: %s" % (tier,out))
549+
continue
550+
544551
if tier in UC.get("tiers_to_DDM"):
545552
to_DDM = True
546553
## check for unitarity

Unified/htmlor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def htmlor( caller = ""):
1717
up = componentInfo(soft=['mcm','wtc','jira'])
1818
if not up.check(): return
1919

20-
for backup in ['statuses.json','siteInfo.json','listProtectedLFN.txt','equalizor.json']:
20+
for backup in ['statuses.json','siteInfo.json','equalizor.json']:
2121
print "copying",backup,"to old location"
2222
os.system('cp %s/%s /afs/cern.ch/user/c/cmst2/www/unified/.'%(monitor_pub_dir, backup))
2323
#os.system('cp %s/%s %s/.'%(monitor_dir, backup, monitor_pub_dir))
@@ -217,9 +217,9 @@ def lap( comment ):
217217
summary_content = {}
218218

219219
view_not_a_module = ['agentInfo','componentInfo']
220-
view_modules = ['injector','batchor','cachor','assignor','completor','GQ','equalizor','checkor','recoveror','actor','closor']+view_not_a_module
220+
view_modules = ['injector','batchor','assignor','completor','GQ','equalizor','checkor','recoveror','actor','closor']+view_not_a_module
221221

222-
all_modules = list(set(view_modules + ['actor','addHoc','assignor','batchor','cachor','checkor','closor','completor','efficiencor','equalizor','GQ','htmlor','injector','lockor','messagor','recoveror','remainor','showError','stuckor','subscribor']))
222+
all_modules = list(set(view_modules + ['actor','addHoc','assignor','batchor','checkor','closor','completor','efficiencor','equalizor','GQ','htmlor','injector','lockor','messagor','recoveror','remainor','showError','stuckor','subscribor']))
223223

224224
html_doc.write("""
225225
<html>

0 commit comments

Comments
 (0)