2012-07-30 10 views
10

Estoy tratando de interactuar con supervisord, y me gustaría hablar con él en un socket Unix (es un entorno de alojamiento compartido).¿Utiliza Python xmlrpclib con conectores de dominio Unix?

Lo que he probado hasta ahora es:

import xmlrpclib 
server = xmlrpclib.ServerProxy('unix:///path/to/supervisor.sock/RPC2') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/xmlrpclib.py", line 1549, in __init__ 
    raise IOError, "unsupported XML-RPC protocol" 
IOError: unsupported XML-RPC protocol 

/path/to/supervisor.sock sin duda existe. Los URI de la forma 'unix: ///path/to/supervisor.sock/RPC2' son utilizados por supervisord, que es donde obtuve la idea. Los documentos no discuten los zócalos de Unix: http://docs.python.org/library/xmlrpclib.html.

¿Esto es posible? ¿Debo usar una biblioteca diferente?

Respuesta

13

xmlrpclib requiere que la url aprobada comience con http o https. La forma de evitar esto es definir un transporte personalizado que ignore esa url. Aquí hay algo de código usando el transporte del supervisor:

import supervisor.xmlrpc 
import xmlrpclib 

proxy = xmlrpclib.ServerProxy('http://127.0.0.1', 
           transport=supervisor.xmlrpc.SupervisorTransport(
            None, None, serverurl='unix://'+socketpath)) 

proxy.supervisor.getState() 

En caso de que no es útil, aquí está una versión actualizada del código que se encuentra here:

class UnixStreamHTTPConnection(httplib.HTTPConnection, object): 
    def __init__(self, *args, **kwargs): 
     self.socketpath = kwargs.pop('socketpath') 
     super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs) 

    def connect(self): 
     self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
     self.sock.connect_ex(self.socketpath) 

class UnixStreamTransport(xmlrpclib.Transport, object): 
    def __init__(self, *args, **kwargs): 
     self.socketpath = kwargs.pop('socketpath') 
     super(UnixStreamTransport, self).__init__(*args, **kwargs) 
6

He aquí un ejemplo actualizado de aprovechamiento xmlrpclib hablar con el supervisor :

import httplib 
import socket 
import xmlrpclib 

class UnixStreamHTTPConnection(httplib.HTTPConnection): 
    def connect(self): 
     self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
     self.sock.connect(self.host) 

class UnixStreamTransport(xmlrpclib.Transport, object): 
    def __init__(self, socket_path): 
     self.socket_path = socket_path 
     super(UnixStreamTransport, self).__init__() 

    def make_connection(self, host): 
     return UnixStreamHTTPConnection(self.socket_path) 


server = xmlrpclib.Server('http://arg_unused', transport=UnixStreamTransport("/var/run/supervisor.sock")) 
print(server.supervisor.getState()) 

Como ya se ha mencionado, tenemos que especificar un URL maniquí con http: // o https: // y luego especificar un transporte personalizado para manejar la socket de dominio

2

Mezcla las respuestas anteriores, esto es lo que funciona para mí ...

import httplib 
import socket 
import xmlrpclib 

class UnixStreamHTTPConnection(httplib.HTTPConnection, object): 
    def __init__(self, *args, **kwargs): 
     self.socketpath = kwargs.pop('socketpath') 
     super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs) 

    def connect(self): 
     self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
     self.sock.connect(self.socketpath) 

class UnixStreamTransport(xmlrpclib.Transport, object): 
    def __init__(self, *args, **kwargs): 
     self.socketpath = kwargs.pop('socketpath') 
     super(UnixStreamTransport, self).__init__(*args, **kwargs) 

    def make_connection(self, host): 
     return UnixStreamHTTPConnection(host, socketpath=self.socketpath) 

server = xmlrpclib.ServerProxy('http://arg_unused', transport=UnixStreamTransport(socketpath="path/to/supervisor.sock")) 
print server.supervisor.getState() 
Cuestiones relacionadas