From: Yang Zhang Date: Fri, 23 May 2008 18:23:30 +0000 (-0400) Subject: added sipb-xen-remote-listvms to aggregate results from multiple vm servers X-Git-Tag: sipb-xen-remote-server/0.2~26 X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-remote.git/commitdiff_plain/d81e1374cf40cfe2cf98bd4264e63e8d43aaf912 added sipb-xen-remote-listvms to aggregate results from multiple vm servers svn path=/trunk/packages/sipb-xen-remote-server/; revision=538 --- diff --git a/files/etc/remctl/conf.d/sipb-xen-web b/files/etc/remctl/conf.d/sipb-xen-web index f79ebbf..eff5884 100644 --- a/files/etc/remctl/conf.d/sipb-xen-web +++ b/files/etc/remctl/conf.d/sipb-xen-web @@ -4,4 +4,4 @@ web lvrename /usr/sbin/sipb-xen-remote-proxy-web /etc/remctl/acl/web web lvresize /usr/sbin/sipb-xen-remote-proxy-web /etc/remctl/acl/web web lvcopy /usr/sbin/sipb-xen-remote-proxy-web /etc/remctl/acl/web web vmboot /usr/sbin/sipb-xen-remote-proxy-web /etc/remctl/acl/web -web listvms /usr/sbin/sipb-xen-remote-proxy-web /etc/remctl/acl/web +web listvms /usr/sbin/sipb-xen-remote-listvms /etc/remctl/acl/web diff --git a/files/usr/sbin/sipb-xen-remote-listvms b/files/usr/sbin/sipb-xen-remote-listvms new file mode 100755 index 0000000..4f16a98 --- /dev/null +++ b/files/usr/sbin/sipb-xen-remote-listvms @@ -0,0 +1,110 @@ +#!/usr/bin/env python2.5 + +""" +Collates the results of listvms from multiple VM servers. Part of the xvm +suite. +""" + +from itertools import chain +from subprocess import CalledProcessError, PIPE, Popen +from sys import argv + +### + +import compiler + +class Unsafe_Source_Error(Exception): + def __init__(self,error,descr = None,node = None): + self.error = error + self.descr = descr + self.node = node + self.lineno = getattr(node,"lineno",None) + + def __repr__(self): + return "Line %d. %s: %s" % (self.lineno, self.error, self.descr) + __str__ = __repr__ + +class SafeEval(object): + + def visit(self, node,**kw): + cls = node.__class__ + meth = getattr(self,'visit'+cls.__name__,self.default) + return meth(node, **kw) + + def default(self, node, **kw): + for child in node.getChildNodes(): + return self.visit(child, **kw) + + visitExpression = default + + def visitConst(self, node, **kw): + return node.value + + def visitDict(self,node,**kw): + return dict([(self.visit(k),self.visit(v)) for k,v in node.items]) + + def visitTuple(self,node, **kw): + return tuple(self.visit(i) for i in node.nodes) + + def visitList(self,node, **kw): + return [self.visit(i) for i in node.nodes] + +class SafeEvalWithErrors(SafeEval): + + def default(self, node, **kw): + raise Unsafe_Source_Error("Unsupported source construct", + node.__class__,node) + + def visitName(self,node, **kw): + if node.name == 'None': return None + raise Unsafe_Source_Error("Strings must be quoted", + node.name, node) + + # Add more specific errors if desired + +def safe_eval(source, fail_on_error = True): + if source.strip() == '': return None + walker = fail_on_error and SafeEvalWithErrors() or SafeEval() + try: + ast = compiler.parse(source,"eval") + except SyntaxError, err: + raise + try: + return walker.visit(ast) + except Unsafe_Source_Error, err: + raise + +### + +def run(cmd): + """ + Run the given command (a list of program and argument strings) and return the + stdout as a string, raising a CalledProcessError if the program exited with a + non-zero status. + """ + p = Popen(cmd, stdout=PIPE) + stdout = p.communicate()[0] + if p.returncode != 0: raise CalledProcessError(p.returncode, cmd) + return stdout + +def main(argv): + # Query each of the server for their VMs. + # run('kinit -k host/sipb-vm-58.mit.edu'.split()) + # TODO get `servers` from a real list of all the VM hosts (instead of + # hardcoding the list here) + servers = [ 'black-mesa.mit.edu', 'sx-blade-2.mit.edu' ] + # XXX + results = [ safe_eval(run(['remctl', server, 'remote', 'web', 'listvms'] + argv[1:])) + for server in servers ] + results = filter( lambda x: x is not None, results ) + + # Merge the results and print. + merged = {} + for result in results: merged.update(result) + print merged + print '.' + +if __name__ == '__main__': + main(argv) + +# vim:et:sw=2:ts=2