ia64/xen-unstable

view tools/python/xen/util/xmlrpclib2.py @ 19848:5839491bbf20

[IA64] replace MAX_VCPUS with d->max_vcpus where necessary.

don't use MAX_VCPUS, and use vcpu::max_vcpus.
The changeset of 2f9e1348aa98 introduced max_vcpus to allow more vcpus
per guest. This patch is ia64 counter part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 11:26:05 2009 +0900 (2009-06-29)
parents b7c1b412c472
children
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 Inc.
17 #============================================================================
19 """
20 An enhanced XML-RPC client/server interface for Python.
21 """
23 import re
24 import fcntl
25 from types import *
28 from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
29 import SocketServer
30 import xmlrpclib, socket, os, stat
32 import mkdir
34 from xen.web import connection
35 from xen.xend.XendLogging import log
37 #
38 # Convert all integers to strings as described in the Xen API
39 #
42 def stringify(value):
43 if isinstance(value, long) or \
44 (isinstance(value, int) and not isinstance(value, bool)):
45 return str(value)
46 elif isinstance(value, dict):
47 new_value = {}
48 for k, v in value.items():
49 new_value[stringify(k)] = stringify(v)
50 return new_value
51 elif isinstance(value, (tuple, list)):
52 return [stringify(v) for v in value]
53 else:
54 return value
57 # We're forced to subclass the RequestHandler class so that we can work around
58 # some bugs in Keep-Alive handling and also enabled it by default
59 class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
60 protocol_version = "HTTP/1.1"
62 def __init__(self, hosts_allowed, request, client_address, server):
63 self.hosts_allowed = hosts_allowed
64 SimpleXMLRPCRequestHandler.__init__(self, request, client_address,
65 server)
67 # this is inspired by SimpleXMLRPCRequestHandler's do_POST but differs
68 # in a few non-trivial ways
69 # 1) we never generate internal server errors. We let the exception
70 # propagate so that it shows up in the Xend debug logs
71 # 2) we don't bother checking for a _dispatch function since we don't
72 # use one
73 def do_POST(self):
74 addrport = self.client_address
75 if not connection.hostAllowed(addrport, self.hosts_allowed):
76 self.connection.shutdown(1)
77 return
79 data = self.rfile.read(int(self.headers["content-length"]))
80 rsp = self.server._marshaled_dispatch(data)
82 self.send_response(200)
83 self.send_header("Content-Type", "text/xml")
84 self.send_header("Content-Length", str(len(rsp)))
85 self.end_headers()
87 self.wfile.write(rsp)
88 self.wfile.flush()
89 if self.close_connection == 1:
90 self.connection.shutdown(1)
92 # This is a base XML-RPC server for TCP. It sets allow_reuse_address to
93 # true, and has an improved marshaller that logs and serializes exceptions.
95 class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
96 allow_reuse_address = True
98 def __init__(self, addr, allowed, xenapi, requestHandler=None,
99 logRequests = 1):
100 self.xenapi = xenapi
102 if requestHandler is None:
103 requestHandler = XMLRPCRequestHandler
104 SimpleXMLRPCServer.__init__(self, addr,
105 (lambda x, y, z:
106 requestHandler(allowed, x, y, z)),
107 logRequests)
109 flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
110 flags |= fcntl.FD_CLOEXEC
111 fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
113 def get_request(self):
114 (client, addr) = SimpleXMLRPCServer.get_request(self)
115 flags = fcntl.fcntl(client.fileno(), fcntl.F_GETFD)
116 flags |= fcntl.FD_CLOEXEC
117 fcntl.fcntl(client.fileno(), fcntl.F_SETFD, flags)
118 return (client, addr)
120 def _marshaled_dispatch(self, data, dispatch_method = None):
121 params, method = xmlrpclib.loads(data)
122 if False:
123 # Enable this block of code to exit immediately without sending
124 # a response. This allows you to test client-side crash handling.
125 import sys
126 sys.exit(1)
127 try:
128 if dispatch_method is not None:
129 response = dispatch_method(method, params)
130 else:
131 response = self._dispatch(method, params)
133 if self.xenapi and \
134 (response is None or
135 not isinstance(response, dict) or
136 'Status' not in response):
137 log.exception('Internal error handling %s: Invalid result %s',
138 method, response)
139 response = { "Status": "Failure",
140 "ErrorDescription":
141 ['INTERNAL_ERROR',
142 'Invalid result %s handling %s' %
143 (response, method)]}
145 # With either Unicode or normal strings, we can only transmit
146 # \t, \n, \r, \u0020-\ud7ff, \ue000-\ufffd, and \u10000-\u10ffff
147 # in an XML document. xmlrpclib does not escape these values
148 # properly, and then breaks when it comes to parse the document.
149 # To hack around this problem, we use repr here and exec above
150 # to transmit the string using Python encoding.
151 # Thanks to David Mertz <mertz@gnosis.cx> for the trick (buried
152 # in xml_pickle.py).
153 if isinstance(response, StringTypes):
154 response = repr(response)[1:-1]
156 response = (response,)
157 response = xmlrpclib.dumps(response,
158 methodresponse=1,
159 allow_none=1)
160 except Exception, exn:
161 try:
162 if self.xenapi:
163 if _is_not_supported(exn):
164 errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
165 else:
166 log.exception('Internal error handling %s', method)
167 errdesc = ['INTERNAL_ERROR', str(exn)]
169 response = xmlrpclib.dumps(
170 ({ "Status": "Failure",
171 "ErrorDescription": errdesc },),
172 methodresponse = 1)
173 else:
174 import xen.xend.XendClient
175 if isinstance(exn, xmlrpclib.Fault):
176 response = xmlrpclib.dumps(exn)
177 else:
178 log.exception('Internal error handling %s', method)
179 response = xmlrpclib.dumps(
180 xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
181 except:
182 log.exception('Internal error handling error')
184 return response
187 notSupportedRE = re.compile(r'method "(.*)" is not supported')
188 def _is_not_supported(exn):
189 try:
190 m = notSupportedRE.search(exn[0])
191 return m is not None
192 except:
193 return False
196 # This is a XML-RPC server that sits on a Unix domain socket.
197 # It implements proper support for allow_reuse_address by
198 # unlink()'ing an existing socket.
200 class UnixXMLRPCRequestHandler(XMLRPCRequestHandler):
201 def address_string(self):
202 try:
203 return XMLRPCRequestHandler.address_string(self)
204 except ValueError, e:
205 return self.client_address[:2]
207 class UnixXMLRPCServer(TCPXMLRPCServer):
208 address_family = socket.AF_UNIX
209 allow_address_reuse = True
211 def __init__(self, addr, allowed, xenapi, logRequests = 1):
212 mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
213 if self.allow_reuse_address and os.path.exists(addr):
214 os.unlink(addr)
216 TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
217 UnixXMLRPCRequestHandler, logRequests)