Ewan Mellor wrote:
On Tue, Mar 21, 2006 at 05:40:05PM -0600, Anthony Liguori wrote:
First off, xm-test is not passing 100%. The failures are all block
related and I've looked at each one and it appears to die for the same
reason the control runs are dying for (unable to very partition is
mounted with /proc/partitions). Every time I run xm-test, I get
different results (in the control) so it's hard to know for sure if this
introduces additional block regressions but I don't think it does.
Everything else passes consistently. I actually went ahead and made
VmError and XendError inherit from xmlrpc.Fault which means they show up
for the client as you'd expect.
I'm submitting this so that others can pound on it. I'll keep looking at
the block failures to see if we can't fix that too. It's all one big
patch since with the changes Ewan requested, it's not so easy to
separate anymore.
Neither of the new files (XMLRPCServer.py and xmlrpclib2.py) have made it into
this patch. Could you resubmit? Thanks,
Sorry, when I was collapsing to a single changeset I forgot to hg
addremove. New patch attached.
Regards,
Anthony Liguori
Ewan.
# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 106189dcd73ab812396d99e4a977308da1e30b74
# Parent 22f1618cf57cc4f0ffc2a19fea6c25c7b1f2c83a
Use XML-RPC as a transport for Xend instead of S-Expression/HTTP.
This changeset introduces a new XML-RPC service that runs in Xend and the
required changes to have xm use this new service by default.
Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/XendClient.py Wed Mar 22 00:01:40 2006
@@ -14,403 +14,11 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
#============================================================================
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
+from xen.util.xmlrpclib2 import ServerProxy
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
+XML_RPC_SOCKET = "/var/run/xend-xmlrpc.sock"
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
- UnixXendClientProtocol, \
- XendError
-
-def fileof(val):
- """Converter for passing configs or other 'large' data.
- Handles lists, files directly.
- Assumes a string is a file name and passes its contents.
- """
- if isinstance(val, types.ListType):
- return sxp.to_string(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)
-
-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)
-
- def xend_node(self):
- return self.xendGet(self.nodeurl())
-
- 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'))
-
- def xend_node_clear_dmesg(self):
- return self.xendPost(self.nodeurl('dmesg'),
- {'op' : 'clear' } )
-
- def xend_node_log(self):
- return self.xendGet(self.nodeurl('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 })
-
- def xend_domains(self):
- return self.xendGet(self.domainurl())
-
- def xend_list_domains(self, detail = True):
- return self.xendGet(self.domainurl(),
- {'detail': detail and '1' or '0'})
-
- def xend_domain_vcpuinfo(self, dom):
- return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
-
- def xend_domain_create(self, conf):
- return self.xendPost(self.domainurl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
-
- def xend_domain_restore(self, filename):
- return self.xendPost(self.domainurl(),
- {'op' : 'restore',
- 'file' : filename })
-
- def xend_domain_configure(self, id, conf):
- return self.xendPost(self.domainurl(id),
- {'op' : 'configure',
- 'config' : fileof(conf) })
-
- def xend_domain(self, id):
- return self.xendGet(self.domainurl(id))
-
- def xend_domain_wait_for_devices(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'wait_for_devices' })
-
- def xend_domain_unpause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'unpause' })
-
- def xend_domain_pause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pause' })
-
- def xend_domain_rename(self, id, name):
- return self.xendPost(self.domainurl(id),
- {'op' : 'rename',
- 'name' : name})
-
- def xend_domain_shutdown(self, id, reason):
- return self.xendPost(self.domainurl(id),
- {'op' : 'shutdown',
- 'reason' : reason})
-
- def xend_domain_sysrq(self, id, key):
- return self.xendPost(self.domainurl(id),
- {'op' : 'sysrq',
- 'key' : key})
-
- def xend_domain_destroy(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'destroy' })
-
- def xend_domain_save(self, id, filename):
- return self.xendPost(self.domainurl(id),
- {'op' : 'save',
- 'file' : 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 })
-
- def xend_domain_pincpu(self, id, vcpu, cpumap):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pincpu',
- 'vcpu' : vcpu,
- 'cpumap' : 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 })
-
- def xend_domain_cpu_sedf_get(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_get'})
-
- 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 })
-
- def xend_domain_maxmem_set(self, id, memory):
- return self.xendPost(self.domainurl(id),
- { 'op' : 'maxmem_set',
- 'memory' : 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
-
- def xend_domain_set_vcpus(self, dom, vcpus):
- return self.xendPost(self.domainurl(dom),
- {'op' : 'set_vcpus',
- 'vcpus' : vcpus })
-
- def xend_domain_devices(self, id, type):
- return self.xendPost(self.domainurl(id),
- {'op' : 'devices',
- 'type' : 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 })
-
- def xend_domain_device_destroy(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_destroy',
- 'type' : type,
- 'dev' : 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 = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/XendDomain.py Wed Mar 22 00:01:40 2006
@@ -355,7 +355,7 @@
def domain_unpause(self, domid):
"""Unpause domain execution."""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
log.info("Domain %s (%d) unpaused.", dominfo.getName(),
dominfo.getDomid())
return dominfo.unpause()
@@ -366,7 +366,7 @@
def domain_pause(self, domid):
"""Pause domain execution."""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
log.info("Domain %s (%d) paused.", dominfo.getName(),
dominfo.getDomid())
return dominfo.pause()
@@ -377,10 +377,10 @@
def domain_destroy(self, domid):
"""Terminate domain immediately."""
- if domid == PRIV_DOMAIN:
- raise XendError("Cannot destroy privileged domain %i" % domid)
-
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
+ if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
+ raise XendError("Cannot destroy privileged domain %s" % domid)
+
if dominfo:
val = dominfo.destroy()
else:
@@ -393,7 +393,7 @@
def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
"""Start domain migration."""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if dominfo.getDomid() == PRIV_DOMAIN:
raise XendError("Cannot migrate privileged domain %i" % domid)
@@ -418,7 +418,7 @@
"""
try:
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
if dominfo.getDomid() == PRIV_DOMAIN:
raise XendError("Cannot save privileged domain %i" % domid)
@@ -438,7 +438,7 @@
@param cpumap: string repr of list of usable cpus
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
# convert cpumap string into a list of ints
cpumap = map(lambda x: int(x),
cpumap.replace("[", "").replace("]", "").split(","))
@@ -451,7 +451,7 @@
warpu):
"""Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
mcuadv=mcuadv,
@@ -464,7 +464,7 @@
def domain_cpu_bvt_get(self, domid):
"""Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.bvtsched_domain_get(dominfo.getDomid())
except Exception, ex:
@@ -475,7 +475,7 @@
weight):
"""Set Simple EDF scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
latency, extratime, weight)
@@ -485,7 +485,7 @@
def domain_cpu_sedf_get(self, domid):
"""Get Simple EDF scheduler parameters for a domain.
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
try:
sedf_info = xc.sedf_domain_get(dominfo.getDomid())
@@ -507,7 +507,7 @@
@param mem: memory limit (in MiB)
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
maxmem = int(mem) * 1024
try:
return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
@@ -521,7 +521,7 @@
@param last: last IO port
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
nr_ports = last - first + 1
try:
return xc.domain_ioport_permission(dominfo.getDomid(),
@@ -538,7 +538,7 @@
@param last: last IO port
@return: 0 on success, -1 on error
"""
- dominfo = self.domain_lookup(domid)
+ dominfo = self.domain_lookup_by_name_or_id_nr(domid)
nr_ports = last - first + 1
try:
return xc.domain_ioport_permission(dominfo.getDomid(),
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/XendError.py Wed Mar 22 00:01:40 2006
@@ -15,9 +15,12 @@
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
#============================================================================
-class XendError(ValueError):
+from xmlrpclib import Fault
+
+class XendError(Fault):
def __init__(self, value):
+ Fault.__init__(self, 2, value)
self.value = value
def __str__(self):
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/XendRoot.py Wed Mar 22 00:01:40 2006
@@ -59,6 +59,10 @@
"""Default for the flag indicating whether xend should run an http
server."""
xend_http_server_default = 'no'
+
+ xend_tcp_xmlrpc_server_default = 'no'
+
+ xend_unix_xmlrpc_server_default = 'yes'
"""Default interface address xend listens at. """
xend_address_default = ''
@@ -180,6 +184,12 @@
"""
return self.get_config_bool("xend-http-server",
self.xend_http_server_default)
+ def get_xend_tcp_xmlrpc_server(self):
+ return self.get_config_bool("xend-tcp-xmlrpc-server",
self.xend_tcp_xmlrpc_server_default)
+
+ def get_xend_unix_xmlrpc_server(self):
+ return self.get_config_bool("xend-unix-xmlrpc-server",
self.xend_unix_xmlrpc_server_default)
+
def get_xend_relocation_server(self):
"""Get the flag indicating whether xend should run a relocation server.
"""
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/server/SrvServer.py Wed Mar 22 00:01:40 2006
@@ -52,6 +52,7 @@
from xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
+from XMLRPCServer import XMLRPCServer
xroot = XendRoot.instance()
@@ -114,4 +115,10 @@
path = xroot.get_xend_unix_path()
log.info('unix path=' + path)
servers.add(UnixHttpServer(root, path))
+
+ if xroot.get_xend_tcp_xmlrpc_server():
+ servers.add(XMLRPCServer(True))
+
+ if xroot.get_xend_unix_xmlrpc_server():
+ servers.add(XMLRPCServer())
return servers
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xm/create.py Wed Mar 22 00:01:40 2006
@@ -30,7 +30,7 @@
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
@@ -813,8 +813,8 @@
"""
try:
- dominfo = server.xend_domain_create(config)
- except XendError, ex:
+ dominfo = server.xend.domain.create(config)
+ except Exception, ex:
import signal
if vncpid:
os.kill(vncpid, signal.SIGKILL)
@@ -822,13 +822,17 @@
dom = sxp.child_value(dominfo, 'name')
- if server.xend_domain_wait_for_devices(dom) < 0:
- server.xend_domain_destroy(dom)
+ try:
+ server.xend.domain.waitForDevices(dom)
+ except:
+ server.xend.domain.destroy(dom)
err("Device creation failed for domain %s" % dom)
if not opts.vals.paused:
- if server.xend_domain_unpause(dom) < 0:
- server.xend_domain_destroy(dom)
+ try:
+ server.xend.domain.unpause(dom)
+ except:
+ server.xend.domain.destroy(dom)
err("Failed to unpause domain %s" % dom)
opts.info("Started domain %s" % (dom))
return int(sxp.child_value(dominfo, 'domid'))
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xm/main.py Wed Mar 22 00:01:40 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
@@ -39,6 +39,7 @@
import console
+from xen.xend.XendClient import server
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
@@ -319,8 +320,7 @@
err("xm save: Unable to create file %s" % savefile)
sys.exit(1)
- from xen.xend.XendClient import server
- server.xend_domain_save(dom, savefile)
+ server.xend.domain.save(dom, savefile)
def xm_restore(args):
arg_check(args, "restore", 1)
@@ -331,16 +331,14 @@
err("xm restore: Unable to read file %s" % savefile)
sys.exit(1)
- from xen.xend.XendClient import server
- server.xend_domain_restore(savefile)
+ server.xend.domain.restore(savefile)
def getDomains(domain_names):
- from xen.xend.XendClient import server
if domain_names:
- return map(server.xend_domain, domain_names)
- else:
- return server.xend_list_domains()
+ return map(server.xend.domain, domain_names)
+ else:
+ return server.xend.domains(1)
def xm_list(args):
@@ -416,12 +414,11 @@
def xm_vcpu_list(args):
- from xen.xend.XendClient import server
if args:
- dominfo = map(server.xend_domain_vcpuinfo, args)
- else:
- doms = server.xend_list_domains(False)
- dominfo = map(server.xend_domain_vcpuinfo, doms)
+ dominfo = map(server.xend.domain.getVCPUInfo, args)
+ else:
+ doms = server.xend.domains(False)
+ dominfo = map(server.xend.domain.getVCPUInfo, doms)
print 'Name ID VCPU CPU State Time(s)
CPU Affinity'
@@ -475,8 +472,7 @@
cpumap = map(lambda x: int(x), cpumap)
cpumap.sort()
- from xen.xend.XendClient import server
- for x in server.xend_node()[1:]:
+ for x in server.xend.node.info()[1:]:
if len(x) > 1 and x[0] == 'nr_cpus':
nr_cpus = int(x[1])
# normalize cpumap by modulus nr_cpus, and drop duplicates
@@ -532,21 +528,18 @@
arg_check(args, "pause", 1)
dom = args[0]
- from xen.xend.XendClient import server
- server.xend_domain_pause(dom)
+ server.xend.domain.pause(dom)
def xm_unpause(args):
arg_check(args, "unpause", 1)
dom = args[0]
- from xen.xend.XendClient import server
- server.xend_domain_unpause(dom)
+ server.xend.domain.unpause(dom)
def xm_rename(args):
arg_check(args, "rename", 2)
- from xen.xend.XendClient import server
- server.xend_domain_rename(args[0], args[1])
+ server.xend.domain.setName(args[0], args[1])
def xm_subcommand(command, args):
cmd = __import__(command, globals(), locals(), 'xen.xm')
@@ -574,8 +567,7 @@
vcpu = int(args[1])
cpumap = cpu_make_map(args[2])
- from xen.xend.XendClient import server
- server.xend_domain_pincpu(dom, vcpu, cpumap)
+ server.xend.domain.pincpu(dom, vcpu, cpumap)
def xm_mem_max(args):
arg_check(args, "mem-max", 2)
@@ -583,8 +575,7 @@
dom = args[0]
mem = int_unit(args[1], 'm')
- from xen.xend.XendClient import server
- server.xend_domain_maxmem_set(dom, mem)
+ server.xend.domain.maxmem_set(dom, mem)
def xm_mem_set(args):
arg_check(args, "mem-set", 2)
@@ -592,20 +583,17 @@
dom = args[0]
mem_target = int_unit(args[1], 'm')
- from xen.xend.XendClient import server
- server.xend_domain_mem_target_set(dom, mem_target)
+ server.xend.domain.setMemoryTarget(dom, mem_target)
def xm_vcpu_set(args):
arg_check(args, "vcpu-set", 2)
- from xen.xend.XendClient import server
- server.xend_domain_set_vcpus(args[0], int(args[1]))
+ server.xend.domain.setVCpuCount(args[0], int(args[1]))
def xm_destroy(args):
arg_check(args, "destroy", 1)
- from xen.xend.XendClient import server
- server.xend_domain_destroy(args[0])
+ server.xend.domain.destroy(args[0])
def xm_domid(args):
@@ -613,8 +601,7 @@
name = args[0]
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
+ dom = server.xend.domain(name)
print sxp.child_value(dom, 'domid')
def xm_domname(args):
@@ -622,23 +609,20 @@
name = args[0]
- from xen.xend.XendClient import server
- dom = server.xend_domain(name)
+ dom = server.xend.domain(name)
print sxp.child_value(dom, 'name')
def xm_sched_bvt(args):
arg_check(args, "sched-bvt", 6)
dom = args[0]
v = map(long, args[1:6])
- from xen.xend.XendClient import server
- server.xend_domain_cpu_bvt_set(dom, *v)
+ server.xend.domain.cpu_bvt_set(dom, *v)
def xm_sched_bvt_ctxallow(args):
arg_check(args, "sched-bvt-ctxallow", 1)
slice = int(args[0])
- from xen.xend.XendClient import server
- server.xend_node_cpu_bvt_slice_set(slice)
+ server.xend.node.cpu_bvt_slice_set(slice)
def xm_sched_sedf(args):
def ns_to_ms(val):
@@ -695,13 +679,12 @@
'Slice(ms)', 'Lat(ms)',
'Extra','Weight')
- from xen.xend.XendClient import server
doms = filter(lambda x : domid_match(domid, x),
[parse_doms_info(dom) for dom in getDomains("")])
for d in doms:
# fetch current values so as not to clobber them
sedf_info = \
- parse_sedf_info(server.xend_domain_cpu_sedf_get(d['dom']))
+ parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
sedf_info['name'] = d['name']
# update values in case of call to set
@@ -713,7 +696,7 @@
v = map(int, [sedf_info['period'], sedf_info['slice'],
sedf_info['latency'],sedf_info['extratime'],
sedf_info['weight']])
- rv = server.xend_domain_cpu_sedf_set(d['dom'], *v)
+ rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
if int(rv) != 0:
err("Failed to set sedf parameters (rv=%d)."%(rv))
@@ -725,8 +708,7 @@
def xm_info(args):
arg_check(args, "info", 0)
- from xen.xend.XendClient import server
- info = server.xend_node()
+ info = server.xend.node.info()
for x in info[1:]:
if len(x) < 2:
@@ -738,8 +720,7 @@
arg_check(args, "console", 1)
dom = args[0]
- from xen.xend.XendClient import server
- info = server.xend_domain(dom)
+ info = server.xend.domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
console.execConsole(domid)
@@ -768,17 +749,15 @@
if not (1 <= len(myargs) <= 2):
err('Invalid arguments: ' + str(myargs))
- from xen.xend.XendClient import server
if not gopts.vals.clear:
- print server.xend_node_get_dmesg()
- else:
- server.xend_node_clear_dmesg()
+ print server.xend.node.dmesg.info()
+ else:
+ server.xend.node.dmesg.clear()
def xm_log(args):
arg_check(args, "log", 0)
- from xen.xend.XendClient import server
- print server.xend_node_log()
+ print server.xend.node.log()
def parse_dev_info(info):
def get_info(n, t, d):
@@ -826,13 +805,12 @@
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vif')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vif'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
if hdr == 0:
print 'Idx BE MAC Addr. handle state evt-ch
tx-/rx-ring-ref BE-path'
hdr = 1
@@ -857,13 +835,12 @@
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vbd')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vbd'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
if hdr == 0:
print 'Vdev BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -887,13 +864,12 @@
print 'No domain parameter given'
sys.exit(1)
dom = params[0]
- from xen.xend.XendClient import server
if use_long:
- devs = server.xend_domain_devices(dom, 'vtpm')
+ devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
- for x in server.xend_domain_devices(dom, 'vtpm'):
+ for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'):
if hdr == 0:
print 'Idx BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -919,8 +895,7 @@
if len(args) == 5:
vbd.append(['backend', args[4]])
- from xen.xend.XendClient import server
- server.xend_domain_device_create(dom, vbd)
+ server.xend.domain.device_create(dom, vbd)
def xm_network_attach(args):
@@ -932,8 +907,7 @@
for a in args[1:]:
vif.append(a.split("="))
- from xen.xend.XendClient import server
- server.xend_domain_device_create(dom, vif)
+ server.xend.domain.device_create(dom, vif)
def detach(args, command, deviceClass):
@@ -942,8 +916,7 @@
dom = args[0]
dev = args[1]
- from xen.xend.XendClient import server
- server.xend_domain_device_destroy(dom, deviceClass, dev)
+ server.xend.domain.destroyDevice(dom, deviceClass, dev)
def xm_block_detach(args):
@@ -955,7 +928,6 @@
def xm_vnet_list(args):
- from xen.xend.XendClient import server
try:
(options, params) = getopt.gnu_getopt(args, 'l', ['long'])
except getopt.GetoptError, opterr:
@@ -990,13 +962,11 @@
print "File not found: %s" % conf
sys.exit(1)
- from xen.xend.XendClient import server
server.xend_vnet_create(conf)
def xm_vnet_delete(args):
arg_check(args, "vnet-delete", 1)
vnet = args[0]
- from xen.xend.XendClient import server
server.xend_vnet_delete(vnet)
commands = {
@@ -1132,23 +1102,10 @@
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@xxxxxxxxxxxxxxxxxxx"
- 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@xxxxxxxxxxxxxxxxxxx"
- raise
except SystemExit:
+ sys.exit(1)
+ except xmlrpclib.Fault, ex:
+ print "Xend generated an internal fault: %s" % ex.faultString
sys.exit(1)
except:
print "Unexpected error:", sys.exc_info()[0]
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xm/migrate.py Wed Mar 22 00:01:40 2006
@@ -60,4 +60,4 @@
opts.err('Invalid arguments: ' + str(args))
dom = args[0]
dst = args[1]
- server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
+ server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xm/shutdown.py Wed Mar 22 00:01:40 2006
@@ -53,8 +53,8 @@
use='Shutdown and reboot.')
def shutdown(opts, doms, mode, wait):
- if doms == None: doms = server.xend_domains()
- dom0_name = sxp.child_value(server.xend_domain(0), 'name')
+ if doms == None: doms = server.xend.domains(0)
+ dom0_name = sxp.child_value(server.xend.domain(0), 'name')
for x in [dom0_name, DOM0_ID]:
if x in doms:
if opts.vals.all:
@@ -62,10 +62,10 @@
else:
opts.err("Can't specify Domain-0")
for d in doms:
- server.xend_domain_shutdown(d, mode)
+ server.xend.domain.shutdown(d, mode)
if wait:
while doms:
- alive = server.xend_domains()
+ alive = server.xend.domains(0)
dead = []
for d in doms:
if d in alive: continue
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/xm/sysrq.py
--- a/tools/python/xen/xm/sysrq.py Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xm/sysrq.py Wed Mar 22 00:01:40 2006
@@ -28,4 +28,4 @@
if len(args) < 2: opts.err('Missing sysrq character')
dom = args[0]
req = ord(args[1][0])
- server.xend_domain_sysrq(dom, req)
+ server.xend.domain.sysrq(dom, req)
diff -r 22f1618cf57c -r 106189dcd73a tools/python/xen/util/xmlrpclib2.py
--- /dev/null Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/util/xmlrpclib2.py Wed Mar 22 00:01:40 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@xxxxxxxxxx>
+#============================================================================
+
+"""
+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 probably 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, rest) = uri.split(':', 1)
+ if protocol == 'httpu':
+ uri = 'http:' + rest
+ 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(fault)
+ 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 22f1618cf57c -r 106189dcd73a
tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null Tue Mar 21 17:57:23 2006
+++ b/tools/python/xen/xend/server/XMLRPCServer.py Wed Mar 22 00:01:40 2006
@@ -0,0 +1,106 @@
+#============================================================================
+# 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@xxxxxxxxxx>
+#============================================================================
+
+from xen.xend import XendDomain, XendDomainInfo, XendNode, \
+ XendLogging, XendDmesg
+from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+
+from xen.xend.XendClient import XML_RPC_SOCKET
+
+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')
+ 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, use_tcp=False):
+ self.ready = False
+ self.use_tcp = use_tcp
+
+ def run(self):
+ if self.use_tcp:
+ # bind to something fixed for now as we may eliminate
+ # tcp support completely.
+ self.server = TCPXMLRPCServer(("localhost", 8005))
+ else:
+ self.server = UnixXMLRPCServer(XML_RPC_SOCKET)
+
+ # 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()
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|