border: 0;
}
-
+#nodes {
+ width: 720px;
+}
+#nodes th, #nodes td {
+ text-align: left;
+}
+#nodes td {
+ width: 50px;
+}
/* Footer */
#footer
--- /dev/null
+#!/usr/bin/python
+
+import web
+import web.cluster
+
+class Content(web.Content):
+ def __init__(self, name):
+ web.Content.__init__(self, name)
+
+ self.cluster = web.cluster.Cluster("minerva.ipfire.org")
+
+ def __call__(self, lang):
+ ret = "<h3>Cluster Monitoring</h4>"
+
+ ret += """<script type="text/javascript">
+ nodes = new Array();
+
+ update = function() {
+ $.getJSON("http://www.ipfire.org/rpc.py", { type: "cluster" },
+ function(data) {
+ $.each(data.nodes, function(i, node) {
+ var nodeid = node.hostname.replace(".", "").replace(".", "");
+
+ nodes[nodeid] = true;
+
+ if ($("#" + nodeid).length) {
+ $("#" + nodeid + "_jobs").html(node.jobs);
+ } else {
+ row = "<tr id=\\"" + nodeid + "\\" class=\\"node\\">";
+ row += " <td id=\\"" + nodeid + "_hostname\\">" + node.hostname + "</td>";
+ row += " <td id=\\"" + nodeid + "_arch\\">" + node.arch + "</td>";
+ row += " <td><span id=\\"" + nodeid + "_loadbar\\"></span></td>";
+ row += " <td id=\\"" + nodeid + "_jobs\\">" + node.jobs + "</td>";
+ row += "</tr>";
+ $("#nodes").append(row);
+ }
+ $("#" + nodeid + "_loadbar").progressBar(node.load, {showText: false});
+ });
+ $("#loadbar").progressBar(data.cluster.load);
+ for (var nodeid in nodes) {
+ if (nodes[nodeid] == false) {
+ $("#" + nodeid).remove();
+ nodes.pop(nodeid);
+ } else {
+ nodes[nodeid] = false;
+ }
+ }
+ });
+ }
+
+ $(document).ready(function(){
+ // Init loadbar
+ $("#loadbar").progressBar();
+
+ update();
+ setInterval("update()", 2500);
+ })
+ </script>"""
+
+ ret += """<p>Cluster's load: <span id="loadbar"></span></p>
+ <table id="nodes">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Arch</th>
+ <th>Load</th>
+ <th>Jobs</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+ </table>"""
+
+ return ret
+
+Sidebar = web.Sidebar
--- /dev/null
+#!/usr/bin/python
+
+import cgi
+import simplejson as json
+
+import web.cluster
+
+
+form = cgi.FieldStorage()
+
+if form.getfirst("type") == "cluster":
+ nodes = []
+ ret = {}
+ cluster = web.cluster.Cluster("minerva.ipfire.org")
+ for node in cluster.nodes:
+ tmp = { "hostname" : node.hostname,
+ "address" : node.address,
+ "arch" : node.arch,
+ "jobs" : node.jobs,
+ "load" : node.load,
+ "speed" : node.speed, }
+
+ nodes.append(tmp)
+ ret["nodes"] = nodes
+ ret["cluster"] = { "load" : cluster.load, }
+ print json.dumps(ret, sort_keys=True, indent=4)
+
--- /dev/null
+#!/usr/bin/python
+
+import telnetlib
+
+class Node(object):
+ def __init__(self, hostname, address, arch, speed, jobs, load):
+ self.hostname = hostname
+ self.address = address
+ self.arch = arch
+ self.speed = speed
+ self.jobs = jobs
+ self.load = int(load) / 10 # in percent
+
+ def __str__(self):
+ return self.hostname
+
+ def __repr__(self):
+ return "<Node %s>" % self.hostname
+
+ def print_node(self):
+ print "Hostname : %s" % self.hostname
+ print " Address: %s" % self.address
+ print " Arch : %s" % self.arch
+ print " Speed : %s" % self.speed
+ print " Jobs : %s" % self.jobs
+ print " Load : %s" % self.load
+
+class Cluster(object):
+ def __init__(self, scheduler, port=8766):
+ self.scheduler = scheduler
+ self.port = port
+
+ self._nodes = None
+
+ def command(self, command):
+ connection = telnetlib.Telnet(self.scheduler, self.port)
+ connection.read_until("quit.\n")
+ connection.write("%s\nquit\n" % command)
+ return connection.read_until("200 done").split("\n")
+
+ @property
+ def load(self):
+ load = 0
+ for node in self.nodes:
+ load += node.load
+ load /= len(self.nodes)
+ return load
+
+ @property
+ def nodes(self):
+ if self._nodes:
+ return self._nodes
+ ret = []
+ data = self.command("listcs")
+ for line in data:
+ if not line.startswith(" "): continue
+ (a, hostname, address, arch, speed, jobs, load) = line.split(" ")
+ address = address.strip("()")
+ arch = arch.strip("[]")
+ speed = speed.split("=")[1]
+ jobs = jobs.split("=")[1]
+ load = load.split("=")[1]
+ ret.append(Node(hostname, address, arch, speed, jobs, load))
+ self._nodes = ret
+ return ret
+
+if __name__ == "__main__":
+ cluster = Cluster("minerva.ipfire.org")
+ print cluster.command("listcs")
+ for node in cluster.nodes:
+ node.print_node()