From bf6ebe9f7c428e15b7c4d7e86a762b7470f97d5b Mon Sep 17 00:00:00 2001 From: Googler Date: Thu, 25 Jan 2024 12:51:55 -0800 Subject: [PATCH] Make tree artifacts that are symlinks to absolute paths work correctly. Previously, the code assumed that they are always symlinks whose realpath is under the execroot. RELNOTES: None. PiperOrigin-RevId: 601536298 Change-Id: Ia6a2c7f2c786e4d69b0d9e0be9c7f65af9931418 --- .../skyframe/ActionOutputMetadataStore.java | 4 +- src/test/shell/bazel/bazel_sandboxing_test.sh | 50 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionOutputMetadataStore.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionOutputMetadataStore.java index 1bc2f4c7c0ac6a..a112964bac4d2f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionOutputMetadataStore.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionOutputMetadataStore.java @@ -348,7 +348,9 @@ private TreeArtifactValue constructTreeArtifactValueFromFilesystem(SpecialArtifa } if (materializationExecPath == null) { - materializationExecPath = treeDir.resolveSymbolicLinks().asFragment().relativeTo(execRoot); + PathFragment realpath = treeDir.resolveSymbolicLinks().asFragment(); + materializationExecPath = + realpath.startsWith(execRoot) ? realpath.relativeTo(execRoot) : realpath; } tree.setMaterializationExecPath(materializationExecPath); diff --git a/src/test/shell/bazel/bazel_sandboxing_test.sh b/src/test/shell/bazel/bazel_sandboxing_test.sh index 91611c20570965..fa613b43a6b836 100755 --- a/src/test/shell/bazel/bazel_sandboxing_test.sh +++ b/src/test/shell/bazel/bazel_sandboxing_test.sh @@ -435,6 +435,56 @@ EOF bazel --output_base="$tmp_output_base" shutdown } +function test_symlink_to_directory_absolute_path() { + if [[ "$PLATFORM" == "darwin" ]]; then + # Tests Linux-specific functionality + return 0 + fi + + create_workspace_with_default_repos WORKSPACE + + sed -i.bak '/sandbox_tmpfs_path/d' $TEST_TMPDIR/bazelrc + + + mkdir -p /tmp/tree/{a,b} + touch /tmp/tree/{a,b}/file + + mkdir -p pkg + cat > pkg/BUILD <<'EOF' +load(":r.bzl", "symlink_rule", "tree_rule") + +symlink_rule(name="s", input=":t") +tree_rule(name="t") +EOF + + + cat > pkg/r.bzl <<'EOF' +def _symlink_impl(ctx): + output = ctx.actions.declare_directory(ctx.label.name) + ctx.actions.symlink(output = output, target_file = ctx.file.input) + return [DefaultInfo(files = depset([output]))] + +symlink_rule = rule( + implementation = _symlink_impl, + attrs = {"input": attr.label(allow_single_file=True)}) + +def _tree_impl(ctx): + output = ctx.actions.declare_directory(ctx.label.name) + ctx.actions.run_shell( + outputs = [output], + # Make the tree artifact itself a symlink to /tmp/tree + command = "export TREE=%s && rmdir $TREE && ln -s /tmp/tree $TREE" % output.path) + return [DefaultInfo(files = depset([output]))] + +tree_rule = rule( + implementation = _tree_impl, + attrs = {}) +EOF + + # /tmp/tree in the action sandbox must be the same as outside of it + bazel build --sandbox_add_mount_pair=/tmp/tree //pkg:s || fail "build failed" +} + function test_symlink_to_directory_with_output_base_under_tmp() { if [[ "$PLATFORM" == "darwin" ]]; then # Tests Linux-specific functionality