add simple command line tools for manipulating node groups, and for querying
authorStephen Soltesz <soltesz@cs.princeton.edu>
Wed, 9 Apr 2008 16:56:35 +0000 (16:56 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Wed, 9 Apr 2008 16:56:35 +0000 (16:56 +0000)
the information collected by monitor for a given node.

nodegroups.py [new file with mode: 0755]
nodeinfo.py [new file with mode: 0755]

diff --git a/nodegroups.py b/nodegroups.py
new file mode 100755 (executable)
index 0000000..92465d0
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+
+# This script is used to manipulate the operational state of nodes in
+# different node groups.  These are basically set operations on nodes via the
+# PLC api.
+# 
+# Take the ng name as an argument....
+# optionally, 
+#  * restart them all.
+#  * Set some or all in the set to rins.
+#  * get a list of nodes in the Alpha nodegroup.
+# 
+# Given a nodelist, it could tag each one with a nodegroup name.
+#  * 
+
+import plc
+import auth
+api = plc.PLC(auth.auth, auth.plc)
+
+from config import config
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.set_defaults(nodegroup="Alpha",
+                                       node=None,
+                                       nodelist=None,
+                                       list=False,
+                                       add=False,
+                                       delete=False,
+                                       )
+parser.add_option("", "--nodegroup", dest="nodegroup", metavar="NodegroupName",
+                                       help="Specify a nodegroup to perform actions on")
+parser.add_option("", "--list", dest="list", action="store_true", 
+                                       help="List all nodes in the given nodegroup")
+parser.add_option("", "--add", dest="add", action="store_true", 
+                                       help="Add nodes to the given nodegroup")
+parser.add_option("", "--delete", dest="delete", action="store_true", 
+                                       help="Delete nodes from the given nodegroup")
+parser.add_option("", "--node", dest="node", metavar="nodename.edu", 
+                                       help="A single node name to add to the nodegroup")
+parser.add_option("", "--nodelist", dest="nodelist", metavar="list.txt", 
+                                       help="Use all nodes in the given file for operation.")
+config = config(parser)
+config.parse_args()
+
+# COLLECT nodegroups, nodes and node lists
+ng = api.GetNodeGroups({'name' : config.nodegroup})
+nodelist = api.GetNodes(ng[0]['node_ids'])
+hostnames = [ n['hostname'] for n in nodelist ]
+
+if config.node or config.nodelist:
+       if config.node: hostnames = [ config.node ] 
+       else: hostnames = config.getListFromFile(config.nodelist)
+
+# commands:
+if config.list:
+       print " ---- Nodes in the %s Node Group ----" % config.nodegroup
+       i = 0
+       for node in nodelist:
+               print "%-2d" % i, 
+               print "%(hostname)-38s %(boot_state)5s %(key)s" % node
+               i += 1
+
+elif config.add:
+       for node in hostnames:
+               print "Adding %s to %s nodegroup" % (config.node, config.nodegroup)
+               api.AddNodeToNodeGroup(config.node, config.nodegroup)
+
+elif config.delete:
+       for node in hostnames:
+               print "Deleting %s from %s nodegroup" % (config.node, config.nodegroup)
+               api.DeleteNodeFromNodeGroup(config.node, config.nodegroup)
+
+else:
+       print "no other options supported."
diff --git a/nodeinfo.py b/nodeinfo.py
new file mode 100755 (executable)
index 0000000..4bee46f
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+
+import plc
+import auth
+api = plc.PLC(auth.auth, auth.plc)
+
+import soltesz
+fb = soltesz.dbLoad("findbad")
+act_all = soltesz.dbLoad("act_all")
+
+import reboot
+
+import time
+
+from config import config
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.set_defaults(node=None)
+parser.add_option("", "--node", dest="node", metavar="nodename.edu", 
+                                       help="A single node name to add to the nodegroup")
+config = config(parser)
+config.parse_args()
+
+def diff_time(timestamp):
+       now = time.time()
+       diff = now - timestamp
+       # return the number of seconds as a difference from current time.
+       t_str = ""
+       if diff < 60: # sec in min.
+               t = diff
+               t_str = "%s sec ago" % t
+       elif diff < 60*60: # sec in hour
+               t = diff // (60)
+               t_str = "%s min ago" % int(t)
+       elif diff < 60*60*24: # sec in day
+               t = diff // (60*60)
+               t_str = "%s hours ago" % int(t)
+       elif diff < 60*60*24*7: # sec in week
+               t = diff // (60*60*24)
+               t_str = "%s days ago" % int(t)
+       elif diff < 60*60*24*30: # approx sec in month
+               t = diff // (60*60*24*7)
+               t_str = "%s weeks ago" % int(t)
+       elif diff > 60*60*24*30: # approx sec in month
+               t = diff // (60*60*24*7*30)
+               t_str = "%s months ago" % int(t)
+       return t_str
+
+def plc_print_nodeinfo(plcnode):
+       url = "https://www.planet-lab.org/db/nodes/index.php?nodepattern="
+       plcnode['url'] = url + plcnode['hostname']
+
+       print "%(hostname)s %(url)s" % plcnode
+       print "   Checked: %s" % time.ctime()
+
+       print "\t boot_state |   created   |   updated   | last_contact"
+       print "\t %10.10s | %11.11s | %11.11s | %12s" % \
+               (plcnode['boot_state'], diff_time(plcnode['date_created']),
+                diff_time(plcnode['last_updated']), 
+                diff_time(plcnode['last_contact']))
+
+def fb_print_nodeinfo(fbnode):
+       print "   Checked: ",
+       if 'checked' in fbnode:
+               print "%11.11s " % diff_time(fbnode['checked'])
+       else:
+               print "Unknown"
+       print "\t      state |  ssh  |  pcu  | bootcd | category | kernel"
+       if fbnode['bootcd']:
+               fbnode['bootcd'] = fbnode['bootcd'].split()[-1]
+       else:
+               fbnode['bootcd'] = "unknown"
+       fbnode['kernel'] = fbnode['kernel'].split()[2]
+       print "\t %(state)10.10s | %(ssh)5.5s | %(pcu)5.5s | %(bootcd)6.6s | %(category)8.8s | %(kernel)s" % fbnode
+
+def act_print_nodeinfo(actnode, header):
+       if header[0]:
+               print "   Created: %11.11s" % diff_time(actnode['date_created'])
+               print "   LastTime %11.11s" % diff_time(actnode['time'])
+               print "\t      RT     | category | action          | msg"
+               header[0] = False
+
+       if 'rt' in actnode:
+               print "\t %5.5s %5.5s | %8.8s | %15.15s | %s" % \
+                       (actnode['rt']['Status'], actnode['rt']['id'][7:],
+                        actnode['category'], actnode['action'][0], 
+                        actnode['msg_format'][:-1])
+       else:
+               print "\t       %5.5s | %8.8s | %15.15s | %s" % \
+                       (actnode['ticket_id'],
+                        actnode['category'], actnode['action'][0], 
+                        actnode['msg_format'][:-1])
+
+def pcu_print_info(pcuinfo):
+       print "   Checked: ",
+       if 'checked' in pcuinfo:
+               print "%11.11s " % diff_time(pcuinfo['checked'])
+       else:
+               print "Unknown"
+
+       print "\t            user   |          password |   hostname "
+       print "\t %17s | %17s | %30s | %s" % \
+               (pcuinfo['username'], pcuinfo['password'], 
+                reboot.pcu_name(pcuinfo), pcuinfo['model'])
+
+       if pcuinfo['portstatus']['22'] == "open":
+               print "\t ssh -o PasswordAuthentication=yes -o PubkeyAuthentication=no %s@%s" % (pcuinfo['username'], reboot.pcu_name(pcuinfo))
+       if pcuinfo['portstatus']['23'] == "open":
+               print "\t telnet %s" % (reboot.pcu_name(pcuinfo))
+       if pcuinfo['portstatus']['80'] == "open" or \
+               pcuinfo['portstatus']['443'] == "open":
+               print "\t http://%s" % (reboot.pcu_name(pcuinfo))
+
+if config.node:
+       plc_nodeinfo = api.GetNodes({'hostname': config.node}, None)[0]
+       fb_nodeinfo  = fb['nodes'][config.node]['values']
+
+       plc_print_nodeinfo(plc_nodeinfo)
+       fb_print_nodeinfo(fb_nodeinfo)
+
+       if fb_nodeinfo['pcu'] == "PCU":
+               pcu = reboot.get_pcu_values(fb_nodeinfo['plcnode']['pcu_ids'][0])
+               pcu_print_info(pcu)
+
+       if config.node in act_all and len(act_all[config.node]) > 0:
+               header = [True]
+               for act_nodeinfo in act_all[config.node]:
+                       act_print_nodeinfo(act_nodeinfo, header)
+       else: act_nodeinfo = None
+