* [RFC] Xend XML-RPC Refactoring
@ 2006-01-31 21:25 Anthony Liguori
2006-01-31 21:36 ` Ronald G Minnich
2006-02-01 9:37 ` Daniel Veillard
0 siblings, 2 replies; 19+ messages in thread
From: Anthony Liguori @ 2006-01-31 21:25 UTC (permalink / raw)
To: xen-devel; +Cc: Jeremy Katz, Sean Dague, Ewan Mellor
Hi,
I wanted to give the list a heads up about something a number of us
discussed at the recent XenSummit.
We would like to simplify Xend by utilizing more of the standard Python
library and relying on less of our own code. The most obvious thing
here is the current S-Expression/HTTP RPC interface. We would like to
replace this with XML-RPC using Python's builtin support (xmlrpclib and
SimpleXMLRPCServer).
I've got some initial code and more details on the wiki
(http://wiki.xensource.com/xenwiki/Xend/XML-RPC). Early estimates are
that this would reduce the code in Xend by about 33% (5k slocs). We
would also like to standardize this XML-RPC interface so that
third-parties write apps to this interface without worrying about
massive breakage.
Thoughts?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-01-31 21:25 [RFC] Xend XML-RPC Refactoring Anthony Liguori
@ 2006-01-31 21:36 ` Ronald G Minnich
2006-01-31 21:47 ` Matt Sottile
` (2 more replies)
2006-02-01 9:37 ` Daniel Veillard
1 sibling, 3 replies; 19+ messages in thread
From: Ronald G Minnich @ 2006-01-31 21:36 UTC (permalink / raw)
To: Anthony Liguori
Cc: Jeremy Katz, Matt Sottile, xen-devel, Ewan Mellor, Sean Dague
Anthony Liguori wrote:
> Hi,
>
> I wanted to give the list a heads up about something a number of us
> discussed at the recent XenSummit.
>
> We would like to simplify Xend by utilizing more of the standard Python
> library and relying on less of our own code. The most obvious thing
> here is the current S-Expression/HTTP RPC interface. We would like to
> replace this with XML-RPC using Python's builtin support (xmlrpclib and
> SimpleXMLRPCServer).
>
> I've got some initial code and more details on the wiki
> (http://wiki.xensource.com/xenwiki/Xend/XML-RPC). Early estimates are
> that this would reduce the code in Xend by about 33% (5k slocs). We
> would also like to standardize this XML-RPC interface so that
> third-parties write apps to this interface without worrying about
> massive breakage.
I think moving from s-exp's to XML is a bad move. If you want, use your
s-expression library from LANL; it's used worldwide, and has done the
job for a lot of projects.
I know of at least one project that moved from XML to s-exp's, using our
library, because XML is just plain unwieldy.
thanks
ron
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-01-31 21:36 ` Ronald G Minnich
@ 2006-01-31 21:47 ` Matt Sottile
2006-01-31 21:58 ` Anthony Liguori
2006-02-01 9:53 ` Ewan Mellor
2 siblings, 0 replies; 19+ messages in thread
From: Matt Sottile @ 2006-01-31 21:47 UTC (permalink / raw)
To: Ronald G Minnich; +Cc: Jeremy Katz, xen-devel, Ewan Mellor, Sean Dague
For those who don't know the library Ron speaks of...
http://sexpr.sourceforge.net/
-m
On Jan 31, 2006, at 2:36 PM, Ronald G Minnich wrote:
> Anthony Liguori wrote:
>> Hi,
>> I wanted to give the list a heads up about something a number of
>> us discussed at the recent XenSummit.
>> We would like to simplify Xend by utilizing more of the standard
>> Python library and relying on less of our own code. The most
>> obvious thing here is the current S-Expression/HTTP RPC
>> interface. We would like to replace this with XML-RPC using
>> Python's builtin support (xmlrpclib and SimpleXMLRPCServer).
>> I've got some initial code and more details on the wiki (http://
>> wiki.xensource.com/xenwiki/Xend/XML-RPC). Early estimates are
>> that this would reduce the code in Xend by about 33% (5k slocs).
>> We would also like to standardize this XML-RPC interface so that
>> third-parties write apps to this interface without worrying about
>> massive breakage.
>
>
> I think moving from s-exp's to XML is a bad move. If you want, use
> your s-expression library from LANL; it's used worldwide, and has
> done the job for a lot of projects.
>
> I know of at least one project that moved from XML to s-exp's,
> using our library, because XML is just plain unwieldy.
>
> thanks
>
> ron
---
Matthew Sottile (matt@lanl.gov)
Advanced Computing Laboratory (CCS-1)
Los Alamos National Laboratory
Los Alamos, NM 87545
Phone: (505)665-6057
Web: http://ddma.lanl.gov/~matt/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-01-31 21:36 ` Ronald G Minnich
2006-01-31 21:47 ` Matt Sottile
@ 2006-01-31 21:58 ` Anthony Liguori
2006-02-01 9:53 ` Ewan Mellor
2 siblings, 0 replies; 19+ messages in thread
From: Anthony Liguori @ 2006-01-31 21:58 UTC (permalink / raw)
To: Ronald G Minnich
Cc: Jeremy Katz, Matt Sottile, xen-devel, Ewan Mellor, Sean Dague
Ronald G Minnich wrote:
> I think moving from s-exp's to XML is a bad move. If you want, use
> your s-expression library from LANL; it's used worldwide, and has done
> the job for a lot of projects.
Python supports XML-RPC out of the box. Using that code will remove 5k
lines of code from Xend.
With Python, all you have to do is register functions with the XML-RPC
handler and use a proxy object. We won't have to write any XML code at
all. I'm quite indifferent to XML/S-Expressions actually. It's just
about simplifying things.
Regards,
Anthony Liguori
> I know of at least one project that moved from XML to s-exp's, using
> our library, because XML is just plain unwieldy.
>
> thanks
>
> ron
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-01-31 21:25 [RFC] Xend XML-RPC Refactoring Anthony Liguori
2006-01-31 21:36 ` Ronald G Minnich
@ 2006-02-01 9:37 ` Daniel Veillard
1 sibling, 0 replies; 19+ messages in thread
From: Daniel Veillard @ 2006-02-01 9:37 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Jeremy Katz, xen-devel, Ewan Mellor, Sean Dague
On Tue, Jan 31, 2006 at 03:25:58PM -0600, Anthony Liguori wrote:
> Hi,
>
> I wanted to give the list a heads up about something a number of us
> discussed at the recent XenSummit.
>
> We would like to simplify Xend by utilizing more of the standard Python
> library and relying on less of our own code. The most obvious thing
> here is the current S-Expression/HTTP RPC interface. We would like to
> replace this with XML-RPC using Python's builtin support (xmlrpclib and
> SimpleXMLRPCServer).
>
> I've got some initial code and more details on the wiki
> (http://wiki.xensource.com/xenwiki/Xend/XML-RPC). Early estimates are
> that this would reduce the code in Xend by about 33% (5k slocs). We
> would also like to standardize this XML-RPC interface so that
> third-parties write apps to this interface without worrying about
> massive breakage.
>
> Thoughts?
Going to XML is fine by me, the only drawback I can think of is in term
of versatility and larger (but stabler) dependancies. To be a bit more
explicit on the first point if you pass an S-exp it's some kind of free
form function call, the caller may pass more arguments or a slightly different
set without breaking fundamentally the interface, the callee may still be able
to extract the set of informations he needs to prepare the call, the same
applies in terms of result set too. Think about the call gathering informations
about a running domain, version 4.0 of xen may return a superset of what 3.0
returns without harming 3.0 based clients, so there is clearly some
added flexibility compared to a normal RPC operation.
On the other hand being able to feeze a clear RPC based API would be a good
sign, that we know exactly how we intend to keep the APIs in the future.
And when it comes to the final API design, the current ones are IMHO too
name oriented when it comes to naming domains, I would really prefer the
final XML-RPC ones to be more id and uuid oriented, as I think they are
more safe (especially when one considers the rename capacity, this may lead to
numerous races between the time one client does the uuid -> name resolution
and the next name based next call).
thanks for starting this !
Daniel
--
Daniel Veillard | Red Hat http://redhat.com/
veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-01-31 21:36 ` Ronald G Minnich
2006-01-31 21:47 ` Matt Sottile
2006-01-31 21:58 ` Anthony Liguori
@ 2006-02-01 9:53 ` Ewan Mellor
2 siblings, 0 replies; 19+ messages in thread
From: Ewan Mellor @ 2006-02-01 9:53 UTC (permalink / raw)
To: Ronald G Minnich; +Cc: Jeremy Katz, xen-devel, Matt Sottile, Sean Dague
On Tue, Jan 31, 2006 at 02:36:43PM -0700, Ronald G Minnich wrote:
> Anthony Liguori wrote:
> >Hi,
> >
> >I wanted to give the list a heads up about something a number of us
> >discussed at the recent XenSummit.
> >
> >We would like to simplify Xend by utilizing more of the standard Python
> >library and relying on less of our own code. The most obvious thing
> >here is the current S-Expression/HTTP RPC interface. We would like to
> >replace this with XML-RPC using Python's builtin support (xmlrpclib and
> >SimpleXMLRPCServer).
> >
> >I've got some initial code and more details on the wiki
> >(http://wiki.xensource.com/xenwiki/Xend/XML-RPC). Early estimates are
> >that this would reduce the code in Xend by about 33% (5k slocs). We
> >would also like to standardize this XML-RPC interface so that
> >third-parties write apps to this interface without worrying about
> >massive breakage.
>
>
> I think moving from s-exp's to XML is a bad move. If you want, use your
> s-expression library from LANL; it's used worldwide, and has done the
> job for a lot of projects.
>
> I know of at least one project that moved from XML to s-exp's, using our
> library, because XML is just plain unwieldy.
Firstly, Anthony, apologies for not writing up the conversation that we
had at the Xen Summit. I am currently on vacation, and will write it up
when I'm back at work (though it looks like you've got most of it on the
wiki already).
On the subject of the proposed changes themselves -- the issue is not
just a replacement of s-expressions with XML, but with the whole
protocol layer with one based upon XML-RPC -- i.e. with standardised
marshalling as well, and often stub generation from an interface
definition too. This should mean that there's less code for people to write
when they wish to interface with Xend (as with Redhat's libvir or IBM's
in-house work) as XML-RPC libraries already exist for every mainstream
language, AFAIK. Yes, there is an s-expression library available from
LANL, but that only gets you half the advantages that moving to XML-RPC
would bring, as you would still have to implement the message dispatch
and argument demarshalling.
As Anthony says, a further advantage is inside Xend, where we can use
the existing SimpleXMLRPCServer to implement the server-side messaging
layer, significantly reducing the size of Xend.
Ewan.
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [RFC] Xend XML-RPC Refactoring
@ 2006-03-07 23:37 Ian Pratt
2006-03-08 0:07 ` Anthony Liguori
0 siblings, 1 reply; 19+ messages in thread
From: Ian Pratt @ 2006-03-07 23:37 UTC (permalink / raw)
To: Anthony Liguori; +Cc: xen-devel
> > We would like to simplify Xend by utilizing more of the standard
> > Python library and relying on less of our own code. The
> most obvious
> > thing here is the current S-Expression/HTTP RPC interface.
> We would
> > like to replace this with XML-RPC using Python's builtin support
> > (xmlrpclib and SimpleXMLRPCServer).
> >
> > I've got some initial code and more details on the wiki
> > (http://wiki.xensource.com/xenwiki/Xend/XML-RPC). Early
> estimates are
> > that this would reduce the code in Xend by about 33% (5k
> slocs). We
> > would also like to standardize this XML-RPC interface so that
> > third-parties write apps to this interface without worrying about
> > massive breakage.
Anothony, have you an updated version of this patch? How much testing
has it had?
Should we be looking to get it in prior to 3.0.2? In principle I think
this would be a good thing, but we may have left it too late. I expect
2.6.16 final will be out fairly soon, and then we'll want to be pushing
a release out in the following week or so.
Thanks,
Ian
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-07 23:37 Ian Pratt
@ 2006-03-08 0:07 ` Anthony Liguori
2006-03-11 20:55 ` Ewan Mellor
0 siblings, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2006-03-08 0:07 UTC (permalink / raw)
To: Ian Pratt; +Cc: xen-devel
[-- Attachment #1: Type: text/plain, Size: 1466 bytes --]
Ian Pratt wrote:
>>> would also like to standardize this XML-RPC interface so that
>>> third-parties write apps to this interface without worrying about
>>> massive breakage.
>>>
>
> Anothony, have you an updated version of this patch? How much testing
> has it had?
>
Yes, I sent those to xen-devel just the other day. They are attached to
this note for your convenience.
I've done a bunch of testing (via xm-test) on x86-32 and limited on x86-64.
> Should we be looking to get it in prior to 3.0.2?
I think the patch that adds an XML-RPC interface to Xend ought to go
in. It doesn't change any of the normally executed code paths for xm
and only listens on a domain socket. This would give us a chance to
start supporting XML-RPC in libvirt and to bang on the interface a
little more.
If 3.0.2 is going out shortly, I'd say hold off on the second patch
until after it goes out. There's no real benefit with the second patch
other than getting more people to exercise the code so it's probably not
worth taking the risk (although as I said, I've tested it pretty heavily).
> In principle I think
> this would be a good thing, but we may have left it too late. I expect
> 2.6.16 final will be out fairly soon, and then we'll want to be pushing
> a release out in the following week or so.
>
I split up the patches specifically with this in mind. The first one
should be very low-risk.
Regards,
Anthony Liguori
> Thanks,
> Ian
>
[-- Attachment #2: xend-xmlrpc-9017.diff --]
[-- Type: text/plain, Size: 9840 bytes --]
# HG changeset patch
# User anthony@rhesis.austin.ibm.com
# Node ID 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
# Parent c369d960f96ba4fd7c9c6920cfa60c46a764323c
Add an XML-RPC interface to Xend.
This introduces a enhanced client library (xmlrpclib2) that supports XML-RPC
over a domain socket (also working around a bug in Python's handling of NIL).
This also introduces a new server that runs along side of the existing
S-Expression/HTTP server.
This changeset makes no change to the normal operation of Xend. xm still goes
through S-Expression/HTTP -- there's just another option for interacting with
Xend.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 16:45:20 2006
+++ b/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 22:08:47 2006
@@ -51,6 +51,7 @@
from xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
+from XMLRPCServer import XMLRPCServer
xroot = XendRoot.instance()
@@ -113,4 +114,5 @@
path = xroot.get_xend_unix_path()
log.info('unix path=' + path)
servers.add(UnixHttpServer(path=path, root=root))
+ servers.add(XMLRPCServer())
return servers
diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py
--- /dev/null Tue Feb 28 16:45:20 2006
+++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 2006
@@ -0,0 +1,109 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
+#============================================================================
+
+"""
+An enhanced XML-RPC client/server interface for Python.
+"""
+
+from httplib import HTTPConnection, HTTP
+from xmlrpclib import Transport
+from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
+import xmlrpclib, socket, os, traceback
+
+# A new ServerProxy that also supports httpu urls. An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2. This problem needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+ def connect(self):
+ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+ _connection_class = HTTPUnixConnection
+
+class UnixTransport(Transport):
+ def request(self, host, handler, request_body, verbose=0):
+ self.__handler = handler
+ return Transport.request(self, host, '/RPC2', request_body, verbose)
+ def make_connection(self, host):
+ return HTTPUnix(self.__handler)
+
+class ServerProxy(xmlrpclib.ServerProxy):
+ def __init__(self, uri, transport=None, encoding=None, verbose=0,
+ allow_none=1):
+ if transport == None:
+ protocol = uri.split(':')[0]
+ if protocol == 'httpu':
+ uri = 'http:' + ':'.join(uri.split(':')[1:])
+ transport = UnixTransport()
+ xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+ verbose, allow_none)
+
+# This is a base XML-RPC server for TCP. It sets allow_reuse_address to
+# true, and has an improved marshaller that serializes unknown exceptions
+# with full traceback information.
+
+class TCPXMLRPCServer(SimpleXMLRPCServer):
+ allow_reuse_address = True
+
+ def _marshaled_dispatch(self, data, dispatch_method = None):
+ params, method = xmlrpclib.loads(data)
+ try:
+ if dispatch_method is not None:
+ response = dispatch_method(method, params)
+ else:
+ response = self._dispatch(method, params)
+
+ response = (response,)
+ response = xmlrpclib.dumps(response,
+ methodresponse=1,
+ allow_none=1)
+ except xmlrpclib.Fault, fault:
+ response = xmlrpclib.dumps(exc)
+ except:
+ response = xmlrpclib.dumps(
+ xmlrpclib.Fault(1, traceback.format_exc())
+ )
+
+ return response
+
+# This is a XML-RPC server that sits on a Unix domain socket.
+# It implements proper support for allow_reuse_address by
+# unlink()'ing an existing socket.
+
+class UnixXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+ def address_string(self):
+ try:
+ return SimpleXMLRPCRequestHandler.address_string(self)
+ except ValueError, e:
+ return self.client_address[:2]
+
+class UnixXMLRPCServer(TCPXMLRPCServer):
+ address_family = socket.AF_UNIX
+
+ def __init__(self, addr, requestHandler=UnixXMLRPCRequestHandler,
+ logRequests=1):
+ if self.allow_reuse_address:
+ try:
+ os.unlink(addr)
+ except OSError, exc:
+ pass
+ TCPXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null Tue Feb 28 16:45:20 2006
+++ b/tools/python/xen/xend/server/XMLRPCServer.py Tue Feb 28 22:08:47 2006
@@ -0,0 +1,97 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
+#============================================================================
+
+from xen.xend import (XendDomain, XendDomainInfo, XendNode,
+ XendLogging, XendDmesg)
+from xen.util.xmlrpclib2 import UnixXMLRPCServer
+
+def lookup(domid):
+ return XendDomain.instance().domain_lookup_by_name_or_id(domid)
+
+def dispatch(domid, fn, args):
+ info = lookup(domid)
+ return getattr(info, fn)(*args)
+
+def domain(domid):
+ info = lookup(domid)
+ return info.sxpr()
+
+def domains(detail=1):
+ if detail < 1:
+ return XendDomain.instance().list_names()
+ else:
+ domains = XendDomain.instance().list_sorted()
+ return map(lambda dom: dom.sxpr(), domains)
+
+def domain_create(config):
+ info = XendDomain.instance().domain_create(config)
+ return info.sxpr()
+
+def domain_restore(src):
+ info = XendDomain.instance().domain_restore(src)
+ return info.sxpr()
+
+def get_log():
+ f = open(XendLogging.getLogFilename(), 'r')
+ ret = f.read()
+ f.close()
+ return ret
+
+methods = ['device_create', 'destroyDevice', 'getDeviceSxprs',
+ 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
+ 'send_sysrq', 'getVCPUInfo', 'waitForDevices']
+
+exclude = ['domain_create', 'domain_restore']
+
+class XMLRPCServer:
+ def __init__(self):
+ self.ready = False
+
+ def run(self):
+ self.server = UnixXMLRPCServer("/var/run/xend-xmlrpc.sock")
+
+ # Functions in XendDomainInfo
+ for name in methods:
+ fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name)
+ self.server.register_function(fn, "xend.domain.%s" % name)
+
+ # Functions in XendDomain
+ inst = XendDomain.instance()
+ for name in dir(inst):
+ fn = getattr(inst, name)
+ if name.startswith("domain_") and callable(fn):
+ if name not in exclude:
+ self.server.register_function(fn, "xend.domain.%s" % name[7:])
+
+ # Functions in XendNode and XendDmesg
+ for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'),
+ (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
+ inst = type.instance()
+ for name in lst:
+ self.server.register_function(getattr(inst, name),
+ "xend.%s.%s" % (n, name))
+
+ # A few special cases
+ self.server.register_function(domain, 'xend.domain')
+ self.server.register_function(domains, 'xend.domains')
+ self.server.register_function(get_log, 'xend.node.log')
+ self.server.register_function(domain_create, 'xend.domain.create')
+ self.server.register_function(domain_restore, 'xend.domain.restore')
+
+ self.server.register_introspection_functions()
+ self.ready = True
+ self.server.serve_forever()
[-- Attachment #3: xend-xmlrpc-9018.diff --]
[-- Type: text/plain, Size: 19947 bytes --]
# HG changeset patch
# User anthony@rhesis.austin.ibm.com
# Node ID 951f0d589164e0cffc785cf23d82118b3e0b0495
# Parent 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
This changeset is a major refactoring of XendClient to use the XML-RPC
transport for Xend and also to make a few changes to xm so that it knows about
the new Exception types.
xm-test has been passing with this changeset for the past couple of weeks.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xend/XendClient.py Tue Feb 28 22:10:14 2006
@@ -16,22 +16,8 @@
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
#============================================================================
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
-
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
-
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
- UnixXendClientProtocol, \
- XendError
+import types, sxp
+from xen.util.xmlrpclib2 import ServerProxy
def fileof(val):
"""Converter for passing configs or other 'large' data.
@@ -39,377 +25,120 @@
Assumes a string is a file name and passes its contents.
"""
if isinstance(val, types.ListType):
- return sxp.to_string(val)
+ return val
if isinstance(val, types.StringType):
- return file(val)
- if hasattr(val, 'readlines'):
- return val
- raise XendError('cannot convert value')
-
-class URL:
- """A URL.
- """
-
- def __init__(self, proto='http', host='localhost', port=None, path='', query=None, frag=None):
- self.proto = proto
- self.host = host
- if port: port = int(port)
- self.port = port
- self.path = path
- self.query = query
- self.frag = frag
-
- def url(self):
- """Get the full URL string including protocol, location and the full path.
- """
- return self.proto + '://' + self.location() + self.fullpath()
-
- def location(self):
- """Get the location part of the URL, including host and port, if present.
- """
- if self.port:
- return self.host + ':' + str(self.port)
- else:
- return self.host
-
- def fullpath(self):
- """Get the full path part of the URL, including query and fragment if present.
- """
- u = [ self.path ]
- if self.query:
- u.append('?')
- u.append(self.query)
- if self.frag:
- u.append('#')
- u.append(self.frag)
- return ''.join(u)
-
- def relative(self, path='', query=None, frag=None):
- """Create a URL relative to this one.
- """
- return URL(proto=self.proto,
- host=self.host,
- port=self.port,
- path=self.path + path,
- query=query,
- frag=frag)
+ return sxp.from_string(val)
+ raise ValueError('invalid value for config')
class Xend:
"""Client interface to Xend.
"""
- """Default location of the xend server."""
- SRV_DEFAULT = "localhost:8000"
-
- """Environment variable to set the location of xend."""
- SRV_VAR = "XEND"
-
- """Default path to the xend root on the server."""
- ROOT_DEFAULT = "/xend/"
-
- """Environment variable to set the xend root path."""
- ROOT_VAR = "XEND_ROOT"
-
def __init__(self, client=None, srv=None, root=None):
- """Create a xend client interface.
- If the client protocol is not specified, the default
- is to use a synchronous protocol.
-
- @param client: client protocol to use
- @param srv: server host, and optional port (format host:port)
- @param root: xend root path on the server
- """
- if client is None:
- client = HttpXendClientProtocol()
- self.client = client
- self.bind(srv, root)
-
- def default_server(self):
- """Get the default location of the xend server.
- """
- return os.getenv(self.SRV_VAR, self.SRV_DEFAULT)
-
- def default_root(self):
- """Get the default root path on the xend server.
- """
- return os.getenv(self.ROOT_VAR, self.ROOT_DEFAULT)
-
- def bind(self, srv=None, root=None):
- """Bind to a given server.
-
- @param srv: server location (host:port)
- @param root: xend root path on the server
- """
- if srv is None: srv = self.default_server()
- if root is None: root = self.default_root()
- if not root.endswith('/'): root += '/'
- (host, port) = srv.split(':', 1)
- self.url = URL(host=host, port=port, path=root)
-
- def xendGet(self, url, args=None):
- return self.client.xendGet(url, args)
-
- def xendPost(self, url, data):
- return self.client.xendPost(url, data)
-
- def nodeurl(self, id=''):
- return self.url.relative('node/' + str(id))
-
- def domainurl(self, id=''):
- return self.url.relative('domain/' + str(id))
-
- def deviceurl(self, id=''):
- return self.url.relative('device/' + str(id))
-
- def vneturl(self, id=''):
- return self.url.relative('vnet/' + str(id))
-
- def xend(self):
- return self.xendGet(self.url)
+ self.srv = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
def xend_node(self):
- return self.xendGet(self.nodeurl())
+ return self.srv.xend.node.info()
- def xend_node_shutdown(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'shutdown'})
-
- def xend_node_restart(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'reboot'})
-
def xend_node_get_dmesg(self):
- return self.xendGet(self.nodeurl('dmesg'))
+ return self.srv.xend.node.dmesg.info()
def xend_node_clear_dmesg(self):
- return self.xendPost(self.nodeurl('dmesg'),
- {'op' : 'clear' } )
+ return self.srv.xend.node.dmesg.clear()
def xend_node_log(self):
- return self.xendGet(self.nodeurl('log'))
+ return self.srv.xend.node.log()
def xend_node_cpu_bvt_slice_set(self, ctx_allow):
- return self.xendPost(self.nodeurl(),
- {'op' : 'cpu_bvt_slice_set',
- 'ctx_allow' : ctx_allow })
+ return self.srv.xend.node.cpu_bvt_slice_set(ctx_allow)
def xend_domains(self):
- return self.xendGet(self.domainurl())
+ return self.srv.xend.domains(0)
def xend_list_domains(self):
- return self.xendGet(self.domainurl(), {'detail': '1'})
+ return self.srv.xend.domains(1)
def xend_domain_vcpuinfo(self, dom):
- return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
+ return self.srv.xend.domain.getVCPUInfo(dom)
def xend_domain_create(self, conf):
- return self.xendPost(self.domainurl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
+ return self.srv.xend.domain.create(fileof(conf))
+ # FIXME
def xend_domain_restore(self, filename):
- return self.xendPost(self.domainurl(),
- {'op' : 'restore',
- 'file' : filename })
+ return self.srv.xend.domain.restore(filename)
def xend_domain_configure(self, id, conf):
- return self.xendPost(self.domainurl(id),
- {'op' : 'configure',
- 'config' : fileof(conf) })
+ return self.srv.xend.domain.configure(id, fileof(conf))
def xend_domain(self, id):
- return self.xendGet(self.domainurl(id))
+ return self.srv.xend.domain(id)
def xend_domain_wait_for_devices(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'wait_for_devices' })
+ try:
+ self.srv.xend.domain.waitForDevices(id)
+ return 0
+ except:
+ return -1
+
+ def lookup(self, id):
+ info = self.srv.xend.domain(id)
+ return int(sxp.child_value(info, 'domid'))
def xend_domain_unpause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'unpause' })
+ self.srv.xend.domain.unpause(self.lookup(id))
+ return 0
def xend_domain_pause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pause' })
+ self.srv.xend.domain.pause(self.lookup(id))
+ return 0
def xend_domain_rename(self, id, name):
- return self.xendPost(self.domainurl(id),
- {'op' : 'rename',
- 'name' : name})
+ return self.srv.xend.domain.setName(id, name)
def xend_domain_shutdown(self, id, reason):
- return self.xendPost(self.domainurl(id),
- {'op' : 'shutdown',
- 'reason' : reason})
+ return self.srv.xend.domain.shutdown(id, reason)
def xend_domain_sysrq(self, id, key):
- return self.xendPost(self.domainurl(id),
- {'op' : 'sysrq',
- 'key' : key})
+ return self.srv.xend.domain.send_sysrq(self.lookup(id), key)
def xend_domain_destroy(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'destroy' })
+ return self.srv.xend.domain.destroy(self.lookup(id))
def xend_domain_save(self, id, filename):
- return self.xendPost(self.domainurl(id),
- {'op' : 'save',
- 'file' : filename })
+ return self.srv.xend.domain.save(self.lookup(id), filename)
def xend_domain_migrate(self, id, dst, live=0, resource=0, port=0):
- return self.xendPost(self.domainurl(id),
- {'op' : 'migrate',
- 'destination': dst,
- 'live' : live,
- 'resource' : resource,
- 'port' : port })
+ return self.srv.xend.domain.migrate(self.lookup(id), dst, live, resource, port)
def xend_domain_pincpu(self, id, vcpu, cpumap):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pincpu',
- 'vcpu' : vcpu,
- 'cpumap' : str(cpumap) })
+ return self.srv.xend.domain.pincpu(self.lookup(id), vcpu, str(cpumap))
def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_bvt_set',
- 'mcuadv' : mcuadv,
- 'warpback' : warpback,
- 'warpvalue': warpvalue,
- 'warpl' : warpl,
- 'warpu' : warpu })
+ return self.srv.xend.domain.cpu_bvt_set(mcuadv, warpback, warpvalue, warpl, warpu)
def xend_domain_cpu_sedf_get(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_get'})
+ return self.srv.xend.domain.cpu_sedf_get(self.lookup(id))
def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime, weight):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_set',
- 'period' : period,
- 'slice' : slice,
- 'latency' : latency,
- 'extratime' : extratime,
- 'weight' : weight })
+ return self.srv.xend.domain.cpu_sedf_set(self.lookup(id), period, slice, latency, extratime, weight)
def xend_domain_maxmem_set(self, id, memory):
- return self.xendPost(self.domainurl(id),
- { 'op' : 'maxmem_set',
- 'memory' : memory })
+ return self.srv.xend.domain.maxmem_set(self.lookup(id), memory)
def xend_domain_mem_target_set(self, id, mem_target):
- val = self.xendPost(self.domainurl(id),
- {'op' : 'mem_target_set',
- 'target' : mem_target })
- return val
+ return self.srv.xend.domain.setMemoryTarget(id, mem_target)
def xend_domain_set_vcpus(self, dom, vcpus):
- return self.xendPost(self.domainurl(dom),
- {'op' : 'set_vcpus',
- 'vcpus' : vcpus })
+ return self.srv.xend.domain.setVCpuCount(self.lookup(dom), vcpus)
def xend_domain_devices(self, id, type):
- return self.xendPost(self.domainurl(id),
- {'op' : 'devices',
- 'type' : type })
+ return self.srv.xend.domain.getDeviceSxprs(id, type)
def xend_domain_device_create(self, id, config):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_create',
- 'config' : fileof(config) })
-
- def xend_domain_device_refresh(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_refresh',
- 'type' : type,
- 'dev' : dev })
+ return self.srv.xend.domain.device_create(id, fileof(config))
def xend_domain_device_destroy(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_destroy',
- 'type' : type,
- 'dev' : dev })
+ return self.srv.xend.domain.destroyDevice(id, type, dev)
- def xend_domain_device_configure(self, id, config, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_configure',
- 'dev' : dev,
- 'config' : fileof(config) })
-
- def xend_vnets(self):
- return self.xendGet(self.vneturl())
-
- def xend_vnet_create(self, conf):
- return self.xendPost(self.vneturl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
-
- def xend_vnet(self, id):
- return self.xendGet(self.vneturl(id))
-
- def xend_vnet_delete(self, id):
- return self.xendPost(self.vneturl(id),
- {'op' : 'delete' })
-
-def getHttpServer(srv=None):
- """Create and return a xend client.
- """
- return Xend(srv=srv, client=HttpXendClientProtocol())
-
-def getUnixServer(srv=None):
- """Create and return a unix-domain xend client.
- """
- return Xend(client=UnixXendClientProtocol(srv))
-
-def xendmain(srv, fn, args, unix=False):
- if unix:
- xend = getUnixServer(srv)
- else:
- xend = getHttpServer(srv)
- xend.rc = 0
- try:
- v = getattr(xend, fn)(*args)
- PrettyPrint.prettyprint(v)
- return 0
- except XendError, err:
- print 'ERROR:', err
- return 1
-
-def main(argv):
- """Call an API function:
-
- python XendClient.py fn args...
-
- The leading 'xend_' on the function can be omitted.
- Example:
-
-python XendClient.py domains
- (0 8)
-python XendClient.py domain 0
- (domain (id 0) (name Domain-0) (memory 128))
- """
- from getopt import getopt
- short_options = 'x:au:d'
- long_options = ['xend=', 'unix=', 'debug']
- (options, args) = getopt(argv[1:], short_options, long_options)
- srv = None
- unix = 1
- for k, v in options:
- if k in ['-x', '--xend']:
- srv = v
- elif k in ['-u', '--unix']:
- unix = int(v)
- if len(args):
- fn = args[0]
- args = args[1:]
- else:
- fn = 'xend'
- args = []
- if not fn.startswith('xend'):
- fn = 'xend_' + fn
- sys.exit(xendmain(srv, fn, args, unix=unix))
-
-if __name__ == "__main__":
- main(sys.argv)
-else:
- server = getUnixServer()
+server = Xend()
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:10:14 2006
@@ -385,7 +385,7 @@
val = dominfo.destroy()
else:
try:
- val = xc.domain_destroy(domid)
+ val = xc.domain_destroy(int(domid))
except Exception, ex:
raise XendError(str(ex))
return val
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xm/create.py Tue Feb 28 22:10:14 2006
@@ -28,11 +28,9 @@
import time
import re
-import xen.lowlevel.xc
-
from xen.xend import sxp
from xen.xend import PrettyPrint
-from xen.xend.XendClient import server, XendError
+from xen.xend.XendClient import server
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
@@ -416,6 +414,8 @@
def err(msg):
"""Print an error to stderr and exit.
"""
+ import traceback
+ traceback.print_exc()
print >>sys.stderr, "Error:", msg
sys.exit(1)
@@ -810,7 +810,7 @@
dominfo = server.xend_domain_restore(filename, config)
else:
dominfo = server.xend_domain_create(config)
- except XendError, ex:
+ except Exception, ex:
import signal
if vncpid:
os.kill(vncpid, signal.SIGKILL)
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xm/main.py Tue Feb 28 22:10:14 2006
@@ -29,8 +29,8 @@
import socket
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
-
-import xen.xend.XendError
+import xmlrpclib
+
import xen.xend.XendProtocol
from xen.xend import PrettyPrint
@@ -1036,23 +1036,13 @@
else:
err("Error connecting to xend: %s." % ex[1])
sys.exit(1)
- except xen.xend.XendError.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@lists.xensource.com"
- raise
- except xen.xend.XendProtocol.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@lists.xensource.com"
- raise
except SystemExit:
+ sys.exit(1)
+ except xmlrpclib.Fault, ex:
+# print "Xend generated an internal fault:"
+# sys.stderr.write(ex.faultString)
+# sys.exit(1)
+ print "Error: Internal Xend error"
sys.exit(1)
except:
print "Unexpected error:", sys.exc_info()[0]
[-- Attachment #4: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-08 0:07 ` Anthony Liguori
@ 2006-03-11 20:55 ` Ewan Mellor
2006-03-11 21:36 ` Daniel Veillard
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Ewan Mellor @ 2006-03-11 20:55 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Ian Pratt, xen-devel
Anthony, I've reviewed your XML-RPC patches. It all looks good, so I'm in
favour of putting them in straight away. I'd like to get the second patch in
straight away as well as the first, that is (for those watching at home) to
change xm to using XML-RPC, because I would like to deprecate the old
protocol sooner, rather than later. Making the XML-RPC interface the primary
control path for Xen 3.0.2 will encourage third-parties to code to that rather
than to the s-expression protocol, and that's a good thing.
Here are some specific comments. There's quite a lot here, but nothing that
would prevent both patches going in. We can discuss these things, and if we're
still in disagreement or regard my suggestions as high risk, then we can put
in the two patches as they stand now.
> # HG changeset patch
> # User anthony@rhesis.austin.ibm.com
> # Node ID 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
> # Parent c369d960f96ba4fd7c9c6920cfa60c46a764323c
> Add an XML-RPC interface to Xend.
>
> This introduces a enhanced client library (xmlrpclib2) that supports XML-RPC
> over a domain socket (also working around a bug in Python's handling of NIL).
>
> This also introduces a new server that runs along side of the existing
> S-Expression/HTTP server.
>
> This changeset makes no change to the normal operation of Xend. xm still goes
> through S-Expression/HTTP -- there's just another option for interacting with
> Xend.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>
> diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/SrvServer.py
> --- a/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 16:45:20 2006
> +++ b/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 22:08:47 2006
> @@ -51,6 +51,7 @@
> from xen.web.SrvDir import SrvDir
>
> from SrvRoot import SrvRoot
> +from XMLRPCServer import XMLRPCServer
>
>
> xroot = XendRoot.instance()
> @@ -113,4 +114,5 @@
> path = xroot.get_xend_unix_path()
> log.info('unix path=' + path)
> servers.add(UnixHttpServer(path=path, root=root))
> + servers.add(XMLRPCServer())
> return servers
It would be prudent to make it possible to turn the XMLRPCServer off, just as we
can turn the other servers off.
> diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py
> --- /dev/null Tue Feb 28 16:45:20 2006
> +++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 2006
>
> [Snip lots]
>
> +class ServerProxy(xmlrpclib.ServerProxy):
> + def __init__(self, uri, transport=None, encoding=None, verbose=0,
> + allow_none=1):
> + if transport == None:
> + protocol = uri.split(':')[0]
> + if protocol == 'httpu':
> + uri = 'http:' + ':'.join(uri.split(':')[1:])
> + transport = UnixTransport()
How about
(protocol, rest) = uri.split(':', 1)
if protocol == 'httpu':
uri = 'http:' + rest
transport = UnixTransport()
>
> [Snip lots more]
>
> diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/XMLRPCServer.py
> --- /dev/null Tue Feb 28 16:45:20 2006
> +++ b/tools/python/xen/xend/server/XMLRPCServer.py Tue Feb 28 22:08:47 2006
> @@ -0,0 +1,97 @@
> +#============================================================================
> +# This library is free software; you can redistribute it and/or
> +# modify it under the terms of version 2.1 of the GNU Lesser General Public
> +# License as published by the Free Software Foundation.
> +#
> +# This library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with this library; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> +#============================================================================
> +# Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
> +#============================================================================
> +
> +from xen.xend import (XendDomain, XendDomainInfo, XendNode,
> + XendLogging, XendDmesg)
This syntax is only in Python 2.4+, so we have to use
from xen.xend import XendDomain, XendDomainInfo, XendNode, \
XendLogging, XendDmesg
> [Snip]
>
> +def get_log():
> + f = open(XendLogging.getLogFilename(), 'r')
> + ret = f.read()
> + f.close()
> + return ret
This will leak a file descriptor if f.read() throws an exception. We need
f = open(XendLogging.getLogFIlename(), 'r')
try:
return f.read()
finally:
f.close()
> +methods = ['device_create', 'destroyDevice', 'getDeviceSxprs',
> + 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
> + 'send_sysrq', 'getVCPUInfo', 'waitForDevices']
> +
> +exclude = ['domain_create', 'domain_restore']
> +
> +class XMLRPCServer:
> + def __init__(self):
> + self.ready = False
> +
> + def run(self):
> + self.server = UnixXMLRPCServer("/var/run/xend-xmlrpc.sock")
This filename constant needs to go somewhere else; XendClient is probably the
best place for it. (I've never liked the way that files in xen/xm have to go
poking around in xen/xend for things that they need, but I don't have the
stomach for a major file rearrangement at the moment, so XendClient will have
to do.)
> + # Functions in XendDomainInfo
> + for name in methods:
> + fn = eval("lambda domid, *args: dispatch(domid, '%s',
> args)"%name)
> + self.server.register_function(fn, "xend.domain.%s" %
> name)
> +
> + # Functions in XendDomain
> + inst = XendDomain.instance()
> + for name in dir(inst):
> + fn = getattr(inst, name)
> + if name.startswith("domain_") and callable(fn):
> + if name not in exclude:
> + self.server.register_function(fn,
> "xend.domain.%s" % name[7:])
> +
> + # Functions in XendNode and XendDmesg
> + for type, lst, n in [(XendNode, ['info',
> 'cpu_bvt_slice_set'], 'node'),
> + (XendDmesg, ['info', 'clear'],
> 'node.dmesg')]:
> + inst = type.instance()
> + for name in lst:
> + self.server.register_function(getattr(inst, name),
> + "xend.%s.%s" % (n,
> name))
> +
This is all a bit skanky, and could be easily cleaned up by introducing a
naming convention for XendDomain, XendNode, etc. How about if we prefixed
every function that we wish to expose to the messaging layer with
"public_"? So for example XendDomainInfo.send_sysrq would be named
public_send_sysrq instead. Then, we could use that to guide the
function registration, rather than having exclude lists and inline lists
of callable methods.
This would make your patch a bit more invasive, in that the renaming
would cause it to touch more files, but I don't have a problem with that
-- I think the change is justified.
> [Snip the rest of this patch]
>
> # HG changeset patch
> # User anthony@rhesis.austin.ibm.com
> # Node ID 951f0d589164e0cffc785cf23d82118b3e0b0495
> # Parent 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
> This changeset is a major refactoring of XendClient to use the XML-RPC
> transport for Xend and also to make a few changes to xm so that it knows about
> the new Exception types.
>
> xm-test has been passing with this changeset for the past couple of weeks.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>
> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendClient.py
> --- a/tools/python/xen/xend/XendClient.py Tue Feb 28 22:08:47 2006
> +++ b/tools/python/xen/xend/XendClient.py Tue Feb 28 22:10:14 2006
>
> [Snip lots]
>
> def xend_node_get_dmesg(self):
> - return self.xendGet(self.nodeurl('dmesg'))
> + return self.srv.xend.node.dmesg.info()
What you've done here is slipped the new XML-RPC layer under the existing
XendClient API. I don't think that we need to support that API at all. All
the functions here just turn into stubs onto ServerProxy, and I don't think
that those stubs buy us anything.
What I'd do here is just this:
XendClient.py:
XEND_XMLRPC_UNIX_SOCKET = '/var/run/xend-xmlrpc.sock'
server = ServerProxy('httpu://' + XEND_XMLRPC_UNIX_SOCKET)
and then push _all_ the other code into the client (main.py, create.py, etc).
So these would change from
from xen.xend.XendClient import server
print server.xend_node_get_dmesg()
to
from xen.xend.XendClient import server
print server.xend.node.dmesg.info()
XendClient.py just dissolves into nothingness, and the clients are no more
complicated.
> def xend_domain_sysrq(self, id, key):
> - return self.xendPost(self.domainurl(id),
> - {'op' : 'sysrq',
> - 'key' : key})
> + return self.srv.xend.domain.send_sysrq(self.lookup(id), key)
For calls like this, where we currently look up the domain ID before making the
real call, I would push the lookup to the server; there's no need for two
roundtrips for this kind of call. I think that if you remove the lookup call,
it will just work now in any case, because XMLRPCServer.lookup uses
XendDomain.domain_lookup_by_name_or_id.
> + # FIXME
> + def xend_domain_restore(self, filename):
> + return self.srv.xend.domain.restore(filename)
What does this FIXME mean?
> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendDomain.py
> --- a/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:08:47 2006
> +++ b/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:10:14 2006
> @@ -385,7 +385,7 @@
> val = dominfo.destroy()
> else:
> try:
> - val = xc.domain_destroy(domid)
> + val = xc.domain_destroy(int(domid))
> except Exception, ex:
> raise XendError(str(ex))
> return val
I can see why you've done this, but it just led me to wonder why
XendDomain.domain_destroy exists at all. All it's doing is looking up a
domain ID, checking that it's not the privileged domain (in the wrong
order!) calling XendDomainInfo.destroy, and calling xc.domain_destroy in
the case of an exception. We should move the check and the exception
handling into XendDomainInfo.destroy, and then we can dispatch to that
method straight away, without needing XendDomain.domain_destroy at all.
The messaging layer already has the capability to lookup domain IDs --
we should use it.
The reason I noticed is that I have been trying to make it so that
XendDomain and XendDomainInfo only receive arguments of the correct type,
with the casts to integers etc handled by the messaging layer. This
change you've made highlights the fact that there is now nowhere for
that type conversion to take place, because the messaging layer is more
generic, and doesn't understand the calls that it is dispatching.
That's OK -- it's a consequence of the removal of all that code in
SrvDomain -- but it's something to be aware of. If we adopt the naming
convention that I suggest above, then all methods accept only arguments
of the correct type _except_ for those named "public_xyz" -- those
methods must validate and convert their arguments appropriately.
> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/create.py
> --- a/tools/python/xen/xm/create.py Tue Feb 28 22:08:47 2006
> +++ b/tools/python/xen/xm/create.py Tue Feb 28 22:10:14 2006
> @@ -28,11 +28,9 @@
> import time
> import re
>
> -import xen.lowlevel.xc
> -
> from xen.xend import sxp
> from xen.xend import PrettyPrint
> -from xen.xend.XendClient import server, XendError
> +from xen.xend.XendClient import server
> from xen.xend.XendBootloader import bootloader
> from xen.util import blkif
>
> @@ -416,6 +414,8 @@
> def err(msg):
> """Print an error to stderr and exit.
> """
> + import traceback
> + traceback.print_exc()
> print >>sys.stderr, "Error:", msg
> sys.exit(1)
This looks like debug code -- I'm not even sure how this traceback helps
you very much. It should be disabled by default, or removed altogether.
> @@ -810,7 +810,7 @@
> dominfo = server.xend_domain_restore(filename, config)
> else:
> dominfo = server.xend_domain_create(config)
> - except XendError, ex:
> + except Exception, ex:
> import signal
> if vncpid:
> os.kill(vncpid, signal.SIGKILL)
> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/main.py
> --- a/tools/python/xen/xm/main.py Tue Feb 28 22:08:47 2006
> +++ b/tools/python/xen/xm/main.py Tue Feb 28 22:10:14 2006
> @@ -29,8 +29,8 @@
> import socket
> import warnings
> warnings.filterwarnings('ignore', category=FutureWarning)
> -
> -import xen.xend.XendError
> +import xmlrpclib
> +
> import xen.xend.XendProtocol
>
> from xen.xend import PrettyPrint
> @@ -1036,23 +1036,13 @@
> else:
> err("Error connecting to xend: %s." % ex[1])
> sys.exit(1)
> - except xen.xend.XendError.XendError, ex:
> - if len(args) > 0:
> - handle_xend_error(argv[1], args, ex)
> - else:
> - print "Unexpected error:", sys.exc_info()[0]
> - print
> - print "Please report to xen-devel@lists.xensource.com"
> - raise
> - except xen.xend.XendProtocol.XendError, ex:
> - if len(args) > 0:
> - handle_xend_error(argv[1], args, ex)
> - else:
> - print "Unexpected error:", sys.exc_info()[0]
> - print
> - print "Please report to xen-devel@lists.xensource.com"
> - raise
> except SystemExit:
> + sys.exit(1)
> + except xmlrpclib.Fault, ex:
> +# print "Xend generated an internal fault:"
> +# sys.stderr.write(ex.faultString)
> +# sys.exit(1)
> + print "Error: Internal Xend error"
I expect we can do better than just printing "Internal Xend Error". How
much structure and useful information is there in an xmlrpclib.Fault at
the moment?
> sys.exit(1)
> except:
> print "Unexpected error:", sys.exc_info()[0]
Looks like that's it! Thanks for all your hard work, Anthony, this is
going to make a big difference to Xend's usefulness and maintainability,
and you've done a good job of it. Let's get it into 3.0.2.
Cheers,
Ewan.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 20:55 ` Ewan Mellor
@ 2006-03-11 21:36 ` Daniel Veillard
2006-03-11 22:20 ` Ewan Mellor
2006-03-12 1:44 ` Anthony Liguori
2006-03-14 6:58 ` Anthony Liguori
2 siblings, 1 reply; 19+ messages in thread
From: Daniel Veillard @ 2006-03-11 21:36 UTC (permalink / raw)
To: Ewan Mellor; +Cc: Ian Pratt, xen-devel
On Sat, Mar 11, 2006 at 08:55:10PM +0000, Ewan Mellor wrote:
> Anthony, I've reviewed your XML-RPC patches. It all looks good, so I'm in
> favour of putting them in straight away. I'd like to get the second patch in
> straight away as well as the first, that is (for those watching at home) to
> change xm to using XML-RPC, because I would like to deprecate the old
> protocol sooner, rather than later. Making the XML-RPC interface the primary
> control path for Xen 3.0.2 will encourage third-parties to code to that rather
> than to the s-expression protocol, and that's a good thing.
+1 we will try to switch ASAP too at the libvirt level.
> It would be prudent to make it possible to turn the XMLRPCServer off, just as we
> can turn the other servers off.
Big dilemna :-)
Currently with http on anybody can manipulate any Xen instance as soon
as one has Xen0 access (I run my libvirt regression test from my normal
user login but except for the convenience it's a bit scary :-). I assume
It will be exactly the same with XML-RPC. I would feel way better if we
could have a policy model which is not all on or all off implemented,
for example associating users with domains, and controlling per user
resource usage. I know that the obvious answer would be "only root should
do that" except that a frustated user needing his VM could then launch
a qemu instance instead and that wouldn't be any better for the server.
IMHO a smarter, more fine grained approach is needed, it will also require
authentication at connection time to the service, and even if not trivial
this should be doable and we use authenticated XML-RPC call all the time
for the Red Hat Network framework, so this has to be possible locally and
remotely.
> > diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py
> > --- /dev/null Tue Feb 28 16:45:20 2006
> > +++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 2006
> >
> > [Snip lots]
> >
> > +class ServerProxy(xmlrpclib.ServerProxy):
> > + def __init__(self, uri, transport=None, encoding=None, verbose=0,
> > + allow_none=1):
> > + if transport == None:
> > + protocol = uri.split(':')[0]
> > + if protocol == 'httpu':
> > + uri = 'http:' + ':'.join(uri.split(':')[1:])
> > + transport = UnixTransport()
>
> How about
>
> (protocol, rest) = uri.split(':', 1)
> if protocol == 'httpu':
> uri = 'http:' + rest
> transport = UnixTransport()
hum, do we really need to invent a new transport for local access ?
I don't remember seeing 'httpu' anywhere, sounds weird to me
[...]
> > except SystemExit:
> > + sys.exit(1)
> > + except xmlrpclib.Fault, ex:
> > +# print "Xend generated an internal fault:"
> > +# sys.stderr.write(ex.faultString)
> > +# sys.exit(1)
> > + print "Error: Internal Xend error"
>
> I expect we can do better than just printing "Internal Xend Error". How
> much structure and useful information is there in an xmlrpclib.Fault at
> the moment?
Another good question, as we are defining an API to Xend I think
the error handling question will become more and more important. The client
will need more structure and informations about processing error, the
full stack trace within xend might not be that useful (except for low level
debugging) to the clients, but currently I just extract a string like
"No such domain test"
which is a bit hard to process correctly even in context. A list of predefined
error code and meaning could help quite a bit along with just the error message.
> > sys.exit(1)
> > except:
> > print "Unexpected error:", sys.exc_info()[0]
>
> Looks like that's it! Thanks for all your hard work, Anthony, this is
> going to make a big difference to Xend's usefulness and maintainability,
> and you've done a good job of it. Let's get it into 3.0.2.
Yup, thanks Anthony :-) !
Daniel
--
Daniel Veillard | Red Hat http://redhat.com/
veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 21:36 ` Daniel Veillard
@ 2006-03-11 22:20 ` Ewan Mellor
2006-03-12 1:46 ` Anthony Liguori
2006-03-12 9:57 ` Daniel Veillard
0 siblings, 2 replies; 19+ messages in thread
From: Ewan Mellor @ 2006-03-11 22:20 UTC (permalink / raw)
To: Daniel Veillard; +Cc: Ian Pratt, xen-devel
On Sat, Mar 11, 2006 at 04:36:57PM -0500, Daniel Veillard wrote:
> > It would be prudent to make it possible to turn the XMLRPCServer off, just as we
> > can turn the other servers off.
>
> Big dilemna :-)
> Currently with http on anybody can manipulate any Xen instance as soon
> as one has Xen0 access (I run my libvirt regression test from my normal
> user login but except for the convenience it's a bit scary :-). I assume
> It will be exactly the same with XML-RPC. I would feel way better if we
> could have a policy model which is not all on or all off implemented,
> for example associating users with domains, and controlling per user
> resource usage. I know that the obvious answer would be "only root should
> do that" except that a frustated user needing his VM could then launch
> a qemu instance instead and that wouldn't be any better for the server.
> IMHO a smarter, more fine grained approach is needed, it will also require
> authentication at connection time to the service, and even if not trivial
> this should be doable and we use authenticated XML-RPC call all the time
> for the Red Hat Network framework, so this has to be possible locally and
> remotely.
Turning the server on and off is just for basic sanity -- the admin gets
to choose which ports they want open so that they don't have to audit
aspects in which they aren't interested.
Of course, a full user / permissions system for the protocol would be a
good idea, but like you say, it's not trivial work. We could kick that
discussion off if you want, but it's going to need someone to design
the permissions semantics, management of users and roles, etc. Is
anyone interested in starting this?
At the moment, the XML-RPC is over a Unix domain socket, so only root
can use it anyway (as controlled by the permission on the socket file).
> > > diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py
> > > --- /dev/null Tue Feb 28 16:45:20 2006
> > > +++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 2006
> > >
> > > [Snip lots]
> > >
> > > +class ServerProxy(xmlrpclib.ServerProxy):
> > > + def __init__(self, uri, transport=None, encoding=None, verbose=0,
> > > + allow_none=1):
> > > + if transport == None:
> > > + protocol = uri.split(':')[0]
> > > + if protocol == 'httpu':
> > > + uri = 'http:' + ':'.join(uri.split(':')[1:])
> > > + transport = UnixTransport()
> >
> > How about
> >
> > (protocol, rest) = uri.split(':', 1)
> > if protocol == 'httpu':
> > uri = 'http:' + rest
> > transport = UnixTransport()
>
> hum, do we really need to invent a new transport for local access ?
> I don't remember seeing 'httpu' anywhere, sounds weird to me
httpu is HTTP over a unix domain socket, as opposed to over TCP. It's
used elsewhere (though not widely, obviously). It gives you basic
protection from non-root users (see your complaint above).
> [...]
> > > except SystemExit:
> > > + sys.exit(1)
> > > + except xmlrpclib.Fault, ex:
> > > +# print "Xend generated an internal fault:"
> > > +# sys.stderr.write(ex.faultString)
> > > +# sys.exit(1)
> > > + print "Error: Internal Xend error"
> >
> > I expect we can do better than just printing "Internal Xend Error". How
> > much structure and useful information is there in an xmlrpclib.Fault at
> > the moment?
>
> Another good question, as we are defining an API to Xend I think
> the error handling question will become more and more important. The client
> will need more structure and informations about processing error, the
> full stack trace within xend might not be that useful (except for low level
> debugging) to the clients, but currently I just extract a string like
> "No such domain test"
> which is a bit hard to process correctly even in context. A list of predefined
> error code and meaning could help quite a bit along with just the error message.
Sure. Do you have a list of error codes already (for libvirt, for
example)?
Ewan.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 20:55 ` Ewan Mellor
2006-03-11 21:36 ` Daniel Veillard
@ 2006-03-12 1:44 ` Anthony Liguori
2006-03-13 10:30 ` Ewan Mellor
2006-03-14 6:58 ` Anthony Liguori
2 siblings, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2006-03-12 1:44 UTC (permalink / raw)
To: Ewan Mellor; +Cc: Ian Pratt, xen-devel
Ewan Mellor wrote:
> Anthony, I've reviewed your XML-RPC patches. It all looks good, so I'm in
> favour of putting them in straight away.
Thanks!
> I'd like to get the second patch in
> straight away as well as the first, that is (for those watching at home) to
> change xm to using XML-RPC, because I would like to deprecate the old
> protocol sooner, rather than later. Making the XML-RPC interface the primary
> control path for Xen 3.0.2 will encourage third-parties to code to that rather
> than to the s-expression protocol, and that's a good thing.
>
Okay. So I'm going to take this to mean that we would deprecate
S-Expression/HTTP for 3.0.2 and remove it in 3.0.3? That would be
really nice.
>> xroot = XendRoot.instance()
>> @@ -113,4 +114,5 @@
>> path = xroot.get_xend_unix_path()
>> log.info('unix path=' + path)
>> servers.add(UnixHttpServer(path=path, root=root))
>> + servers.add(XMLRPCServer())
>> return servers
>>
>
> It would be prudent to make it possible to turn the XMLRPCServer off, just as we
> can turn the other servers off.
>
Yeah, this is certainly sane.
>> +class ServerProxy(xmlrpclib.ServerProxy):
>> + def __init__(self, uri, transport=None, encoding=None, verbose=0,
>> + allow_none=1):
>> + if transport == None:
>> + protocol = uri.split(':')[0]
>> + if protocol == 'httpu':
>> + uri = 'http:' + ':'.join(uri.split(':')[1:])
>> + transport = UnixTransport()
>>
>
> How about
>
> (protocol, rest) = uri.split(':', 1)
> if protocol == 'httpu':
> uri = 'http:' + rest
> transport = UnixTransport()
>
Haven't seen that before. Quite useful :-)
>> +from xen.xend import (XendDomain, XendDomainInfo, XendNode,
>> + XendLogging, XendDmesg)
>>
>
> This syntax is only in Python 2.4+, so we have to use
>
> from xen.xend import XendDomain, XendDomainInfo, XendNode, \
> XendLogging, XendDmesg
>
Yeah, thanks for the catch.
>> [Snip]
>>
>> +def get_log():
>> + f = open(XendLogging.getLogFilename(), 'r')
>> + ret = f.read()
>> + f.close()
>> + return ret
>>
>
> This will leak a file descriptor if f.read() throws an exception. We need
>
> f = open(XendLogging.getLogFIlename(), 'r')
> try:
> return f.read()
> finally:
> f.close()
>
Yeah, again, thanks for the catch :-)
>> + def run(self):
>> + self.server = UnixXMLRPCServer("/var/run/xend-xmlrpc.sock")
>>
>
> This filename constant needs to go somewhere else; XendClient is probably the
> best place for it. (I've never liked the way that files in xen/xm have to go
> poking around in xen/xend for things that they need, but I don't have the
> stomach for a major file rearrangement at the moment, so XendClient will have
> to do.)
>
Okay. I'm fine with that.
>> + # Functions in XendNode and XendDmesg
>> + for type, lst, n in [(XendNode, ['info',
>> 'cpu_bvt_slice_set'], 'node'),
>> + (XendDmesg, ['info', 'clear'],
>> 'node.dmesg')]:
>> + inst = type.instance()
>> + for name in lst:
>> + self.server.register_function(getattr(inst, name),
>> + "xend.%s.%s" % (n,
>> name))
>> +
>>
>
> This is all a bit skanky, and could be easily cleaned up by introducing a
> naming convention for XendDomain, XendNode, etc.
Yes, skanky is very much an understatement. I found XendDomain and
XendDomainInfo particularly nasty to work with considering that they use
different naming conventions too.
> How about if we prefixed
> every function that we wish to expose to the messaging layer with
> "public_"? So for example XendDomainInfo.send_sysrq would be named
> public_send_sysrq instead. Then, we could use that to guide the
> function registration, rather than having exclude lists and inline lists
> of callable methods.
>
Isn't using an underscore a convention for making methods private in
Python? I think, at least, pydoc ignores functions that start with an
underscore.
> This would make your patch a bit more invasive, in that the renaming
> would cause it to touch more files, but I don't have a problem with that
> -- I think the change is justified.
>
Yes, that would make things much nicer so I'm happy to do it. I clearly
wanted to avoid making more changes than necessary at first :-)
>> [Snip the rest of this patch]
>>
>> # HG changeset patch
>> # User anthony@rhesis.austin.ibm.com
>> # Node ID 951f0d589164e0cffc785cf23d82118b3e0b0495
>> # Parent 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
>> This changeset is a major refactoring of XendClient to use the XML-RPC
>> transport for Xend and also to make a few changes to xm so that it knows about
>> the new Exception types.
>>
>> xm-test has been passing with this changeset for the past couple of weeks.
>>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>
>> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendClient.py
>> --- a/tools/python/xen/xend/XendClient.py Tue Feb 28 22:08:47 2006
>> +++ b/tools/python/xen/xend/XendClient.py Tue Feb 28 22:10:14 2006
>>
>> [Snip lots]
>>
>> def xend_node_get_dmesg(self):
>> - return self.xendGet(self.nodeurl('dmesg'))
>> + return self.srv.xend.node.dmesg.info()
>>
>
> What you've done here is slipped the new XML-RPC layer under the existing
> XendClient API. I don't think that we need to support that API at all. All
> the functions here just turn into stubs onto ServerProxy, and I don't think
> that those stubs buy us anything.
>
Nope. Just compatibility. I know there are people using the XendClient
API. I also know we've never declared that to be a fixed API. I didn't
want to be the one to break it though :-)
> What I'd do here is just this:
>
> XendClient.py:
>
> XEND_XMLRPC_UNIX_SOCKET = '/var/run/xend-xmlrpc.sock'
>
> server = ServerProxy('httpu://' + XEND_XMLRPC_UNIX_SOCKET)
>
> and then push _all_ the other code into the client (main.py, create.py, etc).
> So these would change from
>
> from xen.xend.XendClient import server
> print server.xend_node_get_dmesg()
>
> to
>
> from xen.xend.XendClient import server
> print server.xend.node.dmesg.info()
>
> XendClient.py just dissolves into nothingness, and the clients are no more
> complicated.
>
Yes, this would be great. If we don't mind breaking XendClient, I'm
happy to do it.
>> def xend_domain_sysrq(self, id, key):
>> - return self.xendPost(self.domainurl(id),
>> - {'op' : 'sysrq',
>> - 'key' : key})
>> + return self.srv.xend.domain.send_sysrq(self.lookup(id), key)
>>
>
> For calls like this, where we currently look up the domain ID before making the
> real call, I would push the lookup to the server; there's no need for two
> roundtrips for this kind of call. I think that if you remove the lookup call,
> it will just work now in any case, because XMLRPCServer.lookup uses
> XendDomain.domain_lookup_by_name_or_id.
>
Yeah, lookup() is a bit of a hack. I can go through and audit the
functions to make sure that they all accept either names or IDs.
>> + # FIXME
>> + def xend_domain_restore(self, filename):
>> + return self.srv.xend.domain.restore(filename)
>>
>
> What does this FIXME mean?
>
Sorry, that shouldn't have been there. I already fixed that one :-)
>> diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendDomain.py
>> --- a/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:08:47 2006
>> +++ b/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:10:14 2006
>> @@ -385,7 +385,7 @@
>> val = dominfo.destroy()
>> else:
>> try:
>> - val = xc.domain_destroy(domid)
>> + val = xc.domain_destroy(int(domid))
>> except Exception, ex:
>> raise XendError(str(ex))
>> return val
>>
>
> I can see why you've done this, but it just led me to wonder why
> XendDomain.domain_destroy exists at all. All it's doing is looking up a
> domain ID, checking that it's not the privileged domain (in the wrong
> order!) calling XendDomainInfo.destroy, and calling xc.domain_destroy in
> the case of an exception. We should move the check and the exception
> handling into XendDomainInfo.destroy, and then we can dispatch to that
> method straight away, without needing XendDomain.domain_destroy at all.
> The messaging layer already has the capability to lookup domain IDs --
> we should use it.
>
Ok, sounds sane to me.
> The reason I noticed is that I have been trying to make it so that
> XendDomain and XendDomainInfo only receive arguments of the correct type,
> with the casts to integers etc handled by the messaging layer. This
> change you've made highlights the fact that there is now nowhere for
> that type conversion to take place, because the messaging layer is more
> generic, and doesn't understand the calls that it is dispatching.
> That's OK -- it's a consequence of the removal of all that code in
> SrvDomain -- but it's something to be aware of. If we adopt the naming
> convention that I suggest above, then all methods accept only arguments
> of the correct type _except_ for those named "public_xyz" -- those
> methods must validate and convert their arguments appropriately.
>
Why? If a public_ function expects a domid and gets passed a string, it
ought to throw an exception and the client should get it as an error.
This particular hack was to account for a place in xm where it was
passing a string version of the domain ID. The real problem here was
the xm code. I wanted to avoid modifying that code though to
demonstrate that the XML-RPC stuff could be a drop-in-replacement. Of
course, now that that exercise is complete, there's no reason not to go
in and fix the original source of the problem.
>> @@ -416,6 +414,8 @@
>> def err(msg):
>> """Print an error to stderr and exit.
>> """
>> + import traceback
>> + traceback.print_exc()
>> print >>sys.stderr, "Error:", msg
>> sys.exit(1)
>>
>
> This looks like debug code -- I'm not even sure how this traceback helps
> you very much. It should be disabled by default, or removed altogether.
>
Yeah, sorry, I missed that.
>> from xen.xend import PrettyPrint
>> @@ -1036,23 +1036,13 @@
>> else:
>> err("Error connecting to xend: %s." % ex[1])
>> sys.exit(1)
>> - except xen.xend.XendError.XendError, ex:
>> - if len(args) > 0:
>> - handle_xend_error(argv[1], args, ex)
>> - else:
>> - print "Unexpected error:", sys.exc_info()[0]
>> - print
>> - print "Please report to xen-devel@lists.xensource.com"
>> - raise
>> - except xen.xend.XendProtocol.XendError, ex:
>> - if len(args) > 0:
>> - handle_xend_error(argv[1], args, ex)
>> - else:
>> - print "Unexpected error:", sys.exc_info()[0]
>> - print
>> - print "Please report to xen-devel@lists.xensource.com"
>> - raise
>> except SystemExit:
>> + sys.exit(1)
>> + except xmlrpclib.Fault, ex:
>> +# print "Xend generated an internal fault:"
>> +# sys.stderr.write(ex.faultString)
>> +# sys.exit(1)
>> + print "Error: Internal Xend error"
>>
>
> I expect we can do better than just printing "Internal Xend Error". How
> much structure and useful information is there in an xmlrpclib.Fault at
> the moment?
>
We can pass whatever we want. xmlrpclib.Fault contain an integer code
and a string message. For now, I'm just always passing a 1 for the
faultCode and sending the Xend traceback as the faultMessage.
I'm not sure how fancy we want to get for the first drop of this code.
Any suggestions?
BTW, it's printing 'Internal Xend Error' because xm-test has a test case
that checks for that specific result :-)
>
>> sys.exit(1)
>> except:
>> print "Unexpected error:", sys.exc_info()[0]
>>
>
> Looks like that's it! Thanks for all your hard work, Anthony, this is
> going to make a big difference to Xend's usefulness and maintainability,
> and you've done a good job of it. Let's get it into 3.0.2.
>
Thanks for looking at the code! I don't think there's that much change
necessary. I should be able to turn around another patch in a couple days.
Regards,
Anthony Liguori
> Cheers,
>
> Ewan.
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 22:20 ` Ewan Mellor
@ 2006-03-12 1:46 ` Anthony Liguori
2006-03-12 9:27 ` Daniel Veillard
2006-03-12 9:57 ` Daniel Veillard
1 sibling, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2006-03-12 1:46 UTC (permalink / raw)
To: Ewan Mellor; +Cc: Ian Pratt, xen-devel, Daniel Veillard
Ewan Mellor wrote:
> On Sat, Mar 11, 2006 at 04:36:57PM -0500, Daniel Veillard wrote:
>
> Turning the server on and off is just for basic sanity -- the admin gets
> to choose which ports they want open so that they don't have to audit
> aspects in which they aren't interested.
>
> Of course, a full user / permissions system for the protocol would be a
> good idea, but like you say, it's not trivial work. We could kick that
> discussion off if you want, but it's going to need someone to design
> the permissions semantics, management of users and roles, etc. Is
> anyone interested in starting this?
>
We can do basic authentication and require root credentials as a start.
That's really easy to do but I'm not sure sending the root password as
clear text really makes things much better :-)
Python, unfortunately, doesn't have server-side SSL bindings so basic
authentication over SSL is not an option without some custom OpenSSL
bindings.
Regards,
Anthony Liguori
> At the moment, the XML-RPC is over a Unix domain socket, so only root
> can use it anyway (as controlled by the permission on the socket file).
>
>
>>>> diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py
>>>> --- /dev/null Tue Feb 28 16:45:20 2006
>>>> +++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 2006
>>>>
>>>> [Snip lots]
>>>>
>>>> +class ServerProxy(xmlrpclib.ServerProxy):
>>>> + def __init__(self, uri, transport=None, encoding=None, verbose=0,
>>>> + allow_none=1):
>>>> + if transport == None:
>>>> + protocol = uri.split(':')[0]
>>>> + if protocol == 'httpu':
>>>> + uri = 'http:' + ':'.join(uri.split(':')[1:])
>>>> + transport = UnixTransport()
>>>>
>>> How about
>>>
>>> (protocol, rest) = uri.split(':', 1)
>>> if protocol == 'httpu':
>>> uri = 'http:' + rest
>>> transport = UnixTransport()
>>>
>> hum, do we really need to invent a new transport for local access ?
>> I don't remember seeing 'httpu' anywhere, sounds weird to me
>>
>
> httpu is HTTP over a unix domain socket, as opposed to over TCP. It's
> used elsewhere (though not widely, obviously). It gives you basic
> protection from non-root users (see your complaint above).
>
>
>> [...]
>>
>>>> except SystemExit:
>>>> + sys.exit(1)
>>>> + except xmlrpclib.Fault, ex:
>>>> +# print "Xend generated an internal fault:"
>>>> +# sys.stderr.write(ex.faultString)
>>>> +# sys.exit(1)
>>>> + print "Error: Internal Xend error"
>>>>
>>> I expect we can do better than just printing "Internal Xend Error". How
>>> much structure and useful information is there in an xmlrpclib.Fault at
>>> the moment?
>>>
>> Another good question, as we are defining an API to Xend I think
>> the error handling question will become more and more important. The client
>> will need more structure and informations about processing error, the
>> full stack trace within xend might not be that useful (except for low level
>> debugging) to the clients, but currently I just extract a string like
>> "No such domain test"
>> which is a bit hard to process correctly even in context. A list of predefined
>> error code and meaning could help quite a bit along with just the error message.
>>
>
> Sure. Do you have a list of error codes already (for libvirt, for
> example)?
>
> Ewan.
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-12 1:46 ` Anthony Liguori
@ 2006-03-12 9:27 ` Daniel Veillard
0 siblings, 0 replies; 19+ messages in thread
From: Daniel Veillard @ 2006-03-12 9:27 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Ian Pratt, xen-devel, Ewan Mellor
On Sat, Mar 11, 2006 at 07:46:35PM -0600, Anthony Liguori wrote:
> Ewan Mellor wrote:
> >On Sat, Mar 11, 2006 at 04:36:57PM -0500, Daniel Veillard wrote:
> >
> >Turning the server on and off is just for basic sanity -- the admin gets
> >to choose which ports they want open so that they don't have to audit
> >aspects in which they aren't interested.
> >
> >Of course, a full user / permissions system for the protocol would be a
> >good idea, but like you say, it's not trivial work. We could kick that
> >discussion off if you want, but it's going to need someone to design
> >the permissions semantics, management of users and roles, etc. Is
> >anyone interested in starting this?
> >
> We can do basic authentication and require root credentials as a start.
> That's really easy to do but I'm not sure sending the root password as
> clear text really makes things much better :-)
>
> Python, unfortunately, doesn't have server-side SSL bindings so basic
> authentication over SSL is not an option without some custom OpenSSL
> bindings.
Hum, I could check how much "custom" is required, I remember doing
that a long time ago but I could ask around :-) if interested.
Daniel
--
Daniel Veillard | Red Hat http://redhat.com/
veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 22:20 ` Ewan Mellor
2006-03-12 1:46 ` Anthony Liguori
@ 2006-03-12 9:57 ` Daniel Veillard
2006-03-12 17:41 ` Anthony Liguori
1 sibling, 1 reply; 19+ messages in thread
From: Daniel Veillard @ 2006-03-12 9:57 UTC (permalink / raw)
To: Ewan Mellor; +Cc: Ian Pratt, xen-devel
On Sat, Mar 11, 2006 at 10:20:53PM +0000, Ewan Mellor wrote:
> Of course, a full user / permissions system for the protocol would be a
> good idea, but like you say, it's not trivial work. We could kick that
> discussion off if you want, but it's going to need someone to design
> the permissions semantics, management of users and roles, etc. Is
> anyone interested in starting this?
We need to make sure we can have authentication based on the transport
used, otherwise this need to be added at the RPC level (and hence changes
the API).
> At the moment, the XML-RPC is over a Unix domain socket, so only root
> can use it anyway (as controlled by the permission on the socket file).
To me that's a big regression. That mean libvirt can't be used anymore
to just monitor the Xen instance(s) without priviledged access. Monitoring
should not require root priviledge IMHO, ps aux and top are not restricted
to root on Unix. And if you make Xen virtualization a sysadmin only feature
you restrain massively the area of usage IMHO, people will just use
something else (as stated QEmu requires no sysadmin priviledge, and if using
Xen can't be integrated seamlessly in the user workflow, they will switch to
something else).
Well over (modern) unix socket one can extract the UID of the connecting
client, can we extract that from Python ? (c.f. LOCAL_CREDS/SO_PEERCRED)
If yes then that's a good first step toward local authentication without
messing with https and credentials.
> httpu is HTTP over a unix domain socket, as opposed to over TCP. It's
> used elsewhere (though not widely, obviously). It gives you basic
> protection from non-root users (see your complaint above).
It's not a complaint, I'm raising a problem, which IMHO is different.
Adding core piece of OS machinery without thinking of security and
authentication aspects from the start is a mistake that had been done on
Unix already, it would be great to not go though the mess again just
because we are eager to push a solution, the subsequent costs could
reduce the benefits from the effort getting there ;-)
> > > I expect we can do better than just printing "Internal Xend Error". How
> > > much structure and useful information is there in an xmlrpclib.Fault at
> > > the moment?
> >
> > Another good question, as we are defining an API to Xend I think
> > the error handling question will become more and more important. The client
> > will need more structure and informations about processing error, the
> > full stack trace within xend might not be that useful (except for low level
> > debugging) to the clients, but currently I just extract a string like
> > "No such domain test"
> > which is a bit hard to process correctly even in context. A list of predefined
> > error code and meaning could help quite a bit along with just the error message.
>
> Sure. Do you have a list of error codes already (for libvirt, for
> example)?
Yes but for the moment they can't capture what's happening within Xend,
so if the RPC fails they show up just as being from within Xend, with
either a GET or POST information and the string found in the content of
the HTTP answer:
http://libvirt.org/html/libvirt-virterror.html#virErrorNumber
associated docs:
http://libvirt.org/errors.html
Daniel
--
Daniel Veillard | Red Hat http://redhat.com/
veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-12 9:57 ` Daniel Veillard
@ 2006-03-12 17:41 ` Anthony Liguori
0 siblings, 0 replies; 19+ messages in thread
From: Anthony Liguori @ 2006-03-12 17:41 UTC (permalink / raw)
To: xen-devel
On Sun, 12 Mar 2006 04:57:02 -0500, Daniel Veillard wrote:
> On Sat, Mar 11, 2006 at 10:20:53PM +0000, Ewan Mellor wrote:
>> Of course, a full user / permissions system for the protocol would be a
>> good idea, but like you say, it's not trivial work. We could kick that
>> discussion off if you want, but it's going to need someone to design
>> the permissions semantics, management of users and roles, etc. Is
>> anyone interested in starting this?
>
> We need to make sure we can have authentication based on the transport
> used, otherwise this need to be added at the RPC level (and hence changes
> the API).
Here's my proposal:
We make a simple program that connects to a domain socket and funnels the
stdin/stdout to that socket.
One can then build an XML-RPC transport on top of it via SSH. The client
side simply invokes ssh and treats it's stdio as it would a normal socket.
I've used this approach before with great success.
We get PAM authentication for free. An advanced admin can suid that
executable to delegate privileges.
I still think we ought to have a less privileged socket too but one that's
remotable in a similar manner.
>> At the moment, the XML-RPC is over a Unix domain socket, so only root
>> can use it anyway (as controlled by the permission on the socket file).
>
> To me that's a big regression. That mean libvirt can't be used anymore
> to just monitor the Xen instance(s) without priviledged access.
The code is there for TCP. It's just hard coded to use a domain socket
right now. When I make the change Ewan requested to allow it to be
enabled/disabled I'll make it possible to choose the TCP version.
> Well over (modern) unix socket one can extract the UID of the
> connecting
> client, can we extract that from Python ? (c.f. LOCAL_CREDS/SO_PEERCRED)
> If yes then that's a good first step toward local authentication without
> messing with https and credentials.
Yeah, but that's a mess and requires specially constructed packets on the
client side. I think the ssh tunnel approach is a lot easier.
Regards,
Anthony Liguori
>> httpu is HTTP over a unix domain socket, as opposed to over TCP. It's
>> used elsewhere (though not widely, obviously). It gives you basic
>> protection from non-root users (see your complaint above).
>
> It's not a complaint, I'm raising a problem, which IMHO is different.
> Adding core piece of OS machinery without thinking of security and
> authentication aspects from the start is a mistake that had been done on
> Unix already, it would be great to not go though the mess again just
> because we are eager to push a solution, the subsequent costs could
> reduce the benefits from the effort getting there ;-)
>
>> > > I expect we can do better than just printing "Internal Xend Error".
>> > > How much structure and useful information is there in an
>> > > xmlrpclib.Fault at the moment?
>> >
>> > Another good question, as we are defining an API to Xend I think
>> > the error handling question will become more and more important. The
>> > client will need more structure and informations about processing
>> > error, the full stack trace within xend might not be that useful
>> > (except for low level debugging) to the clients, but currently I just
>> > extract a string like
>> > "No such domain test"
>> > which is a bit hard to process correctly even in context. A list of
>> > predefined error code and meaning could help quite a bit along with
>> > just the error message.
>>
>> Sure. Do you have a list of error codes already (for libvirt, for
>> example)?
>
> Yes but for the moment they can't capture what's happening within
> Xend,
> so if the RPC fails they show up just as being from within Xend, with
> either a GET or POST information and the string found in the content of
> the HTTP answer:
> http://libvirt.org/html/libvirt-virterror.html#virErrorNumber
> associated docs:
> http://libvirt.org/errors.html
>
> Daniel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-12 1:44 ` Anthony Liguori
@ 2006-03-13 10:30 ` Ewan Mellor
0 siblings, 0 replies; 19+ messages in thread
From: Ewan Mellor @ 2006-03-13 10:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Ian Pratt, xen-devel
On Sat, Mar 11, 2006 at 07:44:20PM -0600, Anthony Liguori wrote:
> Ewan Mellor wrote:
> >Anthony, I've reviewed your XML-RPC patches. It all looks good, so I'm in
> >favour of putting them in straight away.
> Thanks!
> >I'd like to get the second patch in
> >straight away as well as the first, that is (for those watching at home) to
> >change xm to using XML-RPC, because I would like to deprecate the old
> >protocol sooner, rather than later. Making the XML-RPC interface the
> >primary
> >control path for Xen 3.0.2 will encourage third-parties to code to that
> >rather
> >than to the s-expression protocol, and that's a good thing.
> >
> Okay. So I'm going to take this to mean that we would deprecate
> S-Expression/HTTP for 3.0.2 and remove it in 3.0.3? That would be
> really nice.
Yes, I hope so. That's assuming that a) no-one objects and b) we get the
config file formats (both the main Xend config file and the xm create config
file) into XML too. I don't see any point removing the s-expression protocol
support unless we can remove the s-expression parser/generator too, but I
certainly think that we should deprecate it for 3.0.2.
> > How about if we prefixed
> >every function that we wish to expose to the messaging layer with
> >"public_"? So for example XendDomainInfo.send_sysrq would be named
> >public_send_sysrq instead. Then, we could use that to guide the
> >function registration, rather than having exclude lists and inline lists
> >of callable methods.
> >
> Isn't using an underscore a convention for making methods private in
> Python? I think, at least, pydoc ignores functions that start with an
> underscore.
A preceding underscore indicates that "from Module import *" should not import
the function, i.e. it's a weak "private" declaration. There's nothing special
about embedded underscores though.
I chose public_get_name over publicGetName because I thought that, at the
XML-RPC level, it would be conventional to have "xend.domain.get_name" as the
message name, rather than "xend.domain.GetName". That's personal taste
though, I don't have a strong opinion here.
> >>
> >> def xend_node_get_dmesg(self):
> >>- return self.xendGet(self.nodeurl('dmesg'))
> >>+ return self.srv.xend.node.dmesg.info()
> >>
> >
> >What you've done here is slipped the new XML-RPC layer under the existing
> >XendClient API. I don't think that we need to support that API at all.
> >All
> >the functions here just turn into stubs onto ServerProxy, and I don't think
> >that those stubs buy us anything.
> >
> Nope. Just compatibility. I know there are people using the XendClient
> API.
There are? Who? Anyone who's using the XendClient API, please speak up!
> >The reason I noticed is that I have been trying to make it so that
> >XendDomain and XendDomainInfo only receive arguments of the correct type,
> >with the casts to integers etc handled by the messaging layer. This
> >change you've made highlights the fact that there is now nowhere for
> >that type conversion to take place, because the messaging layer is more
> >generic, and doesn't understand the calls that it is dispatching.
> >That's OK -- it's a consequence of the removal of all that code in
> >SrvDomain -- but it's something to be aware of. If we adopt the naming
> >convention that I suggest above, then all methods accept only arguments
> >of the correct type _except_ for those named "public_xyz" -- those
> >methods must validate and convert their arguments appropriately.
> >
> Why? If a public_ function expects a domid and gets passed a string, it
> ought to throw an exception and the client should get it as an error.
I don't think that there's any user-facing call which should only accept a
domid -- they should all accept either a domain ID or a domain name. Of
course, xm cannot tell whether it is passing a domain ID or a domain name
(because names may be strings of digits too, and these are typed at the
command line) so I think that any public function must be able to cope with
either case.
That said, if there is some call that accepts only an integer, yes, it ought
to be able to throw an exception. (I think, actually, that we're talking at
cross purposes, and obliquely agreeing with each other).
Cheers,
Ewan.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-11 20:55 ` Ewan Mellor
2006-03-11 21:36 ` Daniel Veillard
2006-03-12 1:44 ` Anthony Liguori
@ 2006-03-14 6:58 ` Anthony Liguori
2006-03-14 8:35 ` Ewan Mellor
2 siblings, 1 reply; 19+ messages in thread
From: Anthony Liguori @ 2006-03-14 6:58 UTC (permalink / raw)
To: Ewan Mellor; +Cc: Ian Pratt, xen-devel
Hi Ewan,
I've made the changes you've requested except where I've described
below. After all the regressions complete, I'll push it out to the list
(sometime tomorrow as long as nothing fails miserably).
Ewan Mellor wrote:
> This is all a bit skanky, and could be easily cleaned up by introducing a
> naming convention for XendDomain, XendNode, etc. How about if we prefixed
> every function that we wish to expose to the messaging layer with
> "public_"? So for example XendDomainInfo.send_sysrq would be named
> public_send_sysrq instead. Then, we could use that to guide the
> function registration, rather than having exclude lists and inline lists
> of callable methods.
>
I went ahead and started using the public_ naming convention for
XendDomainInfo. It was fine for a couple of the methods but it got ugly
real quick for things like deviceDestroy as it's called in a bunch of
other places within Xend.
So, I've got two possible solutions for this. We could just keep the
white list or we could introduce new public_ methods within
XendDomainInfo that were just simple wrappers for the underlying
methods. It's seems a bit unnatural but less unnatural than peppering
calls to public_ functions through Xend. Thoughts?
> I can see why you've done this, but it just led me to wonder why
> XendDomain.domain_destroy exists at all. All it's doing is looking up a
> domain ID, checking that it's not the privileged domain (in the wrong
> order!) calling XendDomainInfo.destroy, and calling xc.domain_destroy in
> the case of an exception. We should move the check and the exception
> handling into XendDomainInfo.destroy, and then we can dispatch to that
> method straight away, without needing XendDomain.domain_destroy at all.
> The messaging layer already has the capability to lookup domain IDs --
> we should use it.
>
I've gone through and made sure that all XendDomain functions can accept
either domids or names so that effectively takes care of this hack. I
didn't refactor away the domain_destroy function though as it seems
independent of the XML-RPC stuff.
> I expect we can do better than just printing "Internal Xend Error". How
> much structure and useful information is there in an xmlrpclib.Fault at
> the moment?
>
This one is a bit tricky. We use faultCode to encode particular
exception types but I'm not sure what that buys us. I don't think
encoding OSError as a faultCode (which is what I think the most common
exception we toss other than XendError) really buys us much right now.
I think what we need to do is audit the methods in Xend, figure out what
the common errors are, *catch them within Xend*, and then rethrow them
as standardized Faults. Thoughts?
Regards,
Anthony Liguori
>> sys.exit(1)
>> except:
>> print "Unexpected error:", sys.exc_info()[0]
>>
>
> Looks like that's it! Thanks for all your hard work, Anthony, this is
> going to make a big difference to Xend's usefulness and maintainability,
> and you've done a good job of it. Let's get it into 3.0.2.
>
> Cheers,
>
> Ewan.
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] Xend XML-RPC Refactoring
2006-03-14 6:58 ` Anthony Liguori
@ 2006-03-14 8:35 ` Ewan Mellor
0 siblings, 0 replies; 19+ messages in thread
From: Ewan Mellor @ 2006-03-14 8:35 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Ian Pratt, xen-devel
On Tue, Mar 14, 2006 at 12:58:48AM -0600, Anthony Liguori wrote:
> Hi Ewan,
>
> I've made the changes you've requested except where I've described
> below. After all the regressions complete, I'll push it out to the list
> (sometime tomorrow as long as nothing fails miserably).
>
> Ewan Mellor wrote:
> >This is all a bit skanky, and could be easily cleaned up by introducing a
> >naming convention for XendDomain, XendNode, etc. How about if we prefixed
> >every function that we wish to expose to the messaging layer with
> >"public_"? So for example XendDomainInfo.send_sysrq would be named
> >public_send_sysrq instead. Then, we could use that to guide the
> >function registration, rather than having exclude lists and inline lists
> >of callable methods.
> >
> I went ahead and started using the public_ naming convention for
> XendDomainInfo. It was fine for a couple of the methods but it got ugly
> real quick for things like deviceDestroy as it's called in a bunch of
> other places within Xend.
>
> So, I've got two possible solutions for this. We could just keep the
> white list or we could introduce new public_ methods within
> XendDomainInfo that were just simple wrappers for the underlying
> methods. It's seems a bit unnatural but less unnatural than peppering
> calls to public_ functions through Xend. Thoughts?
Yes, I'd go with the latter. public_device_destroy does the type
conversion, argument validation (with errors thrown if necessary) and
then just calls deviceDestroy. All the other calls to deviceDestroy
from within XendDomainInfo itself don't need the type conversion etc, so just
point at deviceDestroy directly.
Ewan.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2006-03-14 8:35 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-31 21:25 [RFC] Xend XML-RPC Refactoring Anthony Liguori
2006-01-31 21:36 ` Ronald G Minnich
2006-01-31 21:47 ` Matt Sottile
2006-01-31 21:58 ` Anthony Liguori
2006-02-01 9:53 ` Ewan Mellor
2006-02-01 9:37 ` Daniel Veillard
-- strict thread matches above, loose matches on Subject: below --
2006-03-07 23:37 Ian Pratt
2006-03-08 0:07 ` Anthony Liguori
2006-03-11 20:55 ` Ewan Mellor
2006-03-11 21:36 ` Daniel Veillard
2006-03-11 22:20 ` Ewan Mellor
2006-03-12 1:46 ` Anthony Liguori
2006-03-12 9:27 ` Daniel Veillard
2006-03-12 9:57 ` Daniel Veillard
2006-03-12 17:41 ` Anthony Liguori
2006-03-12 1:44 ` Anthony Liguori
2006-03-13 10:30 ` Ewan Mellor
2006-03-14 6:58 ` Anthony Liguori
2006-03-14 8:35 ` Ewan Mellor
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.