【问题标题】:Why would inspect.getfile give me a file that's not there?为什么 inspect.getfile 会给我一个不存在的文件?
【发布时间】:2015-08-11 15:23:59
【问题描述】:

或者,Saltstack + docker-py AttributeError: 'RecentlyUsedContainer' object has no attribute 'lock'

我一直在研究这个问题,但无济于事。我正在尝试使用 SaltStack 管理我的 docker 图像/容器,但遇到了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

在谷歌上搜索了一下,什么也没找到,我继续开始reading the source

在阅读了unixconn.py 并意识到RecentlyUsedContainer 来自urllib3 之后,我去追踪了它的来源,发现有一个_lock 属性不久前被更改为lock。这看起来很奇怪。

我仔细查看了导入并意识到unixconn.py 正在尝试使用请求的内置 urllib3 并且然后回退到独立的 urllib3。所以我检查了请求 urllib3 并发现它确实有,确实有 _lock -> lock 更改。但它比 my 版本的请求更新。所以我升级了请求并再次尝试。仍然没有骰子 - 相同的AttributeError

现在事情开始变得奇怪了。

为了将信息返回给我的 salt master,我开始在我的 salt minion 上使用 docker-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的文档字符串时,我得到原始文档字符串

最后,当我编辑/usr/lib/python2.7/dist-packages/urllib3/_collections.pyc 并更改它的 文档字符串时,(或相同的路径但_collections.py 代替)...

我仍然得到相同的文档字符串!

为什么在这里执行了错误的代码,我怎样才能找到它的位置以便我可以修复问题?

【问题讨论】:

    标签: python python-2.7 python-import urllib3 dockerpy


    【解决方案1】:

    所以我终于想通了:

    确实与盐有关。由于某种原因,salt minion 导入 docker-py 库的方式做了某种......部分保留了导入。我怀疑发生的事情是 salt 正在重新导入 只是 docker-py 库,所以当我对这些文件进行更改时,更改就会显示出来。

    但是,由于 Python 导入机制将首先搜索预导入的模块,因此 urllib3 代码从未重新导入。

    最终只需要重新启动 salt minion:

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

    【讨论】:

      猜你喜欢
      • 2016-06-01
      • 2013-06-18
      • 1970-01-01
      • 2013-10-31
      • 2014-12-19
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      相关资源
      最近更新 更多