xmlrpcserver.py
来自「xen虚拟机源代码安装包」· Python 代码 · 共 258 行
PY
258 行
#============================================================================# 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># Copyright (C) 2006 XenSource Ltd.#============================================================================import errnoimport socketimport typesimport xmlrpclibfrom xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServertry: from SSLXMLRPCServer import SSLXMLRPCServer ssl_enabled = Trueexcept ImportError: ssl_enabled = Falsefrom xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNodefrom xen.xend import XendLogging, XendDmesgfrom xen.xend.XendClient import XML_RPC_SOCKETfrom xen.xend.XendConstants import DOM_STATE_RUNNINGfrom xen.xend.XendLogging import logfrom xen.xend.XendError import XendInvalidDomain# vcpu_avail is a long and is not needed by the clients. It's far easier# to just remove it then to try and marshal the long.def fixup_sxpr(sexpr): ret = [] for k in sexpr: if type(k) in (list, tuple): if len(k) != 2 or k[0] != 'vcpu_avail': ret.append(fixup_sxpr(k)) else: ret.append(k) return retdef lookup(domid): info = XendDomain.instance().domain_lookup(domid) return infodef dispatch(domid, fn, args): info = lookup(domid) return getattr(info, fn)(*args)def domain(domid, full = 0): info = lookup(domid) return fixup_sxpr(info.sxpr(not full))def domains(detail = True, full = False): return domains_with_state(detail, DOM_STATE_RUNNING, full)def domains_with_state(detail, state, full): if detail: domains = XendDomain.instance().list_sorted(state) ret = [] for dom in domains: try: ret.append(fixup_sxpr(dom.sxpr(not full))) except: log.warn("Failed to query SXPR for domain %s" % str(dom)) pass return ret else: return XendDomain.instance().list_names(state)def domain_create(config): info = XendDomain.instance().domain_create(config) return fixup_sxpr(info.sxpr())def domain_restore(src, paused=False): info = XendDomain.instance().domain_restore(src, paused) return fixup_sxpr(info.sxpr())def get_log(): f = open(XendLogging.getLogFilename(), 'r') try: return f.read() finally: f.close()methods = ['device_create', 'device_configure', 'destroyDevice','getDeviceSxprs', 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', 'send_sysrq', 'getVCPUInfo', 'waitForDevices', 'getRestartCount', 'getBlockDeviceClass']exclude = ['domain_create', 'domain_restore']class XMLRPCServer: def __init__(self, auth, use_xenapi, use_tcp = False, ssl_key_file = None, ssl_cert_file = None, host = "localhost", port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None): self.use_tcp = use_tcp self.port = port self.host = host self.path = path self.hosts_allowed = hosts_allowed self.ssl_key_file = ssl_key_file self.ssl_cert_file = ssl_cert_file self.ready = False self.running = True self.auth = auth self.xenapi = use_xenapi and XendAPI.XendAPI(auth) or None def run(self): authmsg = (self.auth == XendAPI.AUTH_NONE and "; authentication has been disabled for this server." or ".") try: if self.use_tcp: using_ssl = self.ssl_key_file and self.ssl_cert_file log.info("Opening %s XML-RPC server on %s%d%s", using_ssl and 'HTTPS' or 'TCP', self.host and '%s:' % self.host or 'all interfaces, port ', self.port, authmsg) if using_ssl: if not ssl_enabled: raise ValueError("pyOpenSSL not installed. " "Unable to start HTTPS XML-RPC server") self.server = SSLXMLRPCServer( (self.host, self.port), self.hosts_allowed, self.xenapi is not None, logRequests = False, ssl_key_file = self.ssl_key_file, ssl_cert_file = self.ssl_cert_file) else: self.server = TCPXMLRPCServer( (self.host, self.port), self.hosts_allowed, self.xenapi is not None, logRequests = False) else: log.info("Opening Unix domain socket XML-RPC server on %s%s", self.path, authmsg) self.server = UnixXMLRPCServer(self.path, self.hosts_allowed, self.xenapi is not None, logRequests = False) except socket.error, exn: log.error('Cannot start server: %s!', exn.args[1]) ready = True running = False return except Exception, e: log.exception('Cannot start server: %s!', e) ready = True running = False return # Register Xen API Functions # ------------------------------------------------------------------- # exportable functions are ones that do not begin with '_' # and has the 'api' attribute. for meth_name in dir(self.xenapi): if meth_name[0] != '_': meth = getattr(self.xenapi, meth_name) if callable(meth) and hasattr(meth, 'api'): self.server.register_function(meth, getattr(meth, 'api')) self.server.register_instance(XendAPI.XendAPIAsyncProxy(self.xenapi)) # Legacy deprecated xm xmlrpc api # -------------------------------------------------------------------- # 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) 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', 'send_debug_keys'], '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(domains_with_state, 'xend.domains_with_state') 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') # A couple of the security functions from xen.util.xsm import xsm as security for name in security.xmlrpc_exports: fn = getattr(security, name) self.server.register_function(fn, "xend.security.%s" % name) self.server.register_introspection_functions() self.ready = True # Custom runloop so we can cleanup when exiting. # ----------------------------------------------------------------- try: while self.running: self.server.handle_request() finally: self.shutdown() def cleanup(self): log.debug('XMLRPCServer.cleanup()') if hasattr(self, 'server'): try: # This is here to make sure the socket is actually # cleaned up when close() is called. Otherwise # SO_REUSEADDR doesn't take effect. To replicate, # try 'xend reload' and look for EADDRINUSE. # # May be caued by us calling close() outside of # the listen()ing thread. self.server.socket.shutdown(2) except socket.error, e: pass # ignore any socket errors try: self.server.socket.close() except socket.error, e: pass def shutdown(self): self.running = False if self.ready: self.ready = False self.cleanup()
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?