ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/osg_bdii.py
Revision: 1.13
Committed: Fri May 2 19:55:39 2008 UTC (17 years ago) by ewv
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_2_0_pre16
Changes since 1.12: +24 -27 lines
Log Message:
Patch from Burt, restore onlyOSG function

File Contents

# User Rev Content
1 ewv 1.7 #!/usr/bin/env python
2     import re, popen2, sys, copy
3    
4     CR = '\r'
5     LF = '\n'
6     CRLF = CR+LF
7    
8     def unwraplines(wrapped_list):
9     r = re.compile('^ (.*)$')
10     unwrapped_list = []
11     for l in wrapped_list:
12     m = r.match(l)
13     if m:
14     unwrapped_list[-1] += m.groups()[0]
15     else:
16     unwrapped_list.append(l.rstrip())
17    
18     return unwrapped_list
19    
20    
21     def runldapquery(filter, attribute, bdii):
22     command = 'ldapsearch -xLLL -p 2170 -h ' + bdii + ' -b o=grid '
23     command += filter + ' ' + attribute
24     pout,pin,perr = popen2.popen3(command)
25    
26     pout = pout.readlines()
27     p = perr.readlines()
28    
29     pout = unwraplines(pout)
30     if (p):
31     for l in p: print l
32     raise RuntimeError('ldapsearch call failed')
33    
34     return pout
35    
36     def jm_from_se_bdii(se, bdii='exp-bdii.cern.ch'):
37     se = '\'' + se + '\''
38 ewv 1.13 pout = runldapquery(" '(GlueCESEBindGroupSEUniqueID=" + se + ")' ", 'GlueCESEBindGroupCEUniqueID', bdii)
39 ewv 1.7
40 ewv 1.8 # r = re.compile('^GlueCESEBindGroupCEUniqueID: (.*:.*/jobmanager-.*)-cms')
41     r = re.compile('^GlueCESEBindGroupCEUniqueID: (.*:.*/jobmanager-.*?)-(.*)')
42 ewv 1.7 jm = []
43     for l in pout:
44     m = r.match(l)
45     if m:
46     item = m.groups()[0]
47     if (jm.count(item) == 0):
48 ewv 1.8 jm.append(item)
49 ewv 1.7
50     return jm
51    
52    
53     def cestate_from_se_bdii(se, bdii='exp-bdii.cern.ch' ):
54     status = []
55     jmlist = jm_from_se_bdii(se)
56    
57     for jm in jmlist:
58     jm += "-cms"
59    
60 ewv 1.13 pout = runldapquery(" '(&(objectClass=GlueCEState)(GlueCEUniqueID=" + jm + "))' ", 'GlueCEStateStatus', bdii)
61 ewv 1.7
62     r = re.compile('^GlueCEStateStatus: (.*)')
63     for l in pout:
64     m = r.match(l)
65     if m:
66     status.append(m.groups()[0])
67    
68     return status
69    
70     def cestate_from_ce_bdii(ce, bdii='exp-bdii.cern.ch'):
71 ewv 1.13 pout = runldapquery(" '(&(objectClass=GlueCEState)(GlueCEInfoHostName=" + ce + ")(GlueCEAccessControlBaseRule=VO:cms))' ", 'GlueCEStateStatus', bdii)
72 ewv 1.7
73     status = ''
74     r = re.compile('^GlueCEStateStatus: (.*)')
75     for l in pout:
76     m = r.match(l)
77     if m:
78     status = m.groups()[0]
79    
80     return status
81    
82     def concatoutput(pout):
83     output = ''
84     for l in pout:
85     if l == '':
86     output = output + LF
87     output = output + l + LF
88    
89     return output
90    
91     def getJMListFromSEList(selist, bdii='exp-bdii.cern.ch'):
92     # Get the Jobmanager list
93     jmlist = []
94    
95 ewv 1.13 query = " '(|"
96 ewv 1.7 for se in selist:
97 ewv 1.13 query = query + "(GlueCESEBindGroupSEUniqueID=" + se + ")"
98     query = query + ")' "
99 ewv 1.7
100     pout = runldapquery(query, 'GlueCESEBindGroupCEUniqueID', bdii)
101 ewv 1.8 r = re.compile('^GlueCESEBindGroupCEUniqueID: (.*:.*/jobmanager-.*?)-(.*)')
102    
103 ewv 1.7 for l in pout:
104     m = r.match(l)
105     if m:
106     item = m.groups()[0]
107     if (jmlist.count(item) == 0):
108 ewv 1.8 jmlist.append(item)
109    
110 ewv 1.10
111 ewv 1.13 query = " '(&(GlueCEAccessControlBaseRule=VO:cms)(|"
112 ewv 1.8 for l in jmlist:
113 ewv 1.13 query += "(GlueCEInfoContactString=" + l + "-*)"
114 ewv 1.8
115 ewv 1.13 query += "))' "
116 ewv 1.8
117     pout = runldapquery(query, 'GlueCEInfoContactString', bdii)
118    
119     r = re.compile('^GlueCEInfoContactString: (.*:.*/jobmanager-.*)')
120     for l in pout:
121     m = r.match(l)
122     if m:
123     item = m.groups()[0]
124     if (jmlist.count(item) == 0):
125     jmlist.append(item)
126 ewv 1.7
127     return jmlist
128    
129     def isOSGSite(host_list, bdii='exp-bdii.cern.ch'):
130     results_list = []
131     r = re.compile('^GlueSiteDescription: (OSG.*)')
132     s = re.compile('^GlueSiteUniqueID: (.*)')
133    
134 ewv 1.13 query = " '(|"
135 ewv 1.7 for h in host_list:
136 ewv 1.13 query = query + "(GlueSiteUniqueID=" + h + ")"
137     query = query + ")' GlueSiteDescription"
138 ewv 1.7
139     pout = runldapquery(query, 'GlueSubClusterUniqueID GlueSiteUniqueID', bdii)
140     output = concatoutput(pout)
141    
142     stanzas = output.split(LF + LF)
143     for stanza in stanzas:
144     osg = 0
145     host = ""
146     details = stanza.split(LF)
147     for detail in details:
148     m = r.match(detail)
149     n = s.match(detail)
150     if m:
151     osg = 1
152     if n:
153     host = n.groups()[0]
154     if (osg == 1):
155     results_list.append(host)
156    
157     return results_list
158    
159 ewv 1.10 def getSoftwareAndArch2(host_list, software, arch, bdii='exp-bdii.cern.ch'):
160     results_list = []
161    
162     # Find installed CMSSW versions and Architecture
163     software = 'VO-cms-' + software
164     arch = 'VO-cms-' + arch
165    
166     query = "'(|"
167    
168     for h in host_list:
169     query += "(GlueCEInfoContactString=" + h + ")"
170     query += ")'"
171    
172     pout = runldapquery(query, 'GlueForeignKey GlueCEInfoContactString', bdii)
173     r = re.compile('GlueForeignKey: GlueClusterUniqueID=(.*)')
174     s = re.compile('GlueCEInfoContactString: (.*)')
175    
176     ClusterMap = {}
177     ClusterUniqueID = None
178     CEInfoContact = None
179    
180     for l in pout:
181     m = r.match(l)
182     if m:
183     ClusterUniqueID = m.groups()[0]
184     m = s.match(l)
185     if m:
186     CEInfoContact = m.groups()[0]
187    
188     if (ClusterUniqueID and CEInfoContact):
189     ClusterMap[ClusterUniqueID] = CEInfoContact
190     ClusterUniqueID = None
191     CEInfoContact = None
192    
193     query = "'(|"
194     for c in ClusterMap.keys():
195     query += "(GlueChunkKey=GlueClusterUniqueID="+c+")"
196     query += ")'"
197    
198     pout = runldapquery(query, 'GlueHostApplicationSoftwareRunTimeEnvironment GlueChunkKey', bdii)
199     output = concatoutput(pout)
200    
201     r = re.compile('^GlueHostApplicationSoftwareRunTimeEnvironment: (.*)')
202     s = re.compile('^GlueChunkKey: GlueClusterUniqueID=(.*)')
203     stanzas = output.split(LF + LF)
204     for stanza in stanzas:
205     software_installed = 0
206     architecture = 0
207     host = ''
208     details = stanza.split(LF)
209     for detail in details:
210     m = r.match(detail)
211     if m:
212     if (m.groups()[0] == software):
213     software_installed = 1
214     elif (m.groups()[0] == arch):
215     architecture = 1
216     m2 = s.match(detail)
217     if m2:
218     ClusterUniqueID = m2.groups()[0]
219     host = ClusterMap[ClusterUniqueID]
220    
221     if ((software_installed == 1) and (architecture == 1)):
222     results_list.append(host)
223    
224     return results_list
225 ewv 1.7
226     def getSoftwareAndArch(host_list, software, arch, bdii='exp-bdii.cern.ch'):
227     results_list = []
228    
229     # Find installed CMSSW versions and Architecture
230     software = 'VO-cms-' + software
231     arch = 'VO-cms-' + arch
232    
233 ewv 1.13 query = " '(|"
234 ewv 1.7 for h in host_list:
235 ewv 1.13 query = query + "(GlueChunkKey='GlueClusterUniqueID=" + h + "\')"
236     query = query + ")' "
237 ewv 1.7
238     pout = runldapquery(query, 'GlueHostApplicationSoftwareRunTimeEnvironment GlueSubClusterUniqueID GlueChunkKey', bdii)
239     output = concatoutput(pout)
240    
241     r = re.compile('^GlueHostApplicationSoftwareRunTimeEnvironment: (.*)')
242     s = re.compile('^GlueChunkKey: GlueClusterUniqueID=(.*)')
243     stanzas = output.split(LF + LF)
244     for stanza in stanzas:
245     software_installed = 0
246     architecture = 0
247     host = ''
248     details = stanza.split(LF)
249     for detail in details:
250     m = r.match(detail)
251     if m:
252     if (m.groups()[0] == software):
253     software_installed = 1
254     elif (m.groups()[0] == arch):
255     architecture = 1
256     m2 = s.match(detail)
257     if m2:
258     host = m2.groups()[0]
259    
260     if ((software_installed == 1) and (architecture == 1)):
261     results_list.append(host)
262    
263 ewv 1.13 print '2', results_list
264 ewv 1.7 return results_list
265    
266     def getJMInfo(selist, software, arch, bdii='exp-bdii.cern.ch', onlyOSG=True):
267     jminfo_list = []
268     host_list = []
269    
270     stat = re.compile('^GlueCEStateStatus: (.*)')
271     host = re.compile('^GlueCEInfoHostName: (.*)')
272     wait = re.compile('^GlueCEStateWaitingJobs: (.*)')
273     name = re.compile('^GlueCEUniqueID: (.*)')
274    
275     jmlist = getJMListFromSEList(selist)
276 ewv 1.8
277 ewv 1.13 query = " '(&(objectClass=GlueCEState)(|"
278 ewv 1.7 for jm in jmlist:
279 ewv 1.13 query = query + "(GlueCEUniqueID=" + jm + ")"
280     query = query + "))' "
281 ewv 1.7
282     pout = runldapquery(query, 'GlueCEUniqueID GlueCEStateStatus GlueCEInfoHostName GlueCEStateWaitingJobs GlueCEStateFreeJobSlots', bdii)
283     output = concatoutput(pout)
284    
285     stanza_list = output.split(LF+LF)
286     for stanza in stanza_list:
287     if len(stanza) > 1:
288     status = 1
289     wait_jobs = 0
290     jmname = ''
291     hostname = 0
292     jminfo = {}
293    
294     details = stanza.split(LF)
295     for det in details:
296     mhost = host.match(det)
297     if mhost: # hostname
298     host_list.append(mhost.groups()[0])
299     hostname = mhost.groups()[0]
300     mstat = stat.match(det)
301     if mstat: # e.g. Production
302     if not ((mstat.groups()[0] == 'Production') and (status == 1)):
303     status = 0
304     mwait = wait.match(det)
305     if mwait: # Waiting jobs
306     if (mwait.groups()[0] > wait_jobs):
307     wait_jobs = mwait.groups()[0]
308     mname = name.match(det)
309     if mname: # jm name
310     jmname = mname.groups()[0]
311    
312     jminfo["name"] = jmname
313     jminfo["status"] = status
314     jminfo["waiting_jobs"] = wait_jobs
315     jminfo["host"] = hostname
316    
317     jminfo_list.append(copy.deepcopy(jminfo))
318    
319     # Narrow the list of host to include only OSG sites if requested
320 ewv 1.13 osg_list = isOSGSite([x['host'] for x in jminfo_list])
321     if not onlyOSG:
322     CElist = [x['name'] for x in jminfo_list]
323 ewv 1.7 else:
324 ewv 1.13 CElist = [x['name'] for x in jminfo_list if osg_list.count(x['host'])]
325 ewv 1.7
326     # Narrow the OSG host list to include only those with the specified software and architecture
327 ewv 1.10 # softarch_list = getSoftwareAndArch(osg_list, software, arch)
328     softarch_list = getSoftwareAndArch2(CElist, software, arch)
329 ewv 1.7
330     # remove any non-OSG sites from the list
331     jminfo_newlist = []
332 ewv 1.10
333 ewv 1.7 for item in jminfo_list:
334     for narrowed_item in softarch_list:
335 ewv 1.10 if (item['name'] == narrowed_item):
336 ewv 1.8 if (jminfo_newlist.count(item) == 0):
337     jminfo_newlist.append(item)
338 ewv 1.7
339     return jminfo_newlist
340    
341     # This function is used to sort lists of dictionaries
342     def compare_by (fieldname):
343     def compare_two_dicts (a, b):
344     return cmp(int(a[fieldname]), int(b[fieldname]))
345     return compare_two_dicts
346    
347     def getJobManagerList(selist, software, arch, bdii='exp-bdii.cern.ch', onlyOSG=True):
348     jms = getJMInfo(selist, software, arch, bdii, onlyOSG)
349     # Sort by waiting_jobs field and return the jobmanager with the least waiting jobs
350     jms.sort(compare_by('waiting_jobs'))
351     jmlist = []
352 ewv 1.8 r = re.compile('^(.*:.*/jobmanager-.*?)-(.*)')
353 ewv 1.7 for jm in jms:
354 ewv 1.8 fullname = jm['name']
355     m = r.match(fullname)
356     if m:
357     name = m.groups()[0]
358     if (jmlist.count(name) == 0): jmlist.append(name)
359 ewv 1.7
360     return jmlist
361    
362     if __name__ == '__main__':
363 ewv 1.10 seList = ['ccsrm.in2p3.fr', 'cmssrm.hep.wisc.edu', 'pccms2.cmsfarm1.ba.infn.it', 'polgrid4.in2p3.fr', 'srm-disk.pic.es', 'srm.ciemat.es', 'srm.ihepa.ufl.edu', 't2data2.t2.ucsd.edu']
364     # seList = ['ccsrm.in2p3.fr', 'storm.ifca.es']
365 ewv 1.13 jmlist = getJobManagerList(seList, "CMSSW_1_6_11", "slc4_ia32_gcc345", 'uscmsbd2.fnal.gov', True)
366 ewv 1.7 for jm in jmlist:
367     print jm
368 ewv 1.10 # print jm_from_se_bdii(sys.argv[1])