2015-08-11 8 views
2

Or, Saltstack + docker-py AttributeError: 'RecentlyUsedContainer' object has no attribute 'lock'Зачем инспектировать.getfile дать мне файл, которого нет?

Я копался в этом вопросе безрезультатно. Я пытаюсь использовать SaltStack для управления изображениями/контейнерами докеров, но столкнулся с this problem.

Первоначально я использовал состояние соли docker.running, но представленное как команда не существует. Когда я изменил состояние на docker.running, я получил отслеживающий я отправил более в этом вопросе GitHub:

 ID: scheduler 
Function: docker.pulled 
    Result: False 
Comment: An exception occurred in this state: Traceback (most recent call last): 
      File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1563, in call 
       **cdata['kwargs']) 
      File "/usr/lib/python2.7/dist-packages/salt/states/dockerio.py", line 271, in pulled 
       returned = pull(name, tag=tag, insecure_registry=insecure_registry) 
      File "/usr/lib/python2.7/dist-packages/salt/modules/dockerio.py", line 1599, in pull 
       client = _get_client() 
      File "/usr/lib/python2.7/dist-packages/salt/modules/dockerio.py", line 277, in _get_client 
       client._version = client.version()['ApiVersion'] 
      File "/usr/local/lib/python2.7/dist-packages/docker/client.py", line 837, in version 
       return self._result(self._get(url), json=True) 
      File "/usr/local/lib/python2.7/dist-packages/docker/clientbase.py", line 86, in _get 
       return self.get(url, **self._set_request_timeout(kwargs)) 
      File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 310, in get 
       #: Stream response content default. 
      File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 279, in request 
      File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 374, in send 
       url=request.url, 
      File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 155, in send 
       **proxy_kwargs) 
      File "/usr/local/lib/python2.7/dist-packages/docker/unixconn/unixconn.py", line 74, in get_connection 
       with self.pools.lock: 
      AttributeError: 'RecentlyUsedContainer' object has no attribute 'lock' 
Started: 09:33:42.873628 
Duration: 22.115 ms 

После поиска Google немного больше и придумать ничего, я пошел вперед и начал reading the source.

После прочтения unixconn.py и понимая, что RecentlyUsedContainer доносился из urllib3, я пошел и разыскал источник, который и обнаружил, что там был _lock атрибут, который был изменен на lock некоторое время назад. Это показалось странным.

Я присмотрелся на импорт и понял, что unixconn.py пытается использовать запросы встроенный urllib3 и затем отступая к стенду только urllib3. Поэтому я проверил запросы urllib3 и обнаружил, что у него действительно есть изменение _lock -> lock. Но он был новее, чем моей версии. Поэтому я обновил запросы и снова попробовал. Все еще нет кубиков - то же самое AttributeError.

Теперь все начинает становиться странным.

Для того, чтобы получить информацию от моего соляного мастера, я начал выкидывать код докера-py и urllib3 на моем солоннике. Сначала я делал исключения с urllib3.__file__, чтобы убедиться, что я использовал нужный файл. Но иногда имя файла, которое оно вернет, было в файле и папке, которая не существует. Обычно он отображал /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.pyc, но когда я удалю этот файл, думая, что, возможно, кэширование .pyc вызывает проблему, он все равно скажет, что это был __file__, хотя его не было.

Затем я обнаружил inspect.getfile. И у меня такое же странное поведение - я могу удалить файл .pyc, и все же inspect.getfile(self.pools) вернет несуществующий файл.

Чтобы сделать жизнь еще лучше, я добавил

raise Exception('Pining for the Fjords') 

в

/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.py 

В конце RecentlyUsedContainer.__init__. Однако это исключение не поднимает.

И я только что подтвердил, что-то фактически лежал мне, потому что, несмотря на изменение unixconn.py

def get_connection(self, url, proxies=None):         
    import inspect               
    r = RecentlyUsedContainer(10)           
    raise Exception(inspect.getfile(r.__class__) + '\n' + r.__doc__) 

который возвращает /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/_collections.pyc, когда я иду редактировать что .pyc и изменить RecentlyUsedContainer «s I строка документации получить оригинальную docstring.

И, наконец, когда я редактировать /usr/lib/python2.7/dist-packages/urllib3/_collections.pyc и изменить это, строка документации (или один и тот же путь, но _collections.py вместо) ...

я все еще получаю ту же строку документации!

Почему здесь выполняется неправильный код, и как я могу узнать, где он находится, поэтому я могу исправить проблему?

ответ

1

Так что я наконец понял, проблема:

Это сделал что-то делать с солью. По какой-то причине, как соляной миньон импортировал библиотеку докер-ру, он сделал какой-то ... частичный захват импорта. Я подозреваю, что происходило то, что соль повторно импортировала только библиотеки докеров-py, поэтому, когда я внес изменения в эти файлы, изменения появятся.

Однако, поскольку механизм импорта Python будет сначала искать предварительно импортированные модули, код urllib3 никогда не был повторно импортирован.

В конечном итоге все, что требуется, чтобы перезапустить соль любимца:

salt 'my-minion' cmd.run "nohup /bin/sh -c 'sleep 10 && salt-call --local service.restart salt-minion'"