blob: 15da79bf3aeeeb4a3cf18344e7135870c0edf024 [file] [log] [blame] [view]
---
layout: documentation
title: Finding non-hermetic behavior in WORKSPACE rules
---
# Finding non-hermetic behavior in WORKSPACE rules
In the following, we say that a host machine is the machine where Bazel runs.
When using remote execution, the actual build and/or test steps are not
happening on the host machine, but are instead sent off to the remote execution
system. However, the steps involved in resolving workspace rules are happening
on the host machine. If your workspace rules access information about the
host machine for use during execution, your build is likely to break due to
incompatibilities between the environments.
As part of [adapting Bazel rules for remote
execution](/remote-execution-rules.html), you need to find such workspace rules
and fix them. This page describes how to find potentially problematic workspace
rules using the workspace log.
## Finding non-hermetic rules
[Workspace rules](/be/workspace.html) allow the developer to add dependencies to
external workspaces, but they are rich enough to allow arbitrary processing to
happen in the process. All related commands are happening locally and can be a
potential source of non-hermeticity. Usually non-hermetic behavior is
introduced through
[`repository_ctx`](/skylark/lib/repository_ctx.html) which allows interacting
with the host machine.
Starting with Bazel 0.18, you can get a log of some potentially non-hermetic
actions by adding the flag `--experimental_workspace_rules_log_file=[PATH]` to
your Bazel command. Here `[PATH]` is a filename under which the log will be
created.
Things to note:
* the log captures the events as they are executed. If some steps are
cached, they will not show up in the log, so to get a full result, don't
forget to run `bazel clean --expunge` beforehand.
* Sometimes functions might be re-executed, in which case the related
events will show up in the log multiple times.
* Workspace rules log currently only logs Starlark events. Some native rules
may cause non-hermetic behavior but not show up in this log. Examples of those
rules include
[maven_jar](/be/workspace.html#maven_jar).
Note that these particular rules do not cause hermiticity concerns as long
as a hash is specified.
To find what was executed during workspace initialization:
1. Run `bazel clean --expunge`. This command will clean your local cache and
any cached repositories, ensuring that all initialization will be re-run.
2. Add `--experimental_workspace_rules_log_file=/tmp/workspacelog` to your
Bazel command and run the build.
This produces a binary proto file listing messages of type
[WorkspaceEvent](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/debug/workspace_log.proto?q=WorkspaceEvent)
3. Download the Bazel source code and navigate to the Bazel folder by using
the command below. You need the source code to be able to parse the
workspace log with the
[workspacelog parser](https://source.bazel.build/bazel/+/master:src/tools/workspacelog/).
git clone https://github.com/bazelbuild/bazel.git
cd bazel
4. In the Bazel source code repo, convert the whole workspace log to text.
bazel build src/tools/workspacelog:parser
bazel-bin/src/tools/workspacelog/parser --log_path=/tmp/workspacelog > /tmp/workspacelog.txt
5. The output may be quite verbose and include output from built in Bazel
rules.
To exclude specific rules from the output, use `--exclude_rule` option.
For example:
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
5. Open `/tmp/workspacelog.txt` and check for unsafe operations.
The log consists of
[WorkspaceEvent](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/debug/workspace_log.proto?q=WorkspaceEvent)
messages outlining certain potentially non-hermetic actions performed on a
[`repository_ctx`](/skylark/lib/repository_ctx.html).
The actions that have been highlighted as potentially non-hermetic are as follows:
* `execute`: executes an arbitrary command on the host environment. Check if
these may introduce any dependencies on the host environment.
* `download`, `download_and_extract`: to ensure hermetic builds, make sure
that sha256 is specified
* `file`, `template`: this is not non-hermetic in itself, but may be a mechanism
for introducing dependencies on the host environment into the repository.
Ensure that you understand where the input comes from, and that it does not
depend on the host environment.
* `os`: this is not non-hermetic in itself, but an easy way to get dependencies
on the host environment. A hermetic build would generally not call this.
In evaluating whether your usage is hermetic, keep in mind that this is
running on the host and not on the workers. Getting environment specifics
from the host is generally not a good idea for remote builds.
* `symlink`: this is normally safe, but look for red flags. Any symlinks to
outside the repository or to an absolute path would cause problems on the
remote worker. If the symlink is created based on host machine properties
it would probably be problematic as well.
* `which`: checking for programs installed on the host is usually problematic
since the workers may have different configurations.