class NodeWidget(widgets.Widget):
pass
-def prep_node_for_display(node, pcuhash=None):
+def prep_node_for_display(node, pcuhash=None, preppcu=True, asofdate=None):
agg = aggregate()
agg.node = node
- if node.plc_pcuid:
+ if node.plc_pcuid and preppcu:
if pcuhash:
pcu = pcuhash[node.plc_pcuid]
else:
if agg.loginbase:
agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
+
+ if asofdate:
+ agg.site = agg.site.get_as_of(asofdate)
+
if agg.site is None:
# TODO: need a cleaner fix for this...
agg.site = HistorySiteRecord.by_loginbase("pl")
agg.site = HistorySiteRecord.by_loginbase("ple")
agg.history = HistoryNodeRecord.by_hostname(node.hostname)
+ if asofdate:
+ agg.history = agg.history.get_as_of(asofdate)
agg.ports = format_ports(node.port_status)
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)
-
+ def node2(self, filter=None):
+ nhquery = HistoryNodeRecord.query.all()
query = []
- for node in fbquery:
- # NOTE: reformat some fields.
- agg = prep_node_for_display(node, pcuhash)
-
- if not agg.history:
- continue
-
- query.append(agg)
+ for nh in nhquery:
+ if filter:
+ if nh.status == filter:
+ query.append(nh)
+ else:
+ query.append(nh)
+
+ rquery=[]
+ for q in query:
+ fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
+ agg = prep_node_for_display(fb)
+ rquery.append(agg)
+
+ #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
+#
+# if filter:
+# if agg.history.status == filter:
+# query.append(agg)
+# else:
+# query.append(agg)
widget = NodeWidget(template='monitorweb.templates.node_template')
- return dict(now=time.ctime(), query=query, nodewidget=widget)
+ return dict(now=time.ctime(), query=rquery, nodewidget=widget)
@expose(template="monitorweb.templates.nodelist")
def node(self, filter='boot'):
@expose(template="monitorweb.templates.pcuview")
@exception_handler(nodeaction_handler,"isinstance(tg_exceptions,RuntimeError)")
def pcuview(self, loginbase=None, pcuid=None, hostname=None, since=20, **data):
- print "PCUVIEW------------------"
- print "befor-len: ", len( [ i for i in session] )
session.flush(); session.clear()
- print "after-len: ", len( [ i for i in session] )
sitequery=[]
pcuquery=[]
nodequery=[]
if 'exceptions' in data:
exceptions = data['exceptions']
+ if 'query' in data:
+ obj = data['query']
+ if len(obj.split(".")) > 1: hostname = obj
+ else: loginbase=obj
+
if pcuid:
print "pcuid: %s" % pcuid
pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
return dict(query=query, pcu_id=pcu_id)
+ @expose(template="monitorweb.templates.nodescanhistory")
+ def nodescanhistory(self, hostname=None, length=10):
+ try: length = int(length)
+ except: length = 10
+
+ fbnode = FindbadNodeRecord.get_by(hostname=hostname)
+ # TODO: add links for earlier history if desired.
+ l = fbnode.versions[-length:]
+ l.reverse()
+ query=[]
+ for node in l:
+ agg = prep_node_for_display(node, pcuhash=None, preppcu=False, asofdate=node.timestamp)
+ query.append(agg)
+
+ return dict(query=query, hostname=hostname)
+
@expose(template="monitorweb.templates.nodehistory")
def nodehistory(self, hostname=None):
query = []
if hostname:
- #fbnode = FindbadNodeRecord.get_by(hostname=hostname)
- ## TODO: add links for earlier history if desired.
- #l = fbnode.versions[-100:]
- #l.reverse()
- #for node in l:
- # prep_node_for_display(node)
- # query.append(node)
-
fbnode = HistoryNodeRecord.get_by(hostname=hostname)
l = fbnode.versions[-100:]
l.reverse()
--- /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 Node List"
+from monitor.util import diff_time
+from time import mktime
+from links import *
+
+?>
+<html py:layout="'sitemenu.kid'"
+ xmlns:py="http://purl.org/kid/ns#"
+ xmlns:mochi="http://www.mochi.org">
+
+<div py:match="item.tag == 'content'">
+
+ <script type="text/javascript">
+ function nodelist_paginator(opts) { plekit_table_paginator(opts, "nodelist"); }
+ </script>
+
+<table id="nodelist" cellpadding="0" border="0" class="plekit_table sortable-onload-2 colstyle-alt no-arrow paginationcallback-nodelist_paginator max-pages-10 paginate-25">
+ <thead>
+ <tr class='pagesize_area'><td class='pagesize_area' colspan='10'>
+ <form class='pagesize' action='satisfy_xhtml_validator'><fieldset>
+ <input class='pagesize_input' type='text' id="nodelist_pagesize" value='25'
+ onkeyup='plekit_pagesize_set("nodelist","nodelist_pagesize", 25);'
+ size='3' maxlength='3' />
+ <label class='pagesize_label'> items/page </label>
+ <img class='reset' src="/planetlab/icons/clear.png" alt="reset visible size"
+ onmousedown='plekit_pagesize_reset("nodelist","nodelist_pagesize", 999);' />
+ </fieldset></form></td></tr>
+
+ <tr class='search_area'><td class='search_area' colspan='10'>
+ <div class='search'><fieldset>
+ <label class='search_label'> Search </label>
+ <input class='search_input' type='text' id='nodelist_search'
+ onkeyup='plekit_table_filter("nodelist","nodelist_search","nodelist_search_and");'
+ size='self.search_width' maxlength='256' />
+ <label>and</label>
+ <input id='nodelist_search_and' class='search_and'
+ type='checkbox' checked='checked'
+ onchange='plekit_table_filter("nodelist","nodelist_search","nodelist_search_and");' />
+ <img class='reset' src="/planetlab/icons/clear.png" alt="reset search"
+ onmousedown='plekit_table_filter_reset("nodelist","nodelist_search","nodelist_search_and");' />
+ </fieldset></div></td></tr>
+
+ <tr>
+ <th nowrap="true" class="sortable plekit_table">Date Checked</th>
+ <th class="sortable plekit_table">Hostname</th>
+ <th class="sortable plekit_table">Ping</th>
+ <th class="sortable plekit_table">SSH</th>
+ <th class="sortable plekit_table">Stat</th>
+ <th class="sortable plekit_table">kernel</th>
+ <th class="sortable plekit_table">BootCD</th>
+ <th class="sortable plekit_table">Last_contact</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr py:for="i,node in enumerate(query)">
+ <span py:if="node is not None">
+ <td nowrap="true" py:content="node.node.date_checked">date_checked</td>
+ <td nowrap="true">
+ <a target="_top" href="${link('pcuview', hostname=node.node.hostname)}" py:content="node.node.hostname">your.host.org</a></td>
+ <td py:content="node.node.ping_status">ping</td>
+ <td py:content="node.node.ssh_status">ssh</td>
+ <td py:content="node.node.plc_node_stats['boot_state']">boot</td>
+ <td nowrap="true" py:content="node.kernel"></td>
+ <td nowrap="true" py:content="node.node.bootcd_version"></td>
+ <td id="node-${node.node.observed_status}" py:content="diff_time(node.node.plc_node_stats['last_contact'])"></td>
+ </span>
+ </tr>
+
+ </tbody>
+</table>
+
+</div>
+
+</html>
<thead>
<tr>
<th mochi:format="int"></th>
- <th>History</th>
+ <th>History (scan)</th>
<th>Hostname</th>
<th>last_contact (cached)</th>
<th>last_checked</th>
<tbody>
<tr py:for="i,agg in enumerate(nodequery)" class="${i%2 and 'odd' or 'even'}" >
<td></td>
- <td><a href="nodehistory?hostname=${agg.node.hostname}">history</a></td>
+ <td><a href="nodehistory?hostname=${agg.node.hostname}">status</a>
+ (<a href="nodescanhistory?hostname=${agg.node.hostname}">scan</a>) history</td>
<td id="node-${agg.node.observed_status}" nowrap="true" >
<a class="ext-link" href="${plc_node_uri_id(agg.node.plc_node_stats['node_id'])}">
<span class="icon">${agg.node.hostname}</span></a>
<body>
<table valign="top" border="1" bgcolor="white" align="center" width="700px">
- <tr> <td> <div id="header">${page_title}</div> </td> </tr>
- <tr>
+ <tr> <td> <div id="header">${page_title}</div> </td>
<td>
+ <form action="pcuview" method="GET">
+ <table>
+ <tr><td> Quick Search:</td>
+ <td><input type="text" name="query"/></td>
+ <td><input type="submit"/></td>
+ </tr>
+ </table>
+ </form>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
<table id="nps-table" width="100%">
<thead>
<tr>
</table>
</td>
</tr>
- <tr> <td> <div id="footer">Copywrite © 2007-2008 The Trustees of Princeton University</div> </td> </tr>
+ <tr> <td> <div id="footer">Copyright © 2007-2008 The Trustees of Princeton University</div> </td> </tr>
</table>
</body>
<?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>
+ <td bgcolor="lightgrey" valign="top" align="center">
+ <a target="_blank" href="${link(plc_myops_uri() + '/monitor/node2', filter=key)}" py:if="primarykey == 'nodes'" py:content="sumdata[primarykey][key]"></a>
+ <div py:if="primarykey != 'nodes'" py:content="sumdata[primarykey][key]"></div>
+ </td>
</span>
</tr>
</span>