扭曲的服务器:猴子补丁文件
Twisted server: monkey-patch file
我 运行 Twisted (Python 2.7.x) 在 Alpine Linux 3.7 inside Docker.
我现在想使用 twisted.internet.inotify
模块,但加载失败。
它在 twisted.python._inotify
中触发了以下异常:
name = ctypes.util.find_library('c')
if not name:
raise ImportError("Can't find C library.")
libc = ctypes.cdll.LoadLibrary(name)
initializeModule(libc)
问题是 Alpine Linux 3.x 有一个错误使得 ctypes.util.find_library('c')
return None
.
我已经将代码与 inotify
module, which I've successfully used in Alpine before, and that one deals with the issue in the following way 进行了比较:
_FILEPATH = ctypes.util.find_library('c')
if _FILEPATH is None:
_FILEPATH = 'libc.so.6'
instance = ctypes.cdll.LoadLibrary(_FILEPATH)
所以我尝试在解释器中调用 ctypes.util.find_library('libc.so.6')
,调用成功。
我现在想做的是猴子补丁 twisted.python._inotify
以便它加载 libc.so.6
而不是 c
,但我不知道我该怎么做,因为我根本无法加载模块。
我有一个选择,那就是在 docker build
期间 sed
源代码,或者甚至可能在服务器启动后立即在服务器内部访问,但这感觉就像是 hack。
我看到 Twisted 包含一个 MonkeyPatch 模块,但我不知道如何使用它,或者它是否适合这个任务。
我怎样才能以最干净的方式解决这个问题?
注意:服务器 运行 作为非 root,因此它没有对 /usr/lib/python2.7/site-packages/twisted/python/_inotify.py
.
的写入权限
这意味着我要么必须在 Docker 文件中 sed
它,要么在服务器启动时在内存中打补丁,然后再加载模块(如果可能的话,我'我更喜欢那个)。
除此之外,我希望您为 Twisted 贡献一个补丁,以彻底解决这个问题,或者使其更容易从应用程序代码或操作级别解决。
也就是说,这里有一个 monkey-patch 应该适合你:
import ctypes.util
def fixed_find_library(name):
if name == "c":
result = original_find_library(name)
if result is not None:
return result
else:
return "libc.so.6"
return original_find_library(name)
original_find_library = ctypes.util.find_library
ctypes.util.find_library = fixed_find_library
# The rest of your application code...
这只需将您提出的解决问题的问题的逻辑编纂成代码即可。只要此代码在 _inotify.py
被导入之前运行,那么当它被导入时,它最终将使用 "fixed" 版本而不是原始版本。
虽然 Jean-Paul 指出的猴子修补似乎是最好的解决方法,但这里有一种修改 Twisted 源代码的方法。
当使用PythonDockerAPI到运行容器时:
container = client.containers.run(...)
patch = 'sed -i.bak s/raise\ ImportError/name\ =\ \"libc.so.6\"\ #\ raise\ ImportError/g /usr/lib/python2.7/site-packages/twisted/python/_inotify.py'
print container.exec_run(patch, user='root')
或在容器内 bash 时:
sed -i.bak s/raise\ ImportError/name\ =\ \"libc.so.6\"\ #\ raise\ ImportError/g /usr/lib/python2.7/site-packages/twisted/python/_inotify.py
我 运行 Twisted (Python 2.7.x) 在 Alpine Linux 3.7 inside Docker.
我现在想使用 twisted.internet.inotify
模块,但加载失败。
它在 twisted.python._inotify
中触发了以下异常:
name = ctypes.util.find_library('c')
if not name:
raise ImportError("Can't find C library.")
libc = ctypes.cdll.LoadLibrary(name)
initializeModule(libc)
问题是 Alpine Linux 3.x 有一个错误使得 ctypes.util.find_library('c')
return None
.
我已经将代码与 inotify
module, which I've successfully used in Alpine before, and that one deals with the issue in the following way 进行了比较:
_FILEPATH = ctypes.util.find_library('c')
if _FILEPATH is None:
_FILEPATH = 'libc.so.6'
instance = ctypes.cdll.LoadLibrary(_FILEPATH)
所以我尝试在解释器中调用 ctypes.util.find_library('libc.so.6')
,调用成功。
我现在想做的是猴子补丁 twisted.python._inotify
以便它加载 libc.so.6
而不是 c
,但我不知道我该怎么做,因为我根本无法加载模块。
我有一个选择,那就是在 docker build
期间 sed
源代码,或者甚至可能在服务器启动后立即在服务器内部访问,但这感觉就像是 hack。
我看到 Twisted 包含一个 MonkeyPatch 模块,但我不知道如何使用它,或者它是否适合这个任务。
我怎样才能以最干净的方式解决这个问题?
注意:服务器 运行 作为非 root,因此它没有对 /usr/lib/python2.7/site-packages/twisted/python/_inotify.py
.
这意味着我要么必须在 Docker 文件中 sed
它,要么在服务器启动时在内存中打补丁,然后再加载模块(如果可能的话,我'我更喜欢那个)。
除此之外,我希望您为 Twisted 贡献一个补丁,以彻底解决这个问题,或者使其更容易从应用程序代码或操作级别解决。
也就是说,这里有一个 monkey-patch 应该适合你:
import ctypes.util
def fixed_find_library(name):
if name == "c":
result = original_find_library(name)
if result is not None:
return result
else:
return "libc.so.6"
return original_find_library(name)
original_find_library = ctypes.util.find_library
ctypes.util.find_library = fixed_find_library
# The rest of your application code...
这只需将您提出的解决问题的问题的逻辑编纂成代码即可。只要此代码在 _inotify.py
被导入之前运行,那么当它被导入时,它最终将使用 "fixed" 版本而不是原始版本。
虽然 Jean-Paul 指出的猴子修补似乎是最好的解决方法,但这里有一种修改 Twisted 源代码的方法。
当使用PythonDockerAPI到运行容器时:
container = client.containers.run(...)
patch = 'sed -i.bak s/raise\ ImportError/name\ =\ \"libc.so.6\"\ #\ raise\ ImportError/g /usr/lib/python2.7/site-packages/twisted/python/_inotify.py'
print container.exec_run(patch, user='root')
或在容器内 bash 时:
sed -i.bak s/raise\ ImportError/name\ =\ \"libc.so.6\"\ #\ raise\ ImportError/g /usr/lib/python2.7/site-packages/twisted/python/_inotify.py