class NodeWidget(widgets.Widget):
pass
-def prep_node_for_display(node):
+def prep_node_for_display(node, pcuhash=None):
agg = aggregate()
agg.node = node
if node.plc_pcuid:
- pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
+ if pcuhash:
+ pcu = pcuhash[node.plc_pcuid]
+ else:
+ pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
+
if pcu:
agg.pcu_status = pcu.reboot_trial_status
agg.pcu_short_status = format_pcu_shortstatus(pcu)
flash("Welcome To MyOps!")
return dict(now=time.ctime())
+ @expose(template="monitorweb.templates.nodelist")
+ def node2(self, filter='boot'):
+
+ fbquery = FindbadNodeRecord.get_all_latest()
+ fbpcus = FindbadPCURecord.get_all_latest()
+ def fbtohash(fbpculist):
+ h = {}
+ for p in fbpculist:
+ h[p.plc_pcuid] = p
+
+ pcuhash = fbtohash(fbpcus)
+
+ query = []
+ for node in fbquery:
+ # NOTE: reformat some fields.
+ agg = prep_node_for_display(node, pcuhash)
+
+ if not agg.history:
+ continue
+
+ query.append(agg)
+
+ widget = NodeWidget(template='monitorweb.templates.node_template')
+ return dict(now=time.ctime(), query=query, nodewidget=widget)
+
@expose(template="monitorweb.templates.nodelist")
def node(self, filter='boot'):
print "NODE------------------"
# NOTE: reformat some fields.
agg = prep_node_for_display(node)
- #node.history.status
- #print node.hostname
-
if not agg.history:
continue
elif agg.history.status in ['debug', 'monitordebug']:
filtercount['debug'] += 1
else:
- # TODO: need a better fix. filtercount
- # doesn't maps to GetBootStates() on
- # 4.3 so this one fails quite often.
if filtercount.has_key(agg.history.status):
filtercount[agg.history.status] += 1
query.append(site)
return dict(query=query, fc=filtercount)
+ @expose(template="monitorweb.templates.sitesummary")
+ def sitesummary(self, loginbase="princeton"):
+ nodequery = []
+ for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
+ agg = prep_node_for_display(node)
+ nodequery += [agg]
+
+ return dict(nodequery=nodequery, loginbase=loginbase)
+
+ @expose(template="monitorweb.templates.summary")
+ def summary(self, since=7):
+ sumdata = {}
+ sumdata['nodes'] = {}
+ sumdata['sites'] = {}
+ sumdata['pcus'] = {}
+
+ def summarize(query, type):
+ for o in query:
+ if o.status not in sumdata[type]:
+ sumdata[type][o.status] = 0
+ sumdata[type][o.status] += 1
+
+ fbquery = HistorySiteRecord.query.all()
+ summarize(fbquery, 'sites')
+ fbquery = HistoryPCURecord.query.all()
+ summarize(fbquery, 'pcus')
+ fbquery = HistoryNodeRecord.query.all()
+ summarize(fbquery, 'nodes')
+
+ if 'monitordebug' in sumdata['nodes']:
+ d = sumdata['nodes']['monitordebug']
+ del sumdata['nodes']['monitordebug']
+ sumdata['nodes']['failboot'] = d
+
+ return dict(sumdata=sumdata, setorder=['good', 'offline', 'down', 'online'])
@expose(template="monitorweb.templates.actionsummary")
def actionsummary(self, since=7):
#site-offline { background-color: red; }\r
#site-down { background-color: indianred; }\r
\r
+#site-True { background-color : darkseagreen; }\r
+#site-False { background-color: indianred; }\r
+\r
#node-online { background-color : lightgreen; }\r
#node-good { background-color : darkseagreen; }\r
#node-offline { background-color: red; }\r
#pcu-offline { background-color: red; }\r
#pcu-down { background-color: indianred; }\r
\r
-/*#site-0 { background-color : white; }*/\r
+#site-0 { background-color : darkseagreen ; }\r
#site-1 { background-color: gold; }\r
#site-2 { background-color: indianred; }\r
\r
<?xml version="1.0" encoding="UTF-8"?>
<Module>
-<ModulePrefs title="Monitor Node Count" title_url="http://www.planet-lab.org">
+<ModulePrefs title="MyOps Summary" title_url="http://www.planet-lab.org">
<Require feature="dynamic-height"/>
</ModulePrefs>
<Content type="html"><![CDATA[
_gel('content_div').innerHTML = responseText;
_IG_AdjustIFrameHeight();
};
-_IG_FetchContent('http://monitor.planet-lab.org/monitor/actionsummary', displaycontent, { refreshInterval: 300 });
+_IG_FetchContent('http://monitor.planet-lab.org/monitor/summary', displaycontent, { refreshInterval: 300 });
</script>
]]></Content>
</Module>
<?xml version="1.0" encoding="UTF-8"?>
<Module>
- <ModulePrefs title="PlanetLab Site Status" title_url="http://www.planet-lab.org">
+ <ModulePrefs title="MyOps Site Status" title_url="http://www.planet-lab.org">
<Require feature="dynamic-height"/>
</ModulePrefs>
<UserPref name="loginBase" display_name="Site Login Base"
_gel('content_div').innerHTML = responseText;
_IG_AdjustIFrameHeight();
};
-var url = 'http://monitor.planet-lab.org/monitor/actionlist?loginbase=' + prefs.getString("loginBase");
+var url = 'http://monitor.planet-lab.org/monitor/sitesummary?loginbase=' + prefs.getString("loginBase");
_IG_FetchContent(url, displaycontent, { refreshInterval: 1200 });
</script>
]]></Content>
import turbogears as tg
import urllib
+def plc_myops_uri():
+ return "http://" + config.MONITOR_HOSTNAME
def plc_mail_uri(ticketid):
return config.RT_WEB_SERVER + "/Ticket/Display.html?id=" + str(ticketid)
def plc_node_uri(hostname):
<table id="sortable_table" class="datagrid" border="1" width="100%">
<thead>
<tr>
- <th mochi:format="int"></th>
- <!--th>Site</th>
- <th>pcu</th-->
- <th>date</th>
+ <th>Last Check</th>
+ <th>Last Change</th>
<th>hostname</th>
- <th>last_contact</th>
+ <th>Status</th>
</tr>
</thead>
<tbody>
<tr py:for="i,node in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
- <td></td>
- <!--td id="site-${node.site.status}">
- <a href="${link('pcuview', loginbase=node.loginbase)}">${node.loginbase}</a>
- </td>
- <td width="20%" nowrap='true' align='center' id="status-${node.pcu_short_status}">
- <div id="links">
- <a class="info" py:if="'error' in node.pcu_short_status"
- href="${link('pcuview', pcuid=node.plc_pcuid)}">
- Error<span><pre>${node.pcu.reboot_trial_status}</pre></span></a>
- <a py:if="'error' not in node.pcu_short_status and 'none' not in node.pcu_short_status"
- href="${link('pcuview', pcuid=node.plc_pcuid)}"
- py:content="node.pcu_short_status">Reboot Status</a>
- <span py:if="'none' in node.pcu_short_status"
- py:content="node.pcu_short_status">Reboot Status</span>
- </div>
- </td-->
- <!--td id="node-${node.observed_status}" nowrap="true">
- <a target="_top" href="${link('pcuview', hostname=node.hostname)}" py:content="node.hostname">your.host.org</a></td-->
- <!--td nowrap="true" py:content="node.kernel"></td-->
- <!--td py:content="node.date_checked"></td-->
<td py:content="node.last_checked"></td>
+ <td py:content="diff_time(mktime(node.last_changed.timetuple()))"></td>
<td nowrap="true">
<a target="_top" href="${link('pcuview', hostname=node.hostname)}" py:content="node.hostname">your.host.org</a></td>
<td id="node-${node.status}" py:content="node.status"></td>
xmlns:mochi="http://www.mochi.org">
<div py:match="item.tag == 'content'">
- <h3>Node History : ${pcu_id}</h3>
+ <h3>PCU History for pcu_id : <a href="${plc_pcu_uri_id(pcu_id)}">${pcu_id}</a></h3>
<table width="100%">
<tbody>
<tr>
<table id="sortable_table" class="datagrid" border="1" width="100%">
<thead>
<tr>
- <th mochi:format="int"></th>
- <!--th>Site</th>
- <th>pcu</th-->
- <th>date</th>
+ <th>Last Check</th>
+ <th>Last Change</th>
<th>pcu_id</th>
- <th>last_contact</th>
+ <th>Status</th>
</tr>
</thead>
<tbody>
<tr py:for="i,pcu in enumerate(query)" class="${i%2 and 'odd' or 'even'}" >
- <td></td>
- <!--td id="site-${node.site.status}">
- <a href="${link('pcuview', loginbase=node.loginbase)}">${node.loginbase}</a>
- </td>
- <td width="20%" nowrap='true' align='center' id="status-${node.pcu_short_status}">
- <div id="links">
- <a class="info" py:if="'error' in node.pcu_short_status"
- href="${link('pcuview', pcuid=node.plc_pcuid)}">
- Error<span><pre>${node.pcu.reboot_trial_status}</pre></span></a>
- <a py:if="'error' not in node.pcu_short_status and 'none' not in node.pcu_short_status"
- href="${link('pcuview', pcuid=node.plc_pcuid)}"
- py:content="node.pcu_short_status">Reboot Status</a>
- <span py:if="'none' in node.pcu_short_status"
- py:content="node.pcu_short_status">Reboot Status</span>
- </div>
- </td-->
- <!--td id="node-${node.observed_status}" nowrap="true">
- <a target="_top" href="${link('pcuview', hostname=node.hostname)}" py:content="node.hostname">your.host.org</a></td-->
- <!--td nowrap="true" py:content="node.kernel"></td-->
- <!--td py:content="node.date_checked"></td-->
<td py:content="pcu.last_checked"></td>
+ <td py:content="diff_time(mktime(pcu.last_changed.timetuple()))"></td>
<td nowrap="true">
<a target="_top" href="${link('pcuview', pcuid=pcu.plc_pcuid)}" py:content="pcu.plc_pcuid">your.host.org</a></td>
<td id="pcu-${pcu.status}" py:content="pcu.status"></td>
<tr>
<th mochi:format="int"></th>
<th>Site name</th>
+ <th mochi:format="int">Slices/Max</th>
<th>Enabled</th>
<th>Penalty</th>
- <th mochi:format="int">Slices/Max</th>
+ <th>Last Change</th>
<th mochi:format="int">Nodes/Total</th>
<th>Date Checked</th>
</tr>
<img style='display: inline' border='0' src="static/images/extlink.gif" align='right'/></a>
</div>
</td>
- <td py:content="site.enabled"></td>
- <td id="site-${site.penalty_level}">${site.penalty_level}</td>
<td>${site.slices_used}/${site.slices_total}</td>
- <td>${site.nodes_up} / ${site.nodes_total}</td>
+ <td id="site-${site.enabled}" py:content="site.enabled"></td>
+ <td id="site-${site.penalty_level}">${site.penalty_level}</td>
<td id="site-${site.status}" py:content="diff_time(mktime(site.last_changed.timetuple()))"></td>
+ <td id="site-${site.nodes_up >= 2}">${site.nodes_up} / ${site.nodes_total}</td>
<td py:content="site.timestamp"></td>
</tr>
</tbody>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python
+layout_params['page_title'] = "MyOps Detail View"
+from monitor.util import diff_time
+from monitor import config
+from time import mktime
+from pcucontrol.reboot import pcu_name, model_to_object
+from links import *
+?>
+<html xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
+ <head>
+ <link href="http://monitor.planet-lab.org/monitor/static/css/style.css" type="text/css" rel="stylesheet" />
+ </head>
+
+ <h3>Nodes for site ${loginbase}</h3>
+ <p>Working on the color...</p>
+ <p py:if="len(nodequery) == 0">
+ There are no registered nodes for this site.
+ </p>
+ <table py:if="len(nodequery) > 0" id="sortable_table" class="datagrid" border="1" width="100%">
+ <thead>
+ <tr>
+ <th>History</th>
+ <th>Hostname</th>
+ <th>Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr py:for="i,agg in enumerate(nodequery)" class="${i%2 and 'odd' or 'even'}" >
+ <td><a target="_blank" href="nodehistory?hostname=${agg.node.hostname}">history</a></td>
+ <td id="node-${agg.node.observed_status}" nowrap="true" >
+ <a class="ext-link" target="_blank" href="${plc_node_uri_id(agg.node.plc_node_stats['node_id'])}">
+ <span class="icon">${agg.node.hostname}</span></a>
+ </td>
+ <td py:content="agg.node.observed_status" nowrap="true" ></td>
+ </tr>
+ </tbody>
+ </table>
+
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python
+layout_params['page_title'] = "MyOps Summary"
+from monitor.util import diff_time
+from monitor import config
+from time import mktime
+from links import *
+?>
+<html
+ xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
+
+ <?python orig=True ?>
+ <table>
+ <tbody>
+ <span py:for="primarykey in ['sites', 'nodes', 'pcus']">
+ <tr>
+ <td width="50" rowspan="2">${primarykey.capitalize()}</td>
+ <span py:for="i,key in enumerate(setorder + [s for s in set(sumdata[primarykey].keys())-set(setorder)]) ">
+ <th valign="top" py:if="orig and i<4" py:content="key.capitalize()"></th>
+ <th valign="top" py:if="orig and i>3" py:content="key.capitalize()"></th>
+ <th valign="top" py:if="not orig and i>3" py:content="key.capitalize()"></th>
+ <th valign="top" py:if="not orig and i<4" py:content=""></th>
+ </span>
+ </tr>
+ <?python orig=False ?>
+ <tr>
+ <span py:for="key in setorder + [s for s in set(sumdata[primarykey].keys())-set(setorder)]">
+ <td bgcolor="lightgrey" valign="top" align="center" py:content="sumdata[primarykey][key]"></td>
+ </span>
+ </tr>
+ </span>
+ </tbody>
+ </table>
+<div py:match="item.tag == 'content'">
+</div>
+
+</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
+<?python\r
+from links import *\r
+?>\r
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://purl.org/kid/ns#"\r
py:extends="'master.kid'">\r
<head>\r
<p> All nodes: <a href="node">Nodes</a> <br/> </p>\r
</li>\r
</ol>\r
- <!--div class="notice"> If you create something cool, please <a href="http://groups.google.com/group/turbogears">let people know</a>, and consider contributing something back to the <a href="http://groups.google.com/group/turbogears">community</a>.</div-->\r
+ <p>If you'd like to track things a little more informally, you can install\r
+ these Google Gadgets for summaries of the entire system or a specific\r
+ site.</p>\r
+ <ul class="links">\r
+ <li><a href="http://fusion.google.com/add?source=atgs&moduleurl=${plc_myops_uri()}/monitor/gadget.xml">MyOps Summary</a></li>\r
+ <li><a href="http://fusion.google.com/add?source=atgs&moduleurl=${plc_myops_uri()}/monitor/sitemonitor.xml">Site Summary</a></li>\r
+ </ul>\r
</div>\r
<!-- End of getting_started -->\r
</body>\r