ia64/xen-unstable

view tools/python/xen/xend/server/XMLRPCServer.py @ 12241:5a291d87c334

[XEND] Make sure lookups cause a refresh so xm list gets the latest
info.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Nov 03 11:29:16 2006 +0000 (2006-11-03)
parents 5165aa656363
children ec4f43a4730f
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
16 # Copyright (C) 2006 XenSource Ltd.
17 #============================================================================
19 import types
20 import xmlrpclib
21 from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
23 from xen.xend import XendDomain, XendDomainInfo, XendNode
24 from xen.xend import XendLogging, XendDmesg
25 from xen.xend.XendClient import XML_RPC_SOCKET
26 from xen.xend.XendLogging import log
27 from xen.xend.XendAPI import XendAPI
28 from xen.xend.XendError import XendInvalidDomain
30 # vcpu_avail is a long and is not needed by the clients. It's far easier
31 # to just remove it then to try and marshal the long.
32 def fixup_sxpr(sexpr):
33 ret = []
34 for k in sexpr:
35 if type(k) in (types.ListType, types.TupleType):
36 if len(k) != 2 or k[0] != 'vcpu_avail':
37 ret.append(fixup_sxpr(k))
38 else:
39 ret.append(k)
40 return ret
42 def lookup(domid):
43 info = XendDomain.instance().domain_lookup(domid)
44 if not info:
45 raise XendInvalidDomain(str(domid))
46 return info
48 def dispatch(domid, fn, args):
49 info = lookup(domid)
50 return getattr(info, fn)(*args)
52 def domain(domid, full = 0):
53 info = lookup(domid)
54 return fixup_sxpr(info.sxpr(not full))
56 def domains(detail=1, full = 0):
57 if detail < 1:
58 return XendDomain.instance().list_names()
59 else:
60 domains = XendDomain.instance().list_sorted()
61 return map(lambda dom: fixup_sxpr(dom.sxpr(not full)), domains)
63 def domain_create(config):
64 info = XendDomain.instance().domain_create(config)
65 return fixup_sxpr(info.sxpr())
67 def domain_restore(src):
68 info = XendDomain.instance().domain_restore(src)
69 return fixup_sxpr(info.sxpr())
71 def get_log():
72 f = open(XendLogging.getLogFilename(), 'r')
73 try:
74 return f.read()
75 finally:
76 f.close()
78 methods = ['device_create', 'device_configure',
79 'destroyDevice','getDeviceSxprs',
80 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
81 'send_sysrq', 'getVCPUInfo', 'waitForDevices',
82 'getRestartCount']
84 exclude = ['domain_create', 'domain_restore']
86 class XMLRPCServer:
87 def __init__(self, use_tcp=False, host = "localhost", port = 8006,
88 path = XML_RPC_SOCKET):
89 self.use_tcp = use_tcp
90 self.port = port
91 self.host = host
92 self.path = path
94 self.ready = False
95 self.running = True
96 self.xenapi = XendAPI()
98 def run(self):
99 if self.use_tcp:
100 self.server = TCPXMLRPCServer((self.host, self.port),
101 logRequests = False)
102 else:
103 self.server = UnixXMLRPCServer(self.path, logRequests = False)
105 # Register Xen API Functions
106 # -------------------------------------------------------------------
107 # exportable functions are ones that do not begin with '_'
108 # and has the 'api' attribute.
110 for meth_name in dir(self.xenapi):
111 meth = getattr(self.xenapi, meth_name)
112 if meth_name[0] != '_' and callable(meth) and hasattr(meth, 'api'):
113 self.server.register_function(meth, getattr(meth, 'api'))
115 # Legacy deprecated xm xmlrpc api
116 # --------------------------------------------------------------------
118 # Functions in XendDomainInfo
119 for name in methods:
120 fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name)
121 self.server.register_function(fn, "xend.domain.%s" % name)
123 inst = XendDomain.instance()
125 for name in dir(inst):
126 fn = getattr(inst, name)
127 if name.startswith("domain_") and callable(fn):
128 if name not in exclude:
129 self.server.register_function(fn, "xend.domain.%s" % name[7:])
131 # Functions in XendNode and XendDmesg
132 for type, lst, n in [(XendNode, ['info'], 'node'),
133 (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
134 inst = type.instance()
135 for name in lst:
136 self.server.register_function(getattr(inst, name),
137 "xend.%s.%s" % (n, name))
139 # A few special cases
140 self.server.register_function(domain, 'xend.domain')
141 self.server.register_function(domains, 'xend.domains')
142 self.server.register_function(get_log, 'xend.node.log')
143 self.server.register_function(domain_create, 'xend.domain.create')
144 self.server.register_function(domain_restore, 'xend.domain.restore')
146 self.server.register_introspection_functions()
147 self.ready = True
149 # Custom runloop so we can cleanup when exiting.
150 # -----------------------------------------------------------------
151 try:
152 self.server.socket.settimeout(1.0)
153 while self.running:
154 self.server.handle_request()
155 finally:
156 self.cleanup()
158 def cleanup(self):
159 log.debug("XMLRPCServer.cleanup()")
161 def shutdown(self):
162 self.running = False
163 self.ready = False