Skip to main content
在指定 Box 的容器内运行 Python 脚本,用于测试自动化、硬件控制和数据处理。

语法

全局选项

参数:
  • RUNNABLE - 要执行的 Python 脚本文件或目录(除非使用了 --kill、--kill-all、--reattach、--continue 或 --console 之类的进程管理标志,否则必填)
  • ARGS - 传给该脚本的额外参数
--kill/--kill-all 可选的信号: SIGINT、SIGQUIT、SIGABRT、SIGKILL、SIGUSR1、SIGUSR2、SIGTERM、SIGSTOP

基本用法

环境变量

设置变量

自动注入的变量

以下环境变量在您的脚本内部自动可用:

文件下载

每次运行在 Box 上都有自己的输出文件夹。把脚本生成的文件写入 lager.output_dir():
然后加上 --download,取回所有文件:
脚本结束后,CLI 会在当前目录中新建一个以该次运行命名的文件夹,把脚本写入 lager.output_dir() 的每个文件(包括子文件夹)以及运行记录复制到其中。然后 CLI 会把每个文件与记录中的哈希进行比较:
无论是否使用 --download,运行记录都会列出输出文件夹中的每个文件。不使用 --download 时,CLI 不会在你的电脑上保存任何内容。在 lager python 之外,lager.output_dir() 返回当前目录中的 lager-output 文件夹,因此脚本在你的电脑上也能运行。

分离模式

在后台运行脚本,不等待输出:
在分离模式下:
  • 只要 Box 接受了这个作业,命令就返回。它在脚本开始之前就返回,也在脚本所需的准备工作(解包模块目录、安装它的 requirements.txt)之前返回
  • 不会把 stdout/stderr 回传
  • 脚本继续在 Box 上运行
  • 用 --reattach 查看它的输出,之后用 --kill 停止它
启动在准备工作运行之前就返回。因此作业可能在提示符回来之后才启动失败 —— 例如某个 requirements.txt 装不上。这类失败要通过作业本身看到,而不是在提示符处。 --reattach 会显示该失败并以非零码退出:
分离运行会获取 Box 锁。0.42.0 及以上版本的 Box 会在作业运行期间持有该锁,并在作业结束时释放它。CLI 会打印 Box 'my-lager-box' is held for the detached run and released when it ends。较旧的 Box 在作业结束后仍保留该锁,此时 CLI 会打印 release with: lager boxes unlock --box my-lager-box。请参阅 锁定。

终止正在运行的脚本

--kill 接受分离启动时打印出的进程 ID。

端口转发

把 Box 上的网络端口转发到您的本机:
端口格式:SRC_PORT[:DST_PORT][/PROTOCOL]

超时

限制脚本的执行时间:
  • 默认值 0 表示不限制。
  • 前台运行被限制在 300 秒。更大的值只会运行 300 秒,Box 会把这个上限写入它的日志。
  • 分离运行没有上限。只有当您给出数值时,Box 才会应用它。
当脚本超过超时时间时,Box 会依次发送信号:
  • 先发送 SIGTERM。CLI 打印 Script terminated due to timeout. 并以 124 退出
  • 如果脚本在 5 秒内没有退出,再发送 SIGKILL。CLI 打印 Script forcibly killed due to timeout. 并以 137 退出

结构化输出

运行在 Box 上的脚本可以用 lager.core.output() 函数把结构化数据回传给 CLI。它使用独立于 stdout/stderr 的专用输出通道(文件描述符 3)。

Box 侧 API

可用的编码器: 结构化输出在到达时就会打印到 CLI 控制台。标准的 stdout 和 stderr 则实时单独串流。

模块 includes

如果您的脚本依赖本地模块,请在项目的 .lager 文件中配置 includes。该文件是 JSON:
相对路径是相对于该 .lager 文件的。CLI 从脚本所在目录开始,沿目录树向上查找 .lager 文件,然后在上传到 Box 之前,把脚本连同全部 include 目录一起打包。
在 test.py 中:

额外文件

随脚本一起上传其他文件:
这些文件会与您的脚本位于 Box 上的同一目录中。

退出码

运行记录

Box 为每次运行写一份运行记录。该记录是一个 JSON 文件。它说明运行了什么、在哪台 Box 上、处于什么状态,以及产生了什么:
  • Box 收到的每个文件的 SHA-256 哈希
  • 运行开始时的 Box 状态:Lager 版本、操作系统、net 配置,以及每台仪器的序列号
  • 开始时间、结束时间和退出码
  • 运行结束的原因:正常退出、超时、被取消,或客户端断开连接
  • 输出以及该次运行输出文件夹中每个文件的 SHA-256 哈希
记录保存的位置:
  • Box 上,每次运行都会保存。 Box 保留最近 500 次运行的记录。
  • Box 的发件箱(outbox)中,前提是有收集器管理该 Box。 收集器是从 Box 取走每条记录并保存到其他地方的服务。记录会留在发件箱中,直到收集器取走。
  • 你的电脑上,仅在使用 --download 时。 CLI 会把记录写为 <process-id>.lager-run.json,放在该次运行的文件夹中、下载的文件旁边(参见文件下载)。CLI 会把输出和下载的文件与记录中的哈希进行比较。如果不一致,CLI 会显示警告。
添加标签,以便以后查找该次运行:
脚本可以添加只有脚本知道的值,例如被测设备的固件版本:
Box 不会验证标签或脚本提供的值。不要在其中放入机密信息。完整格式请参阅 Lager 仓库中的 docs/reference/run-record.md。

Box 锁

lager python 在运行脚本时会获取 Box 锁,这样其他用户就不能同时驱动同一台 Box。请参阅锁定。
  • 前台运行在脚本运行期间持有该锁,命令退出时释放它。
  • 如果另一位用户持有该锁,命令在您的计算机上会立即失败;在 CI 中,它会等待该锁。
  • --kill、--kill-all、--reattach、--continue 和 --console 不获取该锁。
  • 设置 LAGER_AUTO_LOCK_DISABLE=1 可以在不加锁的情况下运行。

示例

硬件测试脚本示例

说明

  • 脚本专用的配置值请用 --env
  • 来自当前 shell 的密钥或令牌请用 --passenv
  • --download 只在脚本结束后取回文件,而不是在运行过程中,并且只取回 lager.output_dir() 中的文件
  • 端口转发的语法是 SRC_PORT[:DST_PORT][/PROTOCOL]
  • 输出通过带保活(间隔 20 秒)的多路复用 HTTP 协议实时流式传输

安装 Python 包

脚本在 Box 上的 Lager Python 容器内运行。要安装脚本依赖的包,请用声明式的 lager box-config pip 命令。这些命令把包记录到 Box 配置中,并重建容器。此后这些包会在多次 lager python 运行和 Box 更新之间保持存在。
完整的声明式配置流程(pip/cargo/npm 包、apt、udev、挂载、env 等),请参阅 Box Config 参考。
独立的 lager pip 命令已被移除,并入了 lager box-config pip。