add a link to both types of node history, status and data
authorStephen Soltesz <soltesz@cs.princeton.edu>
Fri, 26 Jun 2009 23:40:44 +0000 (23:40 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Fri, 26 Jun 2009 23:40:44 +0000 (23:40 +0000)
add a quick search at the top of sitemenu for hostnames and loginbases

web/MonitorWeb/monitorweb/controllers.py
web/MonitorWeb/monitorweb/templates/nodescanhistory.kid [new file with mode: 0644]
web/MonitorWeb/monitorweb/templates/pcuview.kid
web/MonitorWeb/monitorweb/templates/sitemenu.kid
web/MonitorWeb/monitorweb/templates/summary.kid

index 60bdbcc..5fe87b1 100644 (file)
@@ -108,11 +108,11 @@ def prep_pcu_for_display(pcu):
 class NodeWidget(widgets.Widget):
        pass
 
 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
 
        agg = aggregate()
        agg.node = node
 
-       if node.plc_pcuid:
+       if node.plc_pcuid and preppcu:
                if pcuhash:
                        pcu = pcuhash[node.plc_pcuid]
                else:
                if pcuhash:
                        pcu = pcuhash[node.plc_pcuid]
                else:
@@ -145,6 +145,10 @@ def prep_node_for_display(node, pcuhash=None):
 
        if agg.loginbase:
                agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
 
        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")
                if agg.site is None:
                        # TODO: need a cleaner fix for this...
                        agg.site = HistorySiteRecord.by_loginbase("pl")
@@ -152,6 +156,8 @@ def prep_node_for_display(node, pcuhash=None):
                                agg.site = HistorySiteRecord.by_loginbase("ple")
 
        agg.history = HistoryNodeRecord.by_hostname(node.hostname)
                                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)
 
 
        agg.ports = format_ports(node.port_status)
 
@@ -172,29 +178,46 @@ class Root(controllers.RootController, MonitorXmlrpcServer):
                return dict(now=time.ctime())
 
        @expose(template="monitorweb.templates.nodelist")
                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 = []
                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')
                                
                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.nodelist")
        def node(self, filter='boot'):
@@ -314,10 +337,7 @@ class Root(controllers.RootController, MonitorXmlrpcServer):
        @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):
        @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()
                session.flush(); session.clear()
-               print "after-len: ", len( [ i for i in session] )
                sitequery=[]
                pcuquery=[]
                nodequery=[]
                sitequery=[]
                pcuquery=[]
                nodequery=[]
@@ -336,6 +356,11 @@ class Root(controllers.RootController, MonitorXmlrpcServer):
                if 'exceptions' in data:
                        exceptions = data['exceptions']
 
                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)
                if pcuid:
                        print "pcuid: %s" % pcuid
                        pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
@@ -379,18 +404,26 @@ class Root(controllers.RootController, MonitorXmlrpcServer):
 
                return dict(query=query, pcu_id=pcu_id)
 
 
                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:
        @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()
                        fbnode = HistoryNodeRecord.get_by(hostname=hostname)
                        l = fbnode.versions[-100:]
                        l.reverse()
diff --git a/web/MonitorWeb/monitorweb/templates/nodescanhistory.kid b/web/MonitorWeb/monitorweb/templates/nodescanhistory.kid
new file mode 100644 (file)
index 0000000..7e99d9d
--- /dev/null
@@ -0,0 +1,76 @@
+<!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>
index 685f18c..9390bb4 100644 (file)
@@ -143,7 +143,7 @@ from links import *
                        <thead>
                                <tr>
                                        <th mochi:format="int"></th>
                        <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>
                                        <th>Hostname</th>
                                        <th>last_contact (cached)</th>
                                        <th>last_checked</th>
@@ -156,7 +156,8 @@ from links import *
                        <tbody>
                                <tr py:for="i,agg in enumerate(nodequery)" class="${i%2 and 'odd' or 'even'}" >
                                        <td></td>
                        <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>
                                        <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>
index 9479293..0d0f5c6 100644 (file)
 
   <body>
        <table valign="top" border="1" bgcolor="white" align="center" width="700px">
 
   <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>
                <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 id="nps-table" width="100%">
                        <thead>
                        <tr>
@@ -50,7 +61,7 @@
                        </table>
                </td>
        </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>
        </table>
 
   </body>
index 27b888c..e3f7d5f 100644 (file)
@@ -26,7 +26,10 @@ from links import *
                        <?python orig=False ?>
                        <tr>
                                <span py:for="key in setorder + [s for s in set(sumdata[primarykey].keys())-set(setorder)]">
                        <?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>
                                </span>
                        </tr>
                </span>