2012-07-30 14 views
10

Próbuję wejść w interakcję z supervisord i chciałbym z nim porozmawiać przez gniazdo unix (jest to wspólne środowisko hostingu).Użyj Python xmlrpclib z gniazdami domeny unix?

Co próbowałem tak daleko jest:

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 pewno istnieje. Identyfikatory URI w formularzu "unix: ///path/to/supervisor.sock/RPC2" są używane przez supervisord, w której mam pomysł. Dokumenty nie omawiają gniazd unixowych: http://docs.python.org/library/xmlrpclib.html.

Czy to możliwe? Czy powinienem użyć innej biblioteki?

Odpowiedz

13

xmlrpclib wymaga, aby adres URL przeszedł pomyślnie z http lub https. Rozwiązaniem jest zdefiniowanie niestandardowego transportu, który ignoruje ten adres URL. Oto niektóre kodu z wykorzystaniem transportu z przełożonym:

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() 

W przypadku, gdy nie jest to przydatne, tutaj jest zaktualizowana wersja kodu znalezione 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

Oto zaktualizowana przykład za korzystanie xmlrpclib porozmawiać z przełożonym :

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()) 

Jak już wspomniano musimy określić obojętne URL http: // lub https: //, a następnie określić, transport własny do obsługi Gniazdo domeny

2

Mieszanie powyższych odpowiedzi, oto, co działa dla mnie ...

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() 
Powiązane problemy