为什么在奇异容器中挂载主目录会破坏 python 导入?

问题描述 投票:0回答:1

我一直在构建一个奇点容器来运行一些Python代码,尽管阅读了奇点文档,但我无法理解错误/行为。

首先容器是从docker引导的Ubuntu18.04,即:

Bootstrap: docker
From: ubuntu:18.04

我需要使用Python模块(神经元),它需要预先编译等。我编译定义文件的

%post
部分中的代码并添加环境变量:

echo 'export PATH=$PATH:/usr/local/nrn/x86_64/bin' >>$SINGULARITY_ENVIRONMENT
echo 'export LD_LIBRARY_PATH=/usr/local/nrn/x86_64/lib:$LD_LIBRARY_PATH' >>$SINGULARITY_ENVIRONMENT

我可以构建容器而不会出现太多问题(使用

sudo singularity build --sandbox
)。但我一直在尝试运行测试脚本(test.py)以确保一切按预期工作。在脚本中,我导入有问题的模块(神经元),然后尝试将列表保存到 csv 以确保我可以正确保存数据。所以它看起来像这样:

import neuron #this fails and gives an unusual error in specific circumstances I don't understand (described below)
import numpy as np

some_data = [1,2,3]
np.savetxt('test_results.csv',np.asarray(some_data),delimiter=',') 

根据我在使用

singularity exec
时提供的标志,我得到不同的结果,但我不明白(或者不知道从哪里开始理解 - 这是神经元、奇点还是
ubuntu
问题?)。

为了完整起见,容器(和 test.py)位于我运行这些命令的同一目录中(在我的示例中是 dir )。因此,如果我挂载 $HOME,不使用

--no-home
标志并尝试像这样运行 test.py:
singularity exec --writable --bind /home/bidby/path/to/some/dir:/mnt my_container.simg python3 /mnt/test.py

我收到这样的错误:

dlopen failed -  x86_64/.libs/libnrnmech.so: undefined symbol: celsius
,我尝试过谷歌搜索,可能是 C++ 链接错误(但我只知道 python,所以调试它并不容易)。

但是,如果我使用

--no-home
标志,即:
singularity exec --no-home  --writable --bind /home/bidby/path/to/some/dir:/mnt my_container.simg python3 /mnt/test.py

然后模块导入成功,又出现新的错误:

Traceback (most recent call last):
  File "/mnt/test.py", line 15, in <module>
    np.savetxt('test_results.csv',np.asarray(some_data),delimiter=',')
  File "/usr/local/lib/python3.6/dist-packages/numpy/lib/npyio.py", line 1352, in savetxt
    open(fname, 'wt').close()
PermissionError: [Errno 13] Permission denied: 'test_results.csv'

我已经连续几天在谷歌上搜索这个问题了,但我不知道问题出在哪里。根据我所学到和测试的内容,我认为这可能与环境变量如何传递到容器中有关,尽管我不明白为什么我没有权限在这里保存。但我觉得如果我能理解为什么使用

--no-home
标志会影响模块导入,这个问题可能会得到解决。

这可能对解决问题没有帮助,但我注意到/尝试过的其他事情:

如果我使用

--containall
标志,我可以毫无问题地运行 test.py,但是我尝试保存的 csv 文件永远找不到。我检查了文档,上面写着:

使用 --containall (或简称 -C )标志,不会安装 $HOME 并在 $HOME 点创建一个虚拟绑定安装。您不能使用 -B`(或 --bind)来绑定 $HOME 目录,因为它会创建一个空安装。因此,如果您的文件位于 /home/user 的映像中,则 --containall 标志将全部隐藏它们。

我认为这个“虚拟绑定安装”是文件被写入的位置,因此我永远无法真正找到它。

如果我使用

sudo
--writable
标志进入容器,我可以毫无问题地导入神经元。如果我不使用这些标志中的任何一个,那么我会得到与上面相同的“未定义符号”错误。

如果我不导出 LD_LIBRARY_PATH,那么我会收到一个不同的 dlopen 错误,引用不同的 .so 文件,表示该文件不存在 - 这再次证实了我的想法,这是一个路径问题。

我知道我没有包含足够的代码来重现此错误,因为我猜测没有人有时间/精力来构建这个容器(因为它相当大),但我认为我已经包含了最相关的部分。如果需要的话,我们很乐意添加更多。

调试这对我来说是一场噩梦,如果有人能指出我应该谷歌搜索的正确方向,我将非常感激。

python python-3.x ubuntu-18.04 singularity-container neuron-simulator
1个回答
3
投票

这看起来确实像是一个环境问题,但远程调试比本地调试更困难。可以提供帮助的一件事是:使用

--cleanenv
选项以及
--no-home
。这应该使您的容器环境独立于主机环境。这可能会解决您的问题,或者至少指出一个新问题。

接下来显示的写入错误来自测试脚本,其中您使用正在写入的文件的相对路径。一般来说,这意味着它被写入执行脚本的目录。您是否对该目录具有写入权限,或者是否存在您没有写入权限的同名现有文件?

可能不相关,但是:您使用的是哪个版本的奇点?

.simg
用于 2.x 文档,而
.sif
通常用于 3.x。如果您仍在使用 2.x,我强烈建议尽可能更新到最新的 3.x。 2.x 和大多数版本已不再开发 < 2.6.1 have security issues. If your cluster admins are being slow to update, pointing this out can help motivate them.

© www.soinside.com 2019 - 2024. All rights reserved.