# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 5c9c44fc1c39dc6b08535e33b34c12d684c27d77
# Parent 2c77d26871f7463dd1ebb347cd615f18045ed8da
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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendClient.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendDomain.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendError.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/XendRoot.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/create.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/main.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/migrate.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/shutdown.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/sysrq.py
--- a/tools/python/xen/xm/sysrq.py Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xm/sysrq.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/util/xmlrpclib2.py
--- /dev/null Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/util/xmlrpclib2.py Thu Mar 23 10:25:37 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 2c77d26871f7 -r 5c9c44fc1c39
tools/python/xen/xend/server/XMLRPCServer.py
--- /dev/null Thu Mar 23 09:58:39 2006
+++ b/tools/python/xen/xend/server/XMLRPCServer.py Thu Mar 23 10:25:37 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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|