使用Docker的ENTRYPOINT/CMD等效功能构建Singularity配方

huangapple go评论95阅读模式
英文:

build singularity recipe with docker ENTRYPOINT/CMD equivalent functionality

问题

I have a dockerfile which ends

ENTRYPOINT ["sh"]
CMD ["runscript.sh"]

我有一个 Dockerfile,其中包含以下内容:

ENTRYPOINT ["sh"]
CMD ["runscript.sh"]

I can run docker with an argument (a shell script) that overrides "runscript.sh" (if i wish). Note: the shell scripts are provided by a --bind mount

如果需要,我可以运行 Docker 并使用一个参数(一个 shell 脚本)来覆盖 "runscript.sh"。请注意:这些 shell 脚本是通过 --bind 挂载提供的。

I am translating my Dockerfile to a Singularity recipe. From my understanding i can replicate this ENTRYPOINT/CMD functionality using the "%startscript" label. I am trying:

我正在将我的 Dockerfile 翻译成 Singularity 配方。根据我的理解,我可以使用 "%startscript" 标签来复制 ENTRYPOINT/CMD 的功能。我尝试了以下方法:

%startscript
exec "$@"

then run an instance of the container using

然后,使用以下命令运行容器的一个实例:

singularity instance start --bind /hostpath:/containerpath model.sif instancename script.sh

When i do this i get the message:

但是当我这样做时,我收到以下消息:

/.singularity.d/startscript: 4: exec: script.sh: not found

I know i am doing this all wrong, but cant seem to work out what.

我知道我做错了什么,但似乎无法找出问题所在。

Note: if i replace exec "$@" with ./script.sh then the script is executed but i am limited to having a script with this name. I want the flexibility to pass any named script.

注意:如果我将 exec "$@" 替换为 ./script.sh,则脚本将被执行,但我只能使用这个名称的脚本。我希望具有灵活性以传递任何命名的脚本。

英文:

I have a dockerfile which ends

ENTRYPOINT ["sh"]
CMD ["runscript.sh"]

I can run docker with an argument (a shell script) that overrides "runscript.sh" (if i wish). Note: the shell scripts are provided by a --bind mount

I am translating my Dockerfile to a Singularity recipe. From my understanding i can replicate this ENTRYPOINT/CMD functionality using the "%startscript" label. I am trying:

%startscript
exec "$@"

then run an instance of the container using

singularity instance start --bind /hostpath:/containerpath model.sif instancename script.sh

When i do this i get the message:

/.singularity.d/startscript: 4: exec: script.sh: not found

I know i am doing this all wrong, but cant seem to work out what.

Note: if i replace exec "$@" with ./script.sh then the script is executed but i am limited to having a script with this name. I want the flexibility to pass any named script.

答案1

得分: 0

在您的原始 Dockerfile 中:

  1. 删除 ENTRYPOINT
  2. 确保 CMD 包括某种路径,如 CMD ["./runscript.sh"]
  3. 确保脚本的第一行是 "shebang" 行,#!/bin/sh
  4. 在主机系统上确保脚本是可执行的,chmod +x runscript.sh,并检查是否将更改提交到源代码控制

这是您需要在主机系统上运行 ./runscript.sh 而无需使用 Docker 的相同步骤,相同的规则适用。

在您展示的脚本中,您只是运行 exec "$@",可能作为传递 CMD 作为参数的入口脚本。您的原始 Dockerfile 使用 shENTRYPOINT 值)在给定的 CMD 之前添加了一个 CMD,但这个包装器没有这样做,这就是为什么会出现不同行为的原因。

总的来说,我不鼓励将语言解释器的名称拆分到 ENTRYPOINT 中。我更喜欢 CMD 是一个完整的命令的模式,与您展示的入口包装脚本兼容。还有一种模式是 ENTRYPOINT 是一个完整的命令,CMD 是其参数(Kubernetes 将这些选项称为 command:args:)。您这里所做的有点像是一半的方式:如果您覆盖 CMD,那么您必须重复程序名称,但实际上只能运行实现为 shell 脚本的程序。

英文:

In your original Dockerfile:

  1. Remove the ENTRYPOINT
  2. Make sure the CMD includes some sort of path, like CMD ["./runscript.sh"]
  3. Make sure the first line of the script is a "shebang" line, #!/bin/sh
  4. On the host system, make sure the script is executable, chmod +x runscript.sh, and check that change into source control

This is the same set of steps you'd need to do to be able to run ./runscript.sh on the host system, without Docker, and the same rules apply.

In the script you show, you're just running exec "$@", presumably as an entrypoint script being passed the CMD as arguments. Your original Dockerfile prepended whatever CMD it was given with sh (the ENTRYPOINT value), but this wrapper doesn't, and that's why you're getting different behavior.

In general I wouldn't encourage splitting out the name of a language interpreter into ENTRYPOINT. I prefer a pattern of CMD being a complete command, which is compatible with the sort of entrypoint wrapper script you show. There's also a pattern of ENTRYPOINT being a complete command and CMD its arguments (Kubernetes calls these options command: and args:). What you have here is kind of a half way, though: if you override CMD then you must repeat the program name, but you can only actually run programs that are implemented as shell scripts.

答案2

得分: 0

你需要使用 %runscript 而不是 %startscript,然后你可以传递一个参数给 run 命令,该参数将替代配方中的默认值,例如,在配方文件中:

%runscript
./runscript.sh

然后,根据你想要运行默认容器脚本或 "newscript",使用以下之一:

要运行默认容器脚本:

singularity exec image.sif

要运行 "newscript":

singularity exec image.sif newscript.sh
英文:

You need to use

%runscript

and not

%startscript

Then you can pass an argument to run command which will be used in place of the default value in the recipe,

singularity exec image argument

eg. in the recipe file

 %runscript
./runscript.sh

then use either

singularity exec image.sif 

or

singularity exec image.sif newscript.sh

depending on whether you want to run the default container script or the "newscript"

huangapple
  • 本文由 发表于 2023年5月25日 01:48:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326204.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定