ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/osg_bdii.py
Revision: 1.12
Committed: Mon Apr 28 21:19:44 2008 UTC (17 years ago) by ewv
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_2_0_pre15
Changes since 1.11: +0 -1 lines
Log Message:
remove print statement

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     pout = runldapquery(''' '(GlueCESEBindGroupSEUniqueID=''' + se + ''')' ''', 'GlueCESEBindGroupCEUniqueID', bdii)
39    
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     pout = runldapquery(''' '(&(objectClass=GlueCEState)(GlueCEUniqueID=''' + jm + '''))' ''', 'GlueCEStateStatus', bdii)
61    
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     pout = runldapquery(''' '(&(objectClass=GlueCEState)(GlueCEInfoHostName=''' + ce + ''')(GlueCEAccessControlBaseRule=VO:cms))' ''', 'GlueCEStateStatus', bdii)
72    
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     query = ''' '(|'''
96     for se in selist:
97     query = query + '''(GlueCESEBindGroupSEUniqueID=''' + se + ''')'''
98     query = query + ''')' '''
99    
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.8 query = ''' '(&(GlueCEAccessControlBaseRule=VO:cms)(|'''
112     for l in jmlist:
113     query += '''(GlueCEInfoContactString=''' + l + '''-*)'''
114    
115     query += '''))' '''
116    
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     query = ''' '(|'''
135     for h in host_list:
136     query = query + '''(GlueSiteUniqueID=''' + h + ''')'''
137     query = query + ''')' GlueSiteDescription'''
138    
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     query = ''' '(|'''
234     for h in host_list:
235     query = query + '''(GlueChunkKey='GlueClusterUniqueID=''' + h + '''\')'''
236     query = query + ''')' '''
237    
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     return results_list
264    
265     def getJMInfo(selist, software, arch, bdii='exp-bdii.cern.ch', onlyOSG=True):
266     jminfo_list = []
267     host_list = []
268    
269     stat = re.compile('^GlueCEStateStatus: (.*)')
270     host = re.compile('^GlueCEInfoHostName: (.*)')
271     wait = re.compile('^GlueCEStateWaitingJobs: (.*)')
272     name = re.compile('^GlueCEUniqueID: (.*)')
273    
274     jmlist = getJMListFromSEList(selist)
275 ewv 1.8
276 ewv 1.7 query = ''' '(&(objectClass=GlueCEState)(|'''
277     for jm in jmlist:
278 ewv 1.8 query = query + '''(GlueCEUniqueID=''' + jm + ''')'''
279 ewv 1.7 query = query + '''))' '''
280    
281     pout = runldapquery(query, 'GlueCEUniqueID GlueCEStateStatus GlueCEInfoHostName GlueCEStateWaitingJobs GlueCEStateFreeJobSlots', bdii)
282     output = concatoutput(pout)
283    
284     stanza_list = output.split(LF+LF)
285     for stanza in stanza_list:
286     if len(stanza) > 1:
287     status = 1
288     wait_jobs = 0
289     jmname = ''
290     hostname = 0
291     jminfo = {}
292    
293     details = stanza.split(LF)
294     for det in details:
295     mhost = host.match(det)
296     if mhost: # hostname
297     host_list.append(mhost.groups()[0])
298     hostname = mhost.groups()[0]
299     mstat = stat.match(det)
300     if mstat: # e.g. Production
301     if not ((mstat.groups()[0] == 'Production') and (status == 1)):
302     status = 0
303     mwait = wait.match(det)
304     if mwait: # Waiting jobs
305     if (mwait.groups()[0] > wait_jobs):
306     wait_jobs = mwait.groups()[0]
307     mname = name.match(det)
308     if mname: # jm name
309     jmname = mname.groups()[0]
310    
311     jminfo["name"] = jmname
312     jminfo["status"] = status
313     jminfo["waiting_jobs"] = wait_jobs
314     jminfo["host"] = hostname
315    
316     jminfo_list.append(copy.deepcopy(jminfo))
317    
318 ewv 1.10 CElist = [x['name'] for x in jminfo_list]
319    
320 ewv 1.7 # Narrow the list of host to include only OSG sites if requested
321 ewv 1.8
322 ewv 1.7 if onlyOSG:
323     osg_list = isOSGSite(host_list)
324     else:
325     osg_list = host_list
326    
327     # Narrow the OSG host list to include only those with the specified software and architecture
328 ewv 1.10 # softarch_list = getSoftwareAndArch(osg_list, software, arch)
329     softarch_list = getSoftwareAndArch2(CElist, software, arch)
330 ewv 1.7
331     # remove any non-OSG sites from the list
332     jminfo_newlist = []
333 ewv 1.10
334 ewv 1.7 for item in jminfo_list:
335     for narrowed_item in softarch_list:
336 ewv 1.10 if (item['name'] == narrowed_item):
337 ewv 1.8 if (jminfo_newlist.count(item) == 0):
338     jminfo_newlist.append(item)
339 ewv 1.7
340     return jminfo_newlist
341    
342     # This function is used to sort lists of dictionaries
343     def compare_by (fieldname):
344     def compare_two_dicts (a, b):
345     return cmp(int(a[fieldname]), int(b[fieldname]))
346     return compare_two_dicts
347    
348     def getJobManagerList(selist, software, arch, bdii='exp-bdii.cern.ch', onlyOSG=True):
349     jms = getJMInfo(selist, software, arch, bdii, onlyOSG)
350     # Sort by waiting_jobs field and return the jobmanager with the least waiting jobs
351     jms.sort(compare_by('waiting_jobs'))
352     jmlist = []
353 ewv 1.8 r = re.compile('^(.*:.*/jobmanager-.*?)-(.*)')
354 ewv 1.7 for jm in jms:
355 ewv 1.8 fullname = jm['name']
356     m = r.match(fullname)
357     if m:
358     name = m.groups()[0]
359     if (jmlist.count(name) == 0): jmlist.append(name)
360 ewv 1.7
361     return jmlist
362    
363     if __name__ == '__main__':
364 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']
365     # seList = ['ccsrm.in2p3.fr', 'storm.ifca.es']
366     jmlist = getJobManagerList(seList, "CMSSW_1_6_11", "slc4_ia32_gcc345", 'uscmsbd2.fnal.gov', False)
367 ewv 1.7 for jm in jmlist:
368     print jm
369 ewv 1.10 # print jm_from_se_bdii(sys.argv[1])
370    
371 ewv 1.8