【问题标题】:Execute 'docker run' from within SBCL Common Lisp在 SBCL Common Lisp 中执行 'docker run'
【发布时间】:2021-03-16 22:54:25
【问题描述】:

我正在尝试在我的 lisp 程序中运行一个函数。它是一个连接到 IRC 频道的机器人,您可以使用特殊命令查询该机器人以评估一个简单的 lisp 命令。因为在互联网上执行任意代码是极其危险的,所以我希望在虚拟机中进行实际评估,该虚拟机为机器人获取的每个评估查询运行 docker。

我的函数如下所示:

(defun run-command (cmd)
  (uiop:run-program (list "docker" "run" "--rm" "-it" "my/docker" "sbcl" "--noinform" "--no-sysinit" "--no-userinit" "--noprint" "--disable-debugger" "--eval" (string-trim '(#\^M) (format nil "~A" cmd))) "--eval" "'(quit)'") :output '(:string :stripped t))

这个函数背后的想法是启动一个包含 SBCL 的 docker,通过 SBCL --eval 运行命令并将其打印到 docker std-out。而这个打印出来的字符串应该是run-command的结果。

如果我打电话

docker run --rm -it my/docker sbcl --noinform --no-sysinit --no-userinit --noprint --disable-debugger --eval "(print (+ 2 3))" --eval "(quit)"

在我的命令行中,我只得到 5,这正是我想要的。

但是如果我在 lisp 中运行相同的命令,我会得到 uiop:run-program 函数

Subprocess #<UIOP/LAUNCH-PROGRAM::PROCESS-INFO {1004FC3923}>
 with command ("docker" "run" "--rm" "-it"
               "my/docker" "sbcl" "--noinform"
               "--no-sysinit" "--no-userinit" "--noprint"
               "--disable-debugger" "--eval" "(+ 2 3)")

作为错误消息,这意味着进程以某种方式失败。但我不知道这里到底有什么问题。如果我只是执行例如“ls”,我会得到输出,所以该函数似乎工作正常。

我需要一些关于uiop:run-program 的特殊知识还是我做错了什么?

提前致谢。

编辑:事实证明 -it 标志导致了问题。删除标志后出现新错误。现在机器人没有执行 docker 的权限。有没有办法在不授予它 sudo 权限的情况下授予它权限?

【问题讨论】:

  • 这是错误信息的全部内容吗?这似乎被截断了。 *error-output* 上还有其他内容吗?
  • 注意:你的目标让我想起了cl-isolated图书馆。
  • coredump 错误消息之后的内容是堆栈跟踪,如果有帮助,我可以提供。 Ehvince 这看起来很有希望。但是他们如何证明他们的子集是安全的呢?
  • @Echon:除非您基本上已经信任您的代码,否则我不会使用 cl-isolated:对于一件事没有资源控制。在您的情况下,您是否尝试过运行 type docker &c 来检查路径是否正确?
  • @tfb 我检查了所有路径,一切都按预期工作。我发现 -it 标志引起了问题。现在我的问题发生了变化,就像我在原始问题的编辑中描述的那样。

标签: docker command-line common-lisp sbcl


【解决方案1】:

这里调用 docker 的方式(或 SBCL)可能有问题。要获取错误消息,请使用 :error-output :string 参数调用 uiop:run-program,然后选择 continue 重新启动,实际上,终止执行并打印错误输出(如果您从 SLIME 或其他一些 REPL 运行)。如果您在非交互环境中调用它,您可以将调用包装在处理程序绑定中:

(handler-bind ((uiop/run-program:subprocess-error
                 (lambda (e) (invoke-restart (find-restart 'continue)))))
  (run-command ...))

【讨论】:

  • 我试图以您描述的方式收到一条错误消息,结果我得到“输入设备不是 TTY”。现在我更无能为力了。但也许它可以帮助调试。编辑:不知何故 -it 标志创建了错误。删除标志后,我收到以下错误:“无法在本地 docker 找到图像 'my/docker:latest':来自守护进程的错误响应:我/docker 的拉取访问被拒绝,存储库不存在或可能需要 'docker login':拒绝...[长度为 272 的巧妙省略的字符串]"
【解决方案2】:

原来-it 确实造成了麻烦。删除它并提升机器人的正确权限后,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2015-09-30
    • 2015-04-30
    • 2021-11-15
    • 1970-01-01
    相关资源
    最近更新 更多