3 from config import config
4 from optparse import OptionParser
18 def array_to_priority_map(array):
19 """ Create a mapping where each entry of array is given a priority equal
20 to its position in the array. This is useful for subsequent use in the
29 def cmpValMap(v1, v2, map):
30 if v1 in map and v2 in map and map[v1] < map[v2]:
32 elif v1 in map and v2 in map and map[v1] > map[v2]:
34 elif v1 in map and v2 in map:
37 raise Exception("No index %s or %s in map" % (v1, v2))
39 def cmpMap(l1, l2, index, map):
40 if index in l1 and index in l2:
41 if map[l1[index]] < map[l2[index]]:
43 elif map[l1[index]] > map[l2[index]]:
50 def cmpLoginBase(l1, l2):
51 #print "'" + l1['loginbase'] + "'" + " < " + "'" + l2['loginbase'] + "'" + "<BR>"
52 if l1['loginbase'] == l2['loginbase']:
54 elif l1['loginbase'] < l2['loginbase']:
56 elif l1['loginbase'] > l2['loginbase']:
62 map = array_to_priority_map([ 'BOOT', 'DEBUG', 'DOWN' ])
63 return cmpMap(l1,l2,'state', map)
65 def cmpCategoryVal(v1, v2):
66 map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
67 return cmpValMap(v1,v2,map)
69 def cmpCategory(l1, l2):
70 map = array_to_priority_map([ 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
71 return cmpMap(l1,l2,'category', map)
74 """ Either PCU or NOPCU"""
75 map = array_to_priority_map([ 'PCU', 'NOPCU', 'UNKNOWN'])
76 return cmpMap(l1, l2, 'pcu', map)
79 """ Either SSH or NOSSH """
80 map = array_to_priority_map([ 'SSH', 'NOSSH'])
81 return cmpMap(l1, l2, 'ssh', map)
84 """ Compare DNS states """
85 map = array_to_priority_map([ 'OK', 'NOHOSTNAME', 'NOENTRY', 'MISMATCH'])
86 return cmpMap(l1, l2, 'dnsmatch', map)
89 """ Either PING or NOPING """
90 map = array_to_priority_map([ 'PING', 'NOPING'])
91 return cmpMap(l1, l2, 'ping', map)
94 # Extract the kernel version from kernel -a string
95 l_k1 = l1['kernel'].split()
101 l_k2 = l2['kernel'].split()
110 if l1['comonstats'][config.comon] == "null":
111 l1['comonstats'][config.comon] = -1
112 if l2['comonstats'][config.comon] == "null":
113 l2['comonstats'][config.comon] = -1
115 if int(l1['comonstats'][config.comon]) > int(l2['comonstats'][config.comon]):
117 elif int(l1['comonstats'][config.comon]) < int(l2['comonstats'][config.comon]):
122 def ssh_error_to_str(str):
124 if "Connection timed out" in str:
125 ssh_error = "Timeout"
126 elif "Connection closed by remote host" in str:
127 ssh_error = "Closed by remote host"
128 elif "Connection refused" in str:
129 ssh_error = "Connection refused"
130 elif "Temporary failure in name resolution" in str:
131 ssh_error = "Could not resolve name"
132 elif "Name or service not known" in str:
133 ssh_error = "Name not known"
134 elif "Too many authentication failures" in str:
135 ssh_error = "Disconnect: root auth failure"
136 elif "Network is unreachable" in str:
137 ssh_error = "Network is unreachable"
138 elif "Connection reset by peer" in str:
139 ssh_error = "Connection reset by peer"
140 elif "WARNING" in str:
141 ssh_error = "WARNING ssh key updated"
147 def fields_to_html(fields, vals):
150 colorMap = { 'PING' : 'darkseagreen',
151 'NOPING': 'darksalmon',
152 'SSH': 'darkseagreen',
153 'NOSSH': 'indianred',
154 'PCU': 'darkseagreen',
155 'NOPCU': 'lightgrey',
156 'OLDBOOTCD': 'crimson',
160 'PROD': 'darkseagreen',
161 'DEBUG': 'darksalmon',
162 'DEBUG': 'darksalmon',
163 'BOOT': 'lightgreen'}
167 #print 'inside--------------'
172 if f in ['DOWN', 'BOOT', 'DEBUG']:
173 #key = "%s-%s-%s" % (f,f_prev,f_2prev)
174 key = "%s-%s" % (f,f_prev)
175 if key not in categories:
180 #print "<pre>%s</pre><br>" % f
183 bgcolor="bgcolor='%s'" % colorMap[f]
189 if 'ssherror' in vals:
190 str_ssh_error = ssh_error_to_str(vals['ssherror'])
192 str_ssh_error = "NO SSHERROR in VALS"
193 if str_ssh_error != "Timeout":
194 r_str += """<td nowrap %s>%s<br><b><font size="-2">%s</font></b></td>""" % \
195 (bgcolor,f,str_ssh_error)
197 r_str += "<td %s>%s</td>" % (bgcolor, f)
199 r_str += "<td %s>%s</td>" % (bgcolor, f)
201 if len(vals['plcnode']['pcu_ids']) > 0:
202 url = "<a href='/cgi-bin/printbadpcus.php#id%s'>PCU</a>" % vals['plcnode']['pcu_ids'][0]
203 r_str += "<td nowrap %s>%s</td>" % (bgcolor, url)
205 r_str += "<td nowrap %s>%s</td>" % (bgcolor, f)
213 def main(sitefilter):
214 db = soltesz.dbLoad(config.dbname)
216 ## Field widths used for printing
217 maxFieldLengths = { 'nodename' : -45,
227 ## create format string based on config.fields
231 for f in config.fields.split(','):
232 fields[f] = "%%(%s)s" % f
233 #if f in maxFieldLengths:
234 # fields[f] = "%%(%s)%ds" % (f, maxFieldLengths[f])
236 # fields[f] = "%%(%s)%ds" % (f, 10)
238 format_fields.append(fields[f])
240 for f in config.fields.split(','):
241 format += fields[f] + " "
249 #for nodename in l_nodes:
250 # if 'plcsite' in d_n[nodename]['values'] and \
251 # 'login_base' in d_n[nodename]['values']['plcsite']:
252 # loginbase = d_n[nodename]['values']['plcsite']['login_base']
253 # if loginbase not in bysite:
254 # bysite[loginbase] = []
255 # d_n[nodename]['values']['nodename'] = nodename
256 # bysite[loginbase].append(d_n[nodename]['values'])
258 # d2 was an array of [{node}, {}, ...]
259 # the bysite is a loginbase dict of [{node}, {node}]
262 if sitefilter != None:
263 sf = re.compile(sitefilter)
266 for nodename in l_nodes:
267 vals=d_n[nodename]['values']
270 v['nodename'] = nodename
271 if 'plcsite' in vals and \
272 'status' in vals['plcsite'] and \
273 vals['plcsite']['status'] == "SUCCESS":
275 url = "<a href='printbadnodes.py?site=%s'>%s</a>" % ( vals['plcsite']['login_base'],
276 vals['plcsite']['login_base'])
278 site_string = "%s %2s nodes :: %2s of %4s slices" % ( \
280 vals['plcsite']['num_nodes'],
281 vals['plcsite']['num_slices'],
282 vals['plcsite']['max_slices'])
283 loginbase = d_n[nodename]['values']['plcsite']['login_base']
285 #print "ERROR: ", nodename, vals, "<br>"
286 site_string = "<b>UNKNOWN</b>"
289 v['site_string'] = site_string
290 v['loginbase'] = loginbase
291 if (sitefilter != None and sf.match(loginbase) != None) or sitefilter == None:
295 if sitefilter != None:
296 config.cmpcategory = True
298 config.cmploginbase = True
301 if config.cmploginbase:
302 d2.sort(cmp=cmpLoginBase)
309 elif config.cmpcategory:
310 d2.sort(cmp=cmpCategory)
311 elif config.cmpstate:
312 d2.sort(cmp=cmpState)
315 elif config.cmpkernel:
316 d2.sort(cmp=cmpUname)
318 d2.sort(cmp=cmpCategory)
321 #l_loginbase = bysite.keys()
323 print "<table width=80% border=1>"
327 site_string = row['site_string']
328 if site_string != prev_sitestring:
329 print "<tr><td bgcolor=lightblue nowrap>"
333 print "<tr><td> </td>"
335 prev_sitestring = site_string
338 # convert uname values into a single kernel version string
340 kernel = vals['kernel'].split()
342 if kernel[0] == "Linux":
343 vals['kernel'] = kernel[2]
345 vals['ssherror'] = vals['kernel']
348 vals['ssherror'] = ""
351 if 'model' in vals or 'protocol' in vals or 'portstatus' in vals:
352 #vals['model'] = string.replace(vals['model']," ", " ")
353 #vals['protocol'] = vals['protocol'].replace(" ", " ")
354 if vals['model'] == None:
356 vals['model'] = string.replace(vals['model']," ", "_")
357 vals['protocol'] = vals['protocol'].replace(" ", "_")
359 ports = vals['portstatus']
360 lports = ports.keys()
365 ps += "%s: %s<br>" % (port, ports[port])
369 vals['portstatus'] = ps
372 vals['reboot'] = "%s" % vals['reboot']
373 vals['reboot'] = vals['reboot'].replace(" ", "_")
378 for f in format_fields:
379 str_fields.append(f % vals)
382 print >>sys.stderr, vals
384 s = fields_to_html(str_fields, vals)
391 keys = categories.keys()
395 print "<th nowrap align=left>Total %s</th>" % cat
396 print "<td align=left>%s</td>" % categories[cat]
402 if __name__ == '__main__':
408 form = cgi.FieldStorage()
411 if form.has_key('site'):
412 myfilter = form.getvalue("site")
415 parser = OptionParser()
416 parser.set_defaults(cmpdays=False,
418 fields="nodename,ping,ssh,pcu,category,state,kernel,bootcd",
419 dbname="findbad", # -070724-1",
426 parser.add_option("", "--fields", dest="fields", help="")
427 parser.add_option("", "--dbname", dest="dbname", help="")
428 parser.add_option("", "--days", dest="cmpdays", action="store_true", help="")
429 parser.add_option("", "--ping", dest="cmpping", action="store_true", help="")
430 parser.add_option("", "--dns", dest="cmpdns", action="store_true", help="")
431 parser.add_option("", "--ssh", dest="cmpssh", action="store_true", help="")
432 parser.add_option("", "--loginbase",dest="cmploginbase",action="store_true", help="")
433 parser.add_option("", "--category", dest="cmpcategory", action="store_true", help="")
434 parser.add_option("", "--kernel", dest="cmpkernel", action="store_true", help="")
435 parser.add_option("", "--state", dest="cmpstate", action="store_true", help="")
436 parser.add_option("", "--comon", dest="comon", help="")
437 config = config(parser)
439 print "Content-Type: text/html\r\n"
440 print "<html><body>\n"
441 if len(sys.argv) > 1:
442 if sys.argv[1] == "ssherror":
445 print "</body></html>\n"