--- /dev/null
+#!/usr/bin/python
+import soltesz
+from config import config
+from optparse import OptionParser
+import string
+
+import sys
+
+categories = {}
+ssherror = False
+
+def sec2days(sec):
+ if sec == "null":
+ sec = -(60*60*24)
+ sec = int(sec)
+ return sec/(60*60*24)
+
+def array_to_priority_map(array):
+ """ Create a mapping where each entry of array is given a priority equal
+ to its position in the array. This is useful for subsequent use in the
+ cmpMap() function."""
+ map = {}
+ count = 0
+ for i in array:
+ map[i] = count
+ count += 1
+ return map
+
+def cmpValMap(v1, v2, map):
+ if v1 in map and v2 in map and map[v1] < map[v2]:
+ return 1
+ elif v1 in map and v2 in map and map[v1] > map[v2]:
+ return -1
+ elif v1 in map and v2 in map:
+ return 0
+ else:
+ raise Exception("No index %s or %s in map" % (v1, v2))
+
+def cmpMap(l1, l2, index, map):
+ if index in l1 and index in l2:
+ if map[l1[index]] < map[l2[index]]:
+ return -1
+ elif map[l1[index]] > map[l2[index]]:
+ return 1
+ else:
+ return 0
+ else:
+ return 0
+
+def cmpLoginBase(l1, l2):
+ #print "'" + l1['loginbase'] + "'" + " < " + "'" + l2['loginbase'] + "'" + "<BR>"
+ if l1['loginbase'] == l2['loginbase']:
+ return 0
+ elif l1['loginbase'] < l2['loginbase']:
+ return -1
+ elif l1['loginbase'] > l2['loginbase']:
+ return 1
+ else:
+ return 0
+
+def cmpState(l1, l2):
+ map = array_to_priority_map([ 'BOOT', 'DEBUG', 'DOWN' ])
+ return cmpMap(l1,l2,'state', map)
+
+def cmpCategoryVal(v1, v2):
+ map = array_to_priority_map([ None, 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
+ return cmpValMap(v1,v2,map)
+
+def cmpCategory(l1, l2):
+ map = array_to_priority_map([ 'ALPHA', 'PROD', 'OLDBOOTCD', 'UNKNOWN', 'ERROR', ])
+ return cmpMap(l1,l2,'category', map)
+
+def cmpPCU(l1, l2):
+ """ Either PCU or NOPCU"""
+ map = array_to_priority_map([ 'PCU', 'NOPCU', 'UNKNOWN'])
+ return cmpMap(l1, l2, 'pcu', map)
+
+def cmpSSH(l1, l2):
+ """ Either SSH or NOSSH """
+ map = array_to_priority_map([ 'SSH', 'NOSSH'])
+ return cmpMap(l1, l2, 'ssh', map)
+
+def cmpDNS(l1,l2):
+ """ Compare DNS states """
+ map = array_to_priority_map([ 'OK', 'NOHOSTNAME', 'NOENTRY', 'MISMATCH'])
+ return cmpMap(l1, l2, 'dnsmatch', map)
+
+def cmpPing(l1,l2):
+ """ Either PING or NOPING """
+ map = array_to_priority_map([ 'PING', 'NOPING'])
+ return cmpMap(l1, l2, 'ping', map)
+
+def cmpUname(l1, l2):
+ # Extract the kernel version from kernel -a string
+ l_k1 = l1['kernel'].split()
+ if len(l_k1) > 2:
+ k1 = l_k1[2]
+ else:
+ return 1
+
+ l_k2 = l2['kernel'].split()
+ if len(l_k2) > 2:
+ k2 = l_k2[2]
+ else:
+ return -1
+
+ return cmp(k1, k2)
+
+def cmpDays(l1, l2):
+ if l1['comonstats'][config.comon] == "null":
+ l1['comonstats'][config.comon] = -1
+ if l2['comonstats'][config.comon] == "null":
+ l2['comonstats'][config.comon] = -1
+
+ if int(l1['comonstats'][config.comon]) > int(l2['comonstats'][config.comon]):
+ return -1
+ elif int(l1['comonstats'][config.comon]) < int(l2['comonstats'][config.comon]):
+ return 1
+ else:
+ return 0
+
+def ssh_error_to_str(str):
+ ssh_error = ""
+ if "Connection timed out" in str:
+ ssh_error = "Timeout"
+ elif "Connection closed by remote host" in str:
+ ssh_error = "Closed by remote host"
+ elif "Connection refused" in str:
+ ssh_error = "Connection refused"
+ elif "Temporary failure in name resolution" in str:
+ ssh_error = "Could not resolve name"
+ elif "Name or service not known" in str:
+ ssh_error = "Name not known"
+ elif "Too many authentication failures" in str:
+ ssh_error = "Disconnect: root auth failure"
+ elif "Network is unreachable" in str:
+ ssh_error = "Network is unreachable"
+ elif "Connection reset by peer" in str:
+ ssh_error = "Connection reset by peer"
+ elif "WARNING" in str:
+ ssh_error = "WARNING ssh key updated"
+ else:
+ ssh_error = str
+
+ return ssh_error
+
+def fields_to_html(fields, vals):
+ global categories
+ global ssherror
+ colorMap = { 'PING' : 'darkseagreen',
+ 'NOPING': 'darksalmon',
+ 'SSH': 'darkseagreen',
+ 'NOSSH': 'indianred',
+ 'PCU': 'darkseagreen',
+ 'NOPCU': 'lightgrey',
+ 'OLDBOOTCD': 'crimson',
+ 'DOWN': 'indianred',
+ 'ALPHA': 'gold',
+ 'ERROR': 'crimson',
+ 'PROD': 'darkseagreen',
+ 'DEBUG': 'darksalmon',
+ 'DEBUG': 'darksalmon',
+ 'BOOT': 'lightgreen'}
+ r_str = ""
+ f_prev = ""
+ f_2prev = ""
+ #print 'inside--------------'
+ for f in fields:
+ f = f.strip()
+ #print f
+
+ if f in ['DOWN', 'BOOT', 'DEBUG']:
+ #key = "%s-%s-%s" % (f,f_prev,f_2prev)
+ key = "%s-%s" % (f,f_prev)
+ if key not in categories:
+ categories[key] = 1
+ else:
+ categories[key] += 1
+
+ #print "<pre>%s</pre><br>" % f
+
+ if f in colorMap:
+ bgcolor="bgcolor='%s'" % colorMap[f]
+ else:
+ bgcolor=""
+
+ if f == 'NOSSH':
+ if ssherror:
+ if 'ssherror' in vals:
+ str_ssh_error = ssh_error_to_str(vals['ssherror'])
+ else:
+ str_ssh_error = "NO SSHERROR in VALS"
+ if str_ssh_error != "Timeout":
+ r_str += """<td nowrap %s>%s<br><b><font size="-2">%s</font></b></td>""" % \
+ (bgcolor,f,str_ssh_error)
+ else:
+ r_str += "<td %s>%s</td>" % (bgcolor, f)
+ else:
+ r_str += "<td %s>%s</td>" % (bgcolor, f)
+ elif f == 'PCU':
+ if len(vals['plcnode']['pcu_ids']) > 0:
+ url = "<a href='http://dendrite.cs.princeton.edu/~soltesz/printbadpcus.php#id%s'>PCU</a>" % vals['plcnode']['pcu_ids'][0]
+ r_str += "<td nowrap %s>%s</td>" % (bgcolor, url)
+ else:
+ r_str += "<td nowrap %s>%s</td>" % (bgcolor, f)
+ f_2prev = f_prev
+ f_prev = f
+
+ return r_str
+
+
+
+def main(sitefilter):
+ db = soltesz.dbLoad(config.dbname)
+
+ ## Field widths used for printing
+ maxFieldLengths = { 'nodename' : -45,
+ 'ping' : 6,
+ 'ssh' : 6,
+ 'pcu' : 7,
+ 'category' : 9,
+ 'state' : 5,
+ 'kernel' : 10.65,
+ 'comonstats' : 5,
+ 'plcsite' : 12,
+ 'bootcd' : 10.65}
+ ## create format string based on config.fields
+ fields = {}
+ format = ""
+ format_fields = []
+ for f in config.fields.split(','):
+ fields[f] = "%%(%s)s" % f
+ #if f in maxFieldLengths:
+ # fields[f] = "%%(%s)%ds" % (f, maxFieldLengths[f])
+ #else:
+ # fields[f] = "%%(%s)%ds" % (f, 10)
+
+ format_fields.append(fields[f])
+ #print fields
+ for f in config.fields.split(','):
+ format += fields[f] + " "
+ #print format
+
+ d_n = db['nodes']
+ l_nodes = d_n.keys()
+
+ # category by site
+ #bysite = {}
+ #for nodename in l_nodes:
+ # if 'plcsite' in d_n[nodename]['values'] and \
+ # 'login_base' in d_n[nodename]['values']['plcsite']:
+ # loginbase = d_n[nodename]['values']['plcsite']['login_base']
+ # if loginbase not in bysite:
+ # bysite[loginbase] = []
+ # d_n[nodename]['values']['nodename'] = nodename
+ # bysite[loginbase].append(d_n[nodename]['values'])
+
+ # d2 was an array of [{node}, {}, ...]
+ # the bysite is a loginbase dict of [{node}, {node}]
+ d2 = []
+ for nodename in l_nodes:
+ vals=d_n[nodename]['values']
+ v = {}
+ v.update(vals)
+ v['nodename'] = nodename
+ if 'plcsite' in vals and \
+ 'status' in vals['plcsite'] and \
+ vals['plcsite']['status'] == "SUCCESS":
+
+ url = "<a href='printbad.cgi?site=%s'>%s</a>" % ( vals['plcsite']['login_base'],
+ vals['plcsite']['login_base'])
+
+ site_string = "%s %2s nodes :: %2s of %4s slices" % ( \
+ url,
+ vals['plcsite']['num_nodes'],
+ vals['plcsite']['num_slices'],
+ vals['plcsite']['max_slices'])
+ loginbase = d_n[nodename]['values']['plcsite']['login_base']
+ else:
+ #print "ERROR: ", nodename, vals, "<br>"
+ site_string = "<b>UNKNOWN</b>"
+ loginbase = ""
+
+ v['site_string'] = site_string
+ v['loginbase'] = loginbase
+ if (sitefilter != None and loginbase == sitefilter) or sitefilter == None:
+ d2.append(v)
+
+
+ if sitefilter != None:
+ config.cmpcategory = True
+ else:
+ config.cmploginbase = True
+
+
+ if config.cmploginbase:
+ d2.sort(cmp=cmpLoginBase)
+ elif config.cmpping:
+ d2.sort(cmp=cmpPing)
+ elif config.cmpdns:
+ d2.sort(cmp=cmpDNS)
+ elif config.cmpssh:
+ d2.sort(cmp=cmpSSH)
+ elif config.cmpcategory:
+ d2.sort(cmp=cmpCategory)
+ elif config.cmpstate:
+ d2.sort(cmp=cmpState)
+ elif config.cmpdays:
+ d2.sort(cmp=cmpDays)
+ elif config.cmpkernel:
+ d2.sort(cmp=cmpUname)
+ else:
+ d2.sort(cmp=cmpCategory)
+
+
+ #l_loginbase = bysite.keys()
+ #l_loginbase.sort()
+ print "<table width=80% border=1>"
+ prev_sitestring = ""
+ for row in d2:
+
+ site_string = row['site_string']
+ if site_string != prev_sitestring:
+ print "<tr><td bgcolor=lightblue nowrap>"
+ print site_string
+ print "</td>"
+ else:
+ print "<tr><td> </td>"
+
+ prev_sitestring = site_string
+
+ vals = row
+ # convert uname values into a single kernel version string
+ if 'kernel' in vals:
+ kernel = vals['kernel'].split()
+ if len(kernel) > 0:
+ if kernel[0] == "Linux":
+ vals['kernel'] = kernel[2]
+ else:
+ vals['ssherror'] = vals['kernel']
+ vals['kernel'] = ""
+ else:
+ vals['ssherror'] = ""
+ vals['kernel'] = ""
+# continue
+ if 'model' in vals or 'protocol' in vals or 'portstatus' in vals:
+ #vals['model'] = string.replace(vals['model']," ", " ")
+ #vals['protocol'] = vals['protocol'].replace(" ", " ")
+ if vals['model'] == None:
+ vals['model'] = " "
+ vals['model'] = string.replace(vals['model']," ", "_")
+ vals['protocol'] = vals['protocol'].replace(" ", "_")
+ ps = ""
+ ports = vals['portstatus']
+ lports = ports.keys()
+ lports.sort()
+ for port in lports:
+ t = ports[port]
+ if t != "closed":
+ ps += "%s: %s<br>" % (port, ports[port])
+ if ps == "":
+ ps = "All_closed"
+
+ vals['portstatus'] = ps
+
+ if 'reboot' in vals:
+ vals['reboot'] = "%s" % vals['reboot']
+ vals['reboot'] = vals['reboot'].replace(" ", "_")
+
+ try:
+ str_fields = []
+ count = 0
+ for f in format_fields:
+ str_fields.append(f % vals)
+ count += 1
+ except:
+ print >>sys.stderr, vals
+
+ s = fields_to_html(str_fields, vals)
+ print s
+
+ print "\n</tr>"
+
+ print "</table>"
+ print "<table>"
+ keys = categories.keys()
+ keys.sort()
+ for cat in keys:
+ print "<tr>"
+ print "<th nowrap align=left>Total %s</th>" % cat
+ print "<td align=left>%s</td>" % categories[cat]
+ print "</tr>"
+ print "</table>"
+
+import cgi
+import cgitb;
+cgitb.enable()
+import sys
+
+form = cgi.FieldStorage()
+myfilter = None
+
+if form.has_key('site'):
+ myfilter = form.getvalue("site")
+else:
+ myfilter = None
+
+
+if __name__ == '__main__':
+ parser = OptionParser()
+ parser.set_defaults(cmpdays=False,
+ comon="sshstatus",
+ fields="nodename,ping,ssh,pcu,category,state,kernel,bootcd",
+ dbname="findbad", # -070724-1",
+ cmpping=False,
+ cmpdns=False,
+ cmploginbase=False,
+ cmpssh=False,
+ cmpcategory=False,
+ cmpstate=False)
+ parser.add_option("", "--fields", dest="fields", help="")
+ parser.add_option("", "--dbname", dest="dbname", help="")
+ parser.add_option("", "--days", dest="cmpdays", action="store_true", help="")
+ parser.add_option("", "--ping", dest="cmpping", action="store_true", help="")
+ parser.add_option("", "--dns", dest="cmpdns", action="store_true", help="")
+ parser.add_option("", "--ssh", dest="cmpssh", action="store_true", help="")
+ parser.add_option("", "--loginbase",dest="cmploginbase",action="store_true", help="")
+ parser.add_option("", "--category", dest="cmpcategory", action="store_true", help="")
+ parser.add_option("", "--kernel", dest="cmpkernel", action="store_true", help="")
+ parser.add_option("", "--state", dest="cmpstate", action="store_true", help="")
+ parser.add_option("", "--comon", dest="comon", help="")
+ config = config(parser)
+ config.parse_args()
+ print "Content-Type: text/html\r\n"
+ print "<html><body>\n"
+ if len(sys.argv) > 1:
+ if sys.argv[1] == "ssherror":
+ ssherror = True
+ main(myfilter)
+ print "</body></html>\n"
--- /dev/null
+<?php
+
+
+function pcu_link($pcu)
+{
+ return "https://www.planet-lab.org/db/sites/pcu.php?id=" . $pcu['pcu_id'];
+}
+
+function pcu_name($pcu)
+{
+ if ( $pcu['hostname'] != NULL and $pcu['hostname'] != "" ):
+ return $pcu['hostname'];
+ else:
+ return $pcu['ip'];
+ endif;
+}
+function pcu_entry($pcu)
+{
+ if ( count($pcu['complete_entry']) > 0 ) {
+ return join("<BR>", $pcu['complete_entry']);
+ } else {
+ return " ";
+ }
+}
+
+function format_ports($pcu)
+{
+ $str = "";
+ #print print_r(is_array($pcu)) . "<BR>";
+ #print print_r(array_key_exists('portstatus', $pcu)) . "<BR>";
+ if ( is_array($pcu) && array_key_exists('portstatus', $pcu) )
+ {
+ $portstat = $pcu['portstatus'];
+
+ #foreach ( array('22', '23', '80', '443') $portstat as $port => $state)
+ foreach ( array('22', '23', '80', '443') as $port)
+ {
+ $state = $portstat[$port];
+ switch ($state)
+ {
+ case "open":
+ $color = "lightgreen";
+ break;
+ case "filtered":
+ $color = "gold";
+ break;
+ case "closed":
+ $color = "indianred";
+ break;
+ default:
+ $color = "white";
+ break;
+ }
+ $str .= "<span style='background-color: $color'>$port</span> ";
+ # . ": " . $state . "<br>";
+ }
+ } else {
+ # print print_r(is_array($pcu)) . "<BR>";
+ # print print_r(array_key_exists('portstatus', $pcu)) . "<BR>";
+ #echo "<pre>";
+ #print_r($pcu['portstatus']);
+ #echo "</pre>";
+ }
+ if ( $str == "" )
+ {
+ $str = "Closed/Filtered";
+ }
+ return $str;
+}
+function DNS_to_color($dns)
+{
+ switch ($dns)
+ {
+ case "DNS-OK":
+ return 'lightgreen';
+ case "NOHOSTNAME":
+ return 'white';
+ case "DNS-MISMATCH":
+ return 'gold';
+ case "NO-DNS-OR-IP":
+ case "DNS-NOENTRY":
+ return 'indianred';
+ }
+ return 'white';
+}
+
+function reboot_to_color($reboot)
+{
+ switch ($reboot)
+ {
+ case "0":
+ return "darkseagreen";
+ break;
+ case "NetDown":
+ return "lightgrey";
+ break;
+ case "Not_Run":
+ return "lightgrey";
+ break;
+ case "Unsupported_PCU":
+ return "indianred";
+ break;
+ default:
+ if ( strpos($reboot, "error") >= 0)
+ {
+ return "indianred";
+ } else {
+ return 'white';
+ }
+ break;
+ }
+ return "white";
+}
+
+function get_pcuid($pcu) { return $pcu['pcu_id']; }
+function get_dns($pcu) { return $pcu['dnsmatch']; }
+function get_dryrun($pcu) { return $pcu['reboot']; }
+function get_model($pcu) { return $pcu['model']; }
+function get_category_link($category,$header)
+{
+ return "<a href='printbadpcus.php?category=$category'>$header</a>";
+}
+
+include 'soltesz.php';
+$p = new Pickle();
+$findbad = $p->load("findbadpcus");
+$findbadpcus = array_keys($findbad['nodes']);
+
+$pculist = array();
+$c = 0;
+foreach ( $findbadpcus as $pcu_id )
+{
+ if ( is_array($findbad['nodes'][$pcu_id]) )
+ {
+ #if ( in_array('values', $findbad['nodes'][$pcu]) )
+ #{
+ # echo $pcu . " true<BR>";
+ #} else{
+ # echo $pcu . " false<br>";
+ #}
+ if ( array_key_exists('values', $findbad['nodes'][$pcu_id]) )
+ {
+ $pculist[] = $findbad['nodes'][$pcu_id]['values'];
+ }
+ }
+}
+$total = count($pculist);
+
+
+## Sort the pculist
+
+#$pcu_ids = array_map('get_pcuid', $pculist);
+#array_multisort($pcu_ids, SORT_ASC, SORT_NUMERIC, $pculist);
+
+#$dns_ids = array_map('get_dns', $pculist);
+#array_multisort($dns_ids, SORT_ASC, SORT_STRING, $pculist);
+
+#$dry_ids = array_map('get_dryrun', $pculist);
+#array_multisort($dry_ids, SORT_ASC, SORT_STRING, $pculist);
+if ( $_GET['category'] )
+{
+ $category = $_GET['category'];
+ if ( $category == "node_ids" )
+ {
+ $newfunc = create_function('$pcu', 'return count($pcu[\'' . $category . '\']);');
+ } else {
+ $newfunc = create_function('$pcu', 'return $pcu[\'' . $category . '\'];');
+ }
+ if ( $newfunc != "" )
+ {
+ $fields = array_map($newfunc, $pculist);
+ array_multisort($fields, SORT_ASC, SORT_STRING, $pculist);
+ } else {
+ echo "ERROR create_function == null<BR>";
+ }
+}
+
+if ( $_GET['auth'] )
+{
+ $auth = True;
+} else {
+ $auth = False;
+}
+
+
+//array_multisort($protocols, SORT_ASC, SORT_STRING, $pculist);
+?>
+
+<title>PLC PCU Info</title>
+<html>
+<body>
+
+Total PCUs : <?= $total ?>
+<table border=1>
+ <tr>
+ <th>Count</th>
+ <th><?= get_category_link("pcu_id", "PCU ID") ?></th>
+ <th><?= get_category_link("hostname", "Hostname") ?></th>
+ <th><?= get_category_link("complete_entry", "Incomplete Fields") ?></th>
+ <th><?= get_category_link("dnsmatch", "DNS Status") ?></th>
+ <th><?= get_category_link("portstatus", "Port Status") ?></th>
+ <th><?= get_category_link("reboot", "Dry Run Results") ?></th>
+ <th><?= get_category_link("model", "Model") ?></th>
+ <th><?= get_category_link("node_ids", "Nodes") ?></th>
+ <?php if ( $auth ): ?>
+ <th>Username</th>
+ <th>Password</th>
+ <th>Notes</th>
+ <?php endif; ?>
+ </tr>
+<?php $count = 0; ?>
+<?php foreach ( $pculist as $pcu ): ?>
+ <tr>
+ <td><?= $count ?></td>
+ <td id='id<?= $pcu['pcu_id'] ?>'><a href='<?= pcu_link($pcu) ?>'><?= $pcu['pcu_id'] ?></a></td>
+ <td><?= pcu_name($pcu) ?></td>
+ <td><?= pcu_entry($pcu) ?></td>
+ <td bgcolor='<?= DNS_to_color($pcu['dnsmatch']) ?>'><?= $pcu['dnsmatch'] ?></td>
+ <td><?= format_ports($pcu) ?></td>
+ <td bgcolor='<?= reboot_to_color($pcu['reboot']) ?>'><?= $pcu['reboot'] ?></td>
+ <td nowrap><?= $pcu['model'] ?></td>
+ <td><?= count( $pcu['node_ids'] ) ?></td>
+ <?php if ( $auth ): ?>
+ <td><?= ( $pcu['username'] ? $pcu['username'] : " " ) ?></td>
+ <td><?= $pcu['password'] ?></td>
+ <td><?= $pcu['notes'] ?></td>
+ <?php endif; ?>
+ </tr>
+<?php $count += 1; ?>
+<?php endforeach; ?>
+</table>
+
+</body>
+</html>
--- /dev/null
+#!/usr/bin/python
+
+# Read in the act_* databases and print out a human readable version
+
+import sys
+import time
+import getopt
+import soltesz
+
+
+def fields_to_html(fields):
+ colorMap = { 'PING' : 'darkseagreen',
+ 'NOPING': 'darksalmon',
+ 'SSH': 'darkseagreen',
+ 'NOSSH': 'indianred',
+ 'PCU': 'darkseagreen',
+ 'NOPCU': 'lightgrey',
+ 'OLDBOOTCD': 'crimson',
+ 'DOWN': 'indianred',
+ 'ALPHA': 'gold',
+ 'ERROR': 'crimson',
+ 'PROD': 'darkseagreen',
+ 'DEBUG': 'darksalmon',
+ 'DEBUG': 'darksalmon',
+ 'BOOT': 'lightgreen'}
+ r_str = ""
+ for f in fields:
+ if f in colorMap:
+ bgcolor="bgcolor='%s'" % colorMap[f]
+ else:
+ bgcolor=""
+ r_str += "<td nowrap %s>%s</td>" % (bgcolor, f)
+
+ return r_str
+
+def rtTicketLink(rt_ticket):
+ link = """<a href="https://rt.planet-lab.org/Ticket/Display.html?user=guest&pass=guest&id=%s">RT #%s</a>""" % (rt_ticket, rt_ticket)
+ return link
+
+def main():
+
+ total_sites = 0
+ total_nodes = 0
+ total_restored = 0
+ total_down = 0
+
+ act_all = soltesz.dbLoad("act_all")
+ plcdb_hn2lb = soltesz.dbLoad("plcdb_hn2lb")
+ s_nodenames = ""
+ sickdb = {}
+
+ sorted_keys = act_all.keys()
+ sorted_keys.sort()
+ for nodename in sorted_keys:
+ diag_nodelist = act_all[nodename]
+ if nodename in plcdb_hn2lb:
+ lb = plcdb_hn2lb[nodename]
+ if lb not in sickdb:
+ sickdb[lb] = {}
+ sickdb[lb][nodename] = diag_nodelist
+
+ sorted_keys = sickdb.keys()
+ sorted_keys.sort()
+ print "<table width=80% border=1>"
+ for loginbase in sorted_keys:
+ nodedict = sickdb[loginbase]
+ sort_nodekeys = nodedict.keys()
+ sort_nodekeys.sort()
+ print "<tr><td bgcolor=lightblue nowrap>",
+ print loginbase,
+ print "</td><td colspan=5> </td>",
+ print "</tr>"
+ total_sites += 1
+ for nodename in sort_nodekeys:
+ total_nodes += 1
+ if len(act_all[nodename]) == 0:
+ #print "<tr><td>%s</td>" % (nodename)
+ #print "<td>has no events</td></tr>"
+ continue
+ else:
+ # print just the latest event
+ event = act_all[nodename][0]
+ fields = []
+ fields += [nodename]
+ if 'time' in event:
+ s_time=time.strftime("%Y/%m/%d %H:%M:%S",
+ time.gmtime(event['time']))
+ fields += [s_time]
+ if 'ticket_id' in event and event['ticket_id'] != "":
+ link = rtTicketLink(event['ticket_id'])
+ fields += [link]
+ else:
+ if 'found_rt_ticket' in event and event['found_rt_ticket'] != "":
+ link = rtTicketLink(event['found_rt_ticket'])
+ fields += [link]
+ else:
+ fields += ["No Known RT Ticket"]
+
+ if event['action'] == "close_rt":
+ total_restored += 1
+ else:
+ total_down += 1
+
+ for f in ['category', 'action', 'stage', 'info']:
+ if 'stage' in f and 'stage' in event and 'stage' in event['stage']:
+ # truncate the stage_ part.
+ event['stage'] = event['stage'][6:]
+ if f in event:
+ if type(event[f]) == type([]):
+ fields += event[f]
+ else:
+ fields += [event[f]]
+ else:
+ fields += [" "]
+
+ print "<tr>",
+ print fields_to_html(fields),
+ print "</tr>"
+
+ print "</table>"
+ print "<table>"
+ print "<tr>"
+ print "<th>Sites</th>"
+ print "<th>Nodes</th>"
+ print "<th>Restored</th>"
+ print "<th>Down</th>"
+ print "</tr>"
+
+ print "<tr>"
+ print "<td>%s</td>" % total_sites
+ print "<td>%s</td>" % total_nodes
+ print "<td>%s</td>" % total_restored
+ print "<td>%s</td>" % total_down
+
+ print "</tr>"
+ print "</table>"
+
+ print s_nodenames
+
+
+if __name__ == '__main__':
+ print "Content-Type: text/html\r\n"
+ print "<html><body>\n"
+ main()
+ print "</body></html>\n"