在下文中,主机是运行 Bazel 的机器。
使用远程执行时,实际构建和/或测试步骤不是发生在主机上,而是发送到远程执行系统。不过,解析工作区规则所涉及的步骤是在宿主机上进行的。如果您的工作区规则访问主机的相关信息以在执行期间使用,则构建可能会由于环境之间不兼容而中断。
在调整 Bazel 规则以进行远程执行的过程中,您需要找到此类工作区规则并进行修复。本页介绍了如何使用工作区日志查找可能存在问题的工作区规则。
查找非封闭规则
工作区规则允许开发者向外部工作区添加依赖项,但它们足够丰富,以允许在此过程中进行任意处理。所有相关命令都在本地执行,并且可能会造成非封闭。通常,非封闭行为是通过允许与宿主机交互的 repository_ctx
引入的。
从 Bazel 0.18 开始,您可以向 Bazel 命令添加 --experimental_workspace_rules_log_file=[PATH]
标志,以获取某些可能的非封闭操作的日志。此处的 [PATH]
是一个文件名,系统将在该文件名下创建日志。
需注意的事项:
日志会在事件执行时捕获它们如果某些步骤已缓存,它们不会显示在日志中,因此如需获取完整结果,请不要忘记提前运行
bazel clean --expunge
。有时,函数可能会被重新执行,在这种情况下,相关事件会在日志中多次显示。
Workspace 规则目前仅记录 Starlark 事件。
如需查找在工作区初始化期间执行的内容,请执行以下操作:
运行
bazel clean --expunge
。此命令将清理本地缓存和所有缓存的代码库,确保所有初始化都将重新运行。将
--experimental_workspace_rules_log_file=/tmp/workspacelog
添加到 Bazel 命令并运行构建。这将生成一个二进制 proto 文件,其中列出了 WorkspaceEvent 类型消息
下载 Bazel 源代码,然后使用以下命令导航到 Bazel 文件夹。您需要源代码才能使用工作区日志解析器解析工作区日志。
git clone https://github.com/bazelbuild/bazel.git
cd bazel
在 Bazel 源代码库中,将整个工作区日志转换为文本。
bazel build src/tools/workspacelog:parser
bazel-bin/src/tools/workspacelog/parser --log_path=/tmp/workspacelog > /tmp/workspacelog.txt
输出可能会非常详细,并且包含来自内置 Bazel 规则的输出。
如需从输出中排除特定规则,请使用
--exclude_rule
选项。例如:bazel build src/tools/workspacelog:parser
bazel-bin/src/tools/workspacelog/parser --log_path=/tmp/workspacelog \ --exclude_rule "//external:local_config_cc" \ --exclude_rule "//external:dep" > /tmp/workspacelog.txt
打开
/tmp/workspacelog.txt
并检查是否存在不安全的操作。
该日志由 WorkspaceEvent 消息组成,这些消息概述了对 repository_ctx
执行的某些可能的非封闭操作。
已突出显示为可能非封闭的操作如下:
execute
:在主机环境中执行任意命令。检查这些情况是否会在主机环境中引入任何依赖项。download
、download_and_extract
:为确保 build 封闭,请务必指定 sha256file
、template
:这本身不是非封闭的,但可能是一种将主机环境依赖项引入存储库的机制。确保您了解输入的来源,并且不依赖于主机环境。os
:它本身不是非封闭的,而只是一种获取宿主环境依赖项的简单方法。封闭 build 通常不会调用此 API。在评估使用情况是否封闭时,请注意,这是在主机上运行,而不是在工作器上运行。对于远程构建,通常不适合从主机获取环境详情。symlink
:这通常是安全的,但请留意红色标记。指向代码库外部或绝对路径的任何符号链接都会导致远程工作器出现问题。如果符号链接是基于宿主机属性创建的,也可能有问题。which
:检查主机上安装的程序通常会出现问题,因为工作器的配置可能不同。