[8.8.0] Compare paths as fragments in `AbstractActionInputPrefetcher` (#30690)
This is required because `execRoot` might be located on an action file
system overlaying the host file system where downloads are written (see
the changes in
https://github.com/bazelbuild/bazel/commit/b8589c3b278e3f5cee6ef85b0dcabb1cdcd69839
for context).
Without this fix, a directory that is temporarily made writable during
the materialization of a tree artifact isn't recognized as living under
the exec root, so it is silently left with its output permissions and
files can't be moved into place. This has been observed as a tree
artifact whose top-level directory was writable while a subdirectory was
left read-only, surfacing as a spurious missing CAS blob error since all
materialization errors are converted into that.
PiperOrigin-RevId: 830480221
Change-Id: I217b81a81da80f2050c4ec9082ef5f18cb9a0bc9
(cherry picked from commit 1e9d843fa6362b88d5ca1b6cc04b38f69823fb76)
8.8.0 adaptation: on this branch `setWritable` additionally
short-circuits on external repository paths under the output base and
obtains the exec root lazily via `execRoot()`, so the fragment
comparison is applied to the existing `execRoot()` check rather than
replacing the condition wholesale.
This supersedes #30680, which applies the original patch verbatim and
thereby drops the external repository check as well as referencing
`execRoot` as a field, which doesn't exist on this branch.
Co-authored-by: Tiago Quelhas <tjgq@google.com>
diff --git a/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java b/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java
index 1b67f19..4b018ee 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java
@@ -139,10 +139,13 @@
// dir may be on the host file system while the output base is on an overlay) so that the exec
// root, which is only resolvable during the loading phase and later, is not resolved during
// external repo materialization.
+ //
+ // Compare against the exec root as fragments as well, since it may be located on a file
+ // system overlaying the host file system where downloads are written to.
if (dir.asFragment()
.startsWith(
outputBase.getRelative(LabelConstants.EXTERNAL_REPOSITORY_LOCATION).asFragment())
- || !dir.startsWith(execRoot())) {
+ || !dir.asFragment().startsWith(execRoot().asFragment())) {
return;
}
AtomicReference<IOException> caughtException = new AtomicReference<>();