source: trunk/packages/sipb-xen-remote-server/files/usr/sbin/sipb-xen-remote-listvms @ 538

Last change on this file since 538 was 538, checked in by y_z, 16 years ago

added sipb-xen-remote-listvms to aggregate results from multiple vm servers

  • Property svn:executable set to *
File size: 3.1 KB
Line 
1#!/usr/bin/env python2.5
2
3"""
4Collates the results of listvms from multiple VM servers.  Part of the xvm
5suite.
6"""
7
8from itertools import chain
9from subprocess import CalledProcessError, PIPE, Popen
10from sys import argv
11
12###
13
14import compiler
15
16class Unsafe_Source_Error(Exception):
17    def __init__(self,error,descr = None,node = None):
18        self.error = error
19        self.descr = descr
20        self.node = node
21        self.lineno = getattr(node,"lineno",None)
22       
23    def __repr__(self):
24        return "Line %d.  %s: %s" % (self.lineno, self.error, self.descr)
25    __str__ = __repr__   
26           
27class SafeEval(object):
28   
29    def visit(self, node,**kw):
30        cls = node.__class__
31        meth = getattr(self,'visit'+cls.__name__,self.default)
32        return meth(node, **kw)
33           
34    def default(self, node, **kw):
35        for child in node.getChildNodes():
36            return self.visit(child, **kw)
37           
38    visitExpression = default
39   
40    def visitConst(self, node, **kw):
41        return node.value
42
43    def visitDict(self,node,**kw):
44        return dict([(self.visit(k),self.visit(v)) for k,v in node.items])
45       
46    def visitTuple(self,node, **kw):
47        return tuple(self.visit(i) for i in node.nodes)
48       
49    def visitList(self,node, **kw):
50        return [self.visit(i) for i in node.nodes]
51
52class SafeEvalWithErrors(SafeEval):
53
54    def default(self, node, **kw):
55        raise Unsafe_Source_Error("Unsupported source construct",
56                                node.__class__,node)
57           
58    def visitName(self,node, **kw):
59        if node.name == 'None': return None
60        raise Unsafe_Source_Error("Strings must be quoted",
61                                 node.name, node)
62                                 
63    # Add more specific errors if desired
64           
65def safe_eval(source, fail_on_error = True):
66    if source.strip() == '': return None
67    walker = fail_on_error and SafeEvalWithErrors() or SafeEval()
68    try:
69        ast = compiler.parse(source,"eval")
70    except SyntaxError, err:
71        raise
72    try:
73        return walker.visit(ast)
74    except Unsafe_Source_Error, err:
75        raise
76
77###
78
79def run(cmd):
80  """
81  Run the given command (a list of program and argument strings) and return the
82  stdout as a string, raising a CalledProcessError if the program exited with a
83  non-zero status.
84  """
85  p = Popen(cmd, stdout=PIPE)
86  stdout = p.communicate()[0]
87  if p.returncode != 0: raise CalledProcessError(p.returncode, cmd)
88  return stdout
89
90def main(argv):
91  # Query each of the server for their VMs.
92  # run('kinit -k host/sipb-vm-58.mit.edu'.split())
93  # TODO get `servers` from a real list of all the VM hosts (instead of
94  # hardcoding the list here)
95  servers = [ 'black-mesa.mit.edu', 'sx-blade-2.mit.edu' ]
96  # XXX
97  results = [ safe_eval(run(['remctl', server, 'remote', 'web', 'listvms'] + argv[1:]))
98              for server in servers ]
99  results = filter( lambda x: x is not None, results )
100
101  # Merge the results and print.
102  merged = {}
103  for result in results: merged.update(result)
104  print merged
105  print '.'
106
107if __name__ == '__main__':
108  main(argv)
109
110# vim:et:sw=2:ts=2
Note: See TracBrowser for help on using the repository browser.