Разговор с супервизором через xmlrpc

Я пытаюсь поговорить с supervisor через xmlrpc. На основе supervisorctl (особенно эта строка), у меня есть следующее, что вроде должно работать, и действительно работает, поскольку он подключается достаточно, чтобы получить сообщение об ошибке от сервера:

#socketpath is the full path to the socket, which exists
# None and None are the default username and password in the supervisorctl options
In [12]: proxy = xmlrpclib.ServerProxy('http://127.0.0.1', transport=supervisor.xmlrpc.SupervisorTransport(None, None, serverurl='unix://'+socketpath))

In [13]: proxy.supervisor.getState()

В результате эта ошибка:

---------------------------------------------------------------------------
ProtocolError                             Traceback (most recent call last)
/home/marcintustin/webapps/django/oneclickcosvirt/oneclickcos/<ipython-input-13-646258924bc2> in <module>()
----> 1 proxy.supervisor.getState()

/usr/local/lib/python2.7/xmlrpclib.pyc in __call__(self, *args)
   1222         return _Method(self.__send, "%s.%s" % (self.__name, name))
   1223     def __call__(self, *args):
-> 1224         return self.__send(self.__name, args)
   1225
   1226 ##


/usr/local/lib/python2.7/xmlrpclib.pyc in __request(self, methodname, params)
   1576             self.__handler,
   1577             request,
-> 1578             verbose=self.__verbose
   1579             )
   1580

/home/marcintustin/webapps/django/oneclickcosvirt/lib/python2.7/site-packages/supervisor/xmlrpc.pyc in request(self, host, handler, request_body, verbose)
    469                                           r.status,
    470                                           r.reason,
--> 471                                           '' )
    472         data = r.read()
    473         p, u = self.getparser()

ProtocolError: <ProtocolError for 127.0.0.1/RPC2: 401 Unauthorized>

Это unix_http_server раздел supervisord.conf:

[unix_http_server]
file=/home/marcintustin/webapps/django/oneclickcosvirt/tmp/supervisor.sock   ; (the path to the socket file)
;chmod=0700                 ; socket file mode (default 0700)
;chown=nobody:nogroup       ; socket file uid:gid owner
;username=user              ; (default is no username (open server))
;password=123               ; (default is no password (open server))

Так что проблем с аутентификацией быть не должно.

Кажется, что мой код во всех существенных отношениях идентичен эквивалентному коду из supervisorctl, но supervisorctl действительно работает. Что я делаю не так?


person Marcin    schedule 31.07.2012    source источник


Ответы (2)


Ваш код выглядит в основном правильно. Я использую Supervisor 3.0 с Python 2.7 и получаю следующее:

import supervisor.xmlrpc
import xmlrpclib

p = xmlrpclib.ServerProxy('http://127.0.0.1',
        transport=supervisor.xmlrpc.SupervisorTransport(
            None, None,
            'unix:///home/lars/lib/supervisor/tmp/supervisor.sock'))

print p.supervisor.getState()

Я получил:

{'statename': 'RUNNING', 'statecode': 1}

Вы уверены, что ваш работающий экземпляр Supervisor использует именно тот файл конфигурации, который, по вашему мнению, используется? Что, если вы запустите supervisord в режиме отладки, вы увидите соединение?

person larsks    schedule 31.07.2012
comment
Сокет появился в файловой системе только после того, как я добавил в этот файл раздел unix_http_server, так что да, я почти уверен. Поиграюсь с режимом отладки. - person Marcin; 31.07.2012
comment
Соединение не отображается в режиме отладки. Я использую django-supervisor, через который я могу запустить supervisorctl, соединения которого также не отображаются. Не уверен, что с этим случилось. Я почти уверен, что это использует сокет, потому что, когда я добавил сокет в конфигурацию без перезапуска супервизора, он не подключился. - person Marcin; 31.07.2012
comment
Хорошо, по какой-то причине это работает, если я явно задаю имя пользователя и пароль. Я предполагаю, что за кулисами django-supervisor выполняет какую-то бесполезную магию. У меня также есть связанный с этим вопрос: stackoverflow.com/questions/11729159/, если вы хотите ответить на него, я тоже соглашусь. Если нет, я добавлю свой собственный ответ. - person Marcin; 31.07.2012

Я не использую ServerProxy из xmlrpclib, вместо этого я использую класс Server, и мне не нужно определять какие-либо транспорты или пути к сокетам. Не уверен, что это требуется для ваших целей, но вот тонкий клиент, которым я пользуюсь довольно часто. Это в значительной степени прямо из документов.

python -c "import xmlrpclib;\
supervisor_client = xmlrpclib.Server('http://localhost:9001/RPC2');\
print( supervisor_client.supervisor.stopProcess(<some_proc_name>) )"
person Will Charlton    schedule 07.08.2015