奇点秘诀:如何访问容器内的可执行文件?
Singularity Recipe: How to access executable within container?
我是 Singularity 的初学者。
我想在长运行中实现的目标:我有一个包含一长串依赖关系的编程项目,我希望能够将该程序提供给我公司的其他人,而无需缺少依赖项或错误版本的依赖项导致的错误。
现在的想法是使用 Singularity 来轻松提供工作环境。
为了对此进行测试,我编写了一个 Hello World 应用程序,我现在想将其 运行 放入容器中。我有一个文件夹 HelloWorld/
,其中包含 C++ Qt 项目的源代码。然后我写了以下配方文件:
project.recipe
Bootstrap: docker
From: ubuntu:18.04
%setup
cp -R <some_folder>/HelloWorld ${SINGULARITY_ROOTFS}/HelloWorld
%post
apt update
apt-get install -y qt5-default
apt install -y g++
apt-get install -y build-essential
cd HelloWorld
qmake
make
echo "after build:"
ls
%runscript
echo "before execution:"
ls HelloWorld/
./HelloWorld/HelloWorld
回声和目录列表用于我当前的调试过程。
我可以使用 sudo singularity build --writable project.img project.recipe
成功构建图像文件。 (我的调试输出显示可执行文件已成功构建。)
现在的问题是,如果我尝试使用 ./project.img
或 singularity run project.img
运行 它,它将找不到可执行文件。
使用我的调试输出,我发现 %runscript
中的行使用了容器外部的文件夹。
https://sylabs.io/guides/3.1/user-guide/build_a_container.html 之类的教程让我觉得我的食谱是可行的,但显然不是?
我的问题:
- 有什么方法可以让我访问我的可执行文件吗?我叫错了吗?
- 我做事的方式是应该做的吗?或者通常会做一些事情,比如将可执行文件从容器外部获取,然后使用容器调用该外部文件?或者是否有不同的最佳实践?
- 如果编译后要将可执行文件复制到容器外,我该怎么做?当我在
%post
时如何访问外部文件夹?
- 这是我想要实现的最佳工作流程吗?后来,我的想法是将大项目同样复制到容器中,安装或复制依赖项,然后编译项目,最后删除其源代码。我也考虑过使用存储库,但我不能将项目放在一个开放的存储库中,而且我不想存储任何密码。
- 首先,使用
%files
,不要使用%setup
。 %setup
是 运行 作为 root 并且可以直接修改主机服务器。您可能很容易不小心弄坏东西而没有意识到。您可以通过这种方式获得相同的效果:
%files
some_folder/HelloWorld /HelloWorld
你说错了。在您的 %setup
(希望现在在您的 %files
)步骤中,您正在将数据复制到 /HelloWorld
。在您的 %runscript
中,您正在调用 ./HelloWorld/HelloWorld
,这相当于 $PWD/HelloWorld/HelloWorld
。由于奇点自动安装在 $PWD
(以及 $HOME
和其他一些目录)中,因此您没有调用您想要调用的内容。
您不需要将可执行文件复制到容器外部,您只需要确保您正在执行的内容在您认为的位置即可。
无法访问 %post
中的主机文件系统,您应该先通过 %files
复制所需的所有内容。
这是一个合理的工作流程。拥有代码的本地私有存储库可能是跟踪您的更改的好主意,但这是您的决定。
我是 Singularity 的初学者。
我想在长运行中实现的目标:我有一个包含一长串依赖关系的编程项目,我希望能够将该程序提供给我公司的其他人,而无需缺少依赖项或错误版本的依赖项导致的错误。
现在的想法是使用 Singularity 来轻松提供工作环境。
为了对此进行测试,我编写了一个 Hello World 应用程序,我现在想将其 运行 放入容器中。我有一个文件夹 HelloWorld/
,其中包含 C++ Qt 项目的源代码。然后我写了以下配方文件:
project.recipe
Bootstrap: docker
From: ubuntu:18.04
%setup
cp -R <some_folder>/HelloWorld ${SINGULARITY_ROOTFS}/HelloWorld
%post
apt update
apt-get install -y qt5-default
apt install -y g++
apt-get install -y build-essential
cd HelloWorld
qmake
make
echo "after build:"
ls
%runscript
echo "before execution:"
ls HelloWorld/
./HelloWorld/HelloWorld
回声和目录列表用于我当前的调试过程。
我可以使用 sudo singularity build --writable project.img project.recipe
成功构建图像文件。 (我的调试输出显示可执行文件已成功构建。)
现在的问题是,如果我尝试使用 ./project.img
或 singularity run project.img
运行 它,它将找不到可执行文件。
使用我的调试输出,我发现 %runscript
中的行使用了容器外部的文件夹。
https://sylabs.io/guides/3.1/user-guide/build_a_container.html 之类的教程让我觉得我的食谱是可行的,但显然不是?
我的问题:
- 有什么方法可以让我访问我的可执行文件吗?我叫错了吗?
- 我做事的方式是应该做的吗?或者通常会做一些事情,比如将可执行文件从容器外部获取,然后使用容器调用该外部文件?或者是否有不同的最佳实践?
- 如果编译后要将可执行文件复制到容器外,我该怎么做?当我在
%post
时如何访问外部文件夹? - 这是我想要实现的最佳工作流程吗?后来,我的想法是将大项目同样复制到容器中,安装或复制依赖项,然后编译项目,最后删除其源代码。我也考虑过使用存储库,但我不能将项目放在一个开放的存储库中,而且我不想存储任何密码。
- 首先,使用
%files
,不要使用%setup
。%setup
是 运行 作为 root 并且可以直接修改主机服务器。您可能很容易不小心弄坏东西而没有意识到。您可以通过这种方式获得相同的效果:
%files
some_folder/HelloWorld /HelloWorld
你说错了。在您的
%setup
(希望现在在您的%files
)步骤中,您正在将数据复制到/HelloWorld
。在您的%runscript
中,您正在调用./HelloWorld/HelloWorld
,这相当于$PWD/HelloWorld/HelloWorld
。由于奇点自动安装在$PWD
(以及$HOME
和其他一些目录)中,因此您没有调用您想要调用的内容。您不需要将可执行文件复制到容器外部,您只需要确保您正在执行的内容在您认为的位置即可。
无法访问
%post
中的主机文件系统,您应该先通过%files
复制所需的所有内容。这是一个合理的工作流程。拥有代码的本地私有存储库可能是跟踪您的更改的好主意,但这是您的决定。