aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/exec
diff options
context:
space:
mode:
authorGravatar buchgr <buchgr@google.com>2018-08-02 06:47:19 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-02 06:48:54 -0700
commitd4d3d506f4cf6cfaafaeeb717d681ff7784e2384 (patch)
tree0dd0aad48aadde21b44d6153b3489bcd882ba904 /src/main/java/com/google/devtools/build/lib/exec
parentdcd7c63d09e12fc3e2a9ca80b1422e4bcdd2740f (diff)
remote: add support for directory inputs in runfiles
Add support for tree artifacts (ctx.action.declare_directory(...)) in runfiles. Before this change we would throw away the information about the files inside a tree artifact before executing an action. That's fine for local execution where the sandbox just copies/symlinks a directory and doesn't care much what's inside. However, in remote execution we actually need to upload each individual file and so we need to be aware of all individual files not just directories. This change makes it so that this information is made available to a SpawnRunner via the SpawnInputExpander. RELNOTES: None PiperOrigin-RevId: 207091668
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/exec')
-rw-r--r--src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
index 444ffa51b6..0e965b32dd 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
@@ -20,6 +20,8 @@ import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
+import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
import com.google.devtools.build.lib.actions.MetadataProvider;
import com.google.devtools.build.lib.actions.RunfilesSupplier;
@@ -29,6 +31,7 @@ import com.google.devtools.build.lib.exec.FilesetManifest.RelativeSymlinkBehavio
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
@@ -40,8 +43,7 @@ import java.util.TreeMap;
* laid out.
*/
public class SpawnInputExpander {
- @VisibleForTesting
- static final ActionInput EMPTY_FILE = new EmptyActionInput("/dev/null");
+ @VisibleForTesting static final ActionInput EMPTY_FILE = new EmptyActionInput("/dev/null");
private final Path execRoot;
private final boolean strict;
@@ -103,10 +105,11 @@ public class SpawnInputExpander {
void addRunfilesToInputs(
Map<PathFragment, ActionInput> inputMap,
RunfilesSupplier runfilesSupplier,
- MetadataProvider actionFileCache)
+ MetadataProvider actionFileCache,
+ ArtifactExpander artifactExpander)
throws IOException {
- Map<PathFragment, Map<PathFragment, Artifact>> rootsAndMappings = null;
- rootsAndMappings = runfilesSupplier.getMappings();
+ Map<PathFragment, Map<PathFragment, Artifact>> rootsAndMappings =
+ runfilesSupplier.getMappings();
for (Map.Entry<PathFragment, Map<PathFragment, Artifact>> rootAndMappings :
rootsAndMappings.entrySet()) {
@@ -116,10 +119,23 @@ public class SpawnInputExpander {
PathFragment location = root.getRelative(mapping.getKey());
Artifact localArtifact = mapping.getValue();
if (localArtifact != null) {
- if (strict && !actionFileCache.getMetadata(localArtifact).getType().isFile()) {
- throw new IOException("Not a file: " + localArtifact.getPath().getPathString());
+ Preconditions.checkState(!localArtifact.isMiddlemanArtifact());
+ if (localArtifact.isTreeArtifact()) {
+ List<ActionInput> expandedInputs =
+ ActionInputHelper.expandArtifacts(
+ Collections.singletonList(localArtifact), artifactExpander);
+ for (ActionInput input : expandedInputs) {
+ addMapping(
+ inputMap,
+ location.getRelative(((TreeFileArtifact) input).getParentRelativePath()),
+ input);
+ }
+ } else {
+ if (strict) {
+ failIfDirectory(actionFileCache, localArtifact);
+ }
+ addMapping(inputMap, location, localArtifact);
}
- addMapping(inputMap, location, localArtifact);
} else {
addMapping(inputMap, location, EMPTY_FILE);
}
@@ -127,6 +143,14 @@ public class SpawnInputExpander {
}
}
+ private static void failIfDirectory(MetadataProvider actionFileCache, ActionInput input)
+ throws IOException {
+ FileArtifactValue metadata = actionFileCache.getMetadata(input);
+ if (metadata != null && !metadata.getType().isFile()) {
+ throw new IOException("Not a file: " + input.getExecPathString());
+ }
+ }
+
/**
* Parses the fileset manifest file, adding to the inputMappings where appropriate. Lines
* referring to directories are recursed.
@@ -175,10 +199,15 @@ public class SpawnInputExpander {
}
/**
- * Convert the inputs of the given spawn to a map from exec-root relative paths to action inputs.
- * The returned map never contains {@code null} values; it uses {@link #EMPTY_FILE} for empty
+ * Convert the inputs and runfiles of the given spawn to a map from exec-root relative paths to
+ * {@link ActionInput}s. The returned map does not contain tree artifacts as they are expanded
+ * to file artifacts.
+ *
+ * <p>The returned map never contains {@code null} values; it uses {@link #EMPTY_FILE} for empty
* files, which is an instance of {@link
* com.google.devtools.build.lib.actions.cache.VirtualActionInput}.
+ *
+ * <p>The returned map contains all runfiles, but not the {@code MANIFEST}.
*/
public SortedMap<PathFragment, ActionInput> getInputMapping(
Spawn spawn, ArtifactExpander artifactExpander, MetadataProvider actionInputFileCache)
@@ -186,7 +215,7 @@ public class SpawnInputExpander {
TreeMap<PathFragment, ActionInput> inputMap = new TreeMap<>();
addInputs(inputMap, spawn, artifactExpander);
addRunfilesToInputs(
- inputMap, spawn.getRunfilesSupplier(), actionInputFileCache);
+ inputMap, spawn.getRunfilesSupplier(), actionInputFileCache, artifactExpander);
addFilesetManifests(spawn.getFilesetMappings(), inputMap);
return inputMap;
}