diff options
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java | 64 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java | 29 |
2 files changed, 83 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java index 563a19f7f7..5bf57ec063 100644 --- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java @@ -30,10 +30,12 @@ import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.actions.Spawn; import com.google.devtools.build.lib.actions.SpawnActionContext; import com.google.devtools.build.lib.actions.UserExecException; +import com.google.devtools.build.lib.analysis.AnalysisUtils; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.config.RunUnder; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.rules.cpp.CppCompileAction; +import com.google.devtools.build.lib.rules.fileset.FilesetActionContext; import com.google.devtools.build.lib.rules.test.TestRunnerAction; import com.google.devtools.build.lib.standalone.StandaloneSpawnStrategy; import com.google.devtools.build.lib.unix.FilesystemUtils; @@ -46,7 +48,7 @@ import com.google.devtools.build.lib.vfs.SearchPath; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -203,13 +205,14 @@ public class LinuxSandboxedStrategy implements SpawnActionContext { return dirs.build(); } - private ImmutableMap<Path, Path> getMounts( - Spawn spawn, ActionExecutionContext executionContext) throws IOException { + private ImmutableMap<Path, Path> getMounts(Spawn spawn, ActionExecutionContext executionContext) + throws IOException, UserExecException { MountMap mounts = new MountMap(); mounts.putAll(mountUsualUnixDirs()); mounts.putAll(withRecursedDirs(setupBlazeUtils())); mounts.putAll(withRecursedDirs(mountRunfilesFromManifests(spawn))); mounts.putAll(withRecursedDirs(mountRunfilesFromSuppliers(spawn))); + mounts.putAll(withRecursedDirs(mountFilesFromFilesetManifests(spawn, executionContext))); mounts.putAll(withRecursedDirs(mountInputs(spawn, executionContext))); mounts.putAll(withRecursedDirs(mountRunUnderCommand(spawn))); return validateMounts(withResolvedSymlinks(mounts)); @@ -319,24 +322,68 @@ public class LinuxSandboxedStrategy implements SpawnActionContext { /** * Mount all runfiles that the spawn needs as specified in its runfiles manifests. */ - private MountMap mountRunfilesFromManifests(Spawn spawn) throws IOException { + private MountMap mountRunfilesFromManifests(Spawn spawn) throws IOException, UserExecException { MountMap mounts = new MountMap(); for (Entry<PathFragment, Artifact> manifest : spawn.getRunfilesManifests().entrySet()) { String manifestFilePath = manifest.getValue().getPath().getPathString(); Preconditions.checkState(!manifest.getKey().isAbsolute()); Path targetDirectory = execRoot.getRelative(manifest.getKey()); - mounts.putAll(parseManifestFile(targetDirectory, new File(manifestFilePath))); + mounts.putAll(parseManifestFile(targetDirectory, new File(manifestFilePath), false, "")); } return mounts; } - static MountMap parseManifestFile(Path targetDirectory, File manifestFile) throws IOException { + /** + * Mount all files that the spawn needs as specified in its fileset manifests. + */ + private MountMap mountFilesFromFilesetManifests( + Spawn spawn, ActionExecutionContext executionContext) throws IOException, UserExecException { + final FilesetActionContext filesetContext = + executionContext.getExecutor().getContext(FilesetActionContext.class); MountMap mounts = new MountMap(); - for (String line : Files.readLines(manifestFile, Charset.defaultCharset())) { + for (Artifact fileset : spawn.getFilesetManifests()) { + Path manifest = + execRoot.getRelative(AnalysisUtils.getManifestPathFromFilesetPath(fileset.getExecPath())); + Path targetDirectory = execRoot.getRelative(fileset.getExecPathString()); + + mounts.putAll( + parseManifestFile( + targetDirectory, manifest.getPathFile(), true, filesetContext.getWorkspaceName())); + } + return mounts; + } + + static MountMap parseManifestFile( + Path targetDirectory, File manifestFile, boolean isFilesetManifest, String workspaceName) + throws IOException, UserExecException { + MountMap mounts = new MountMap(); + int lineNum = 0; + for (String line : Files.readLines(manifestFile, StandardCharsets.UTF_8)) { + if (isFilesetManifest && (++lineNum % 2 == 0)) { + continue; + } + if (line.isEmpty()) { + continue; + } + String[] fields = line.trim().split(" "); + + Path targetPath; + if (isFilesetManifest) { + PathFragment targetPathFragment = new PathFragment(fields[0]); + if (!workspaceName.isEmpty()) { + if (!targetPathFragment.getSegment(0).equals(workspaceName)) { + throw new UserExecException("Fileset manifest line must start with workspace name"); + } + targetPathFragment = targetPathFragment.subFragment(1, targetPathFragment.segmentCount()); + } + targetPath = targetDirectory.getRelative(targetPathFragment); + } else { + targetPath = targetDirectory.getRelative(fields[0]); + } + Path source; - Path targetPath = targetDirectory.getRelative(fields[0]); switch (fields.length) { case 1: source = targetDirectory.getFileSystem().getPath("/dev/null"); @@ -347,6 +394,7 @@ public class LinuxSandboxedStrategy implements SpawnActionContext { default: throw new IllegalStateException("'" + line + "' splits into more than 2 parts"); } + mounts.put(targetPath, source); } return mounts; diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java index 74016762f4..94494e32c6 100644 --- a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java +++ b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.UserExecException; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -227,7 +228,7 @@ public class LinuxSandboxedStrategyTest extends LinuxSandboxedStrategyTestCase { } @Test - public void testParseManifestFile() throws IOException { + public void testParseManifestFile() throws IOException, UserExecException { Path targetDir = workspaceDir.getRelative("runfiles"); targetDir.createDirectory(); @@ -240,7 +241,8 @@ public class LinuxSandboxedStrategyTest extends LinuxSandboxedStrategyTestCase { Charset.defaultCharset(), String.format("x/testfile %s\nx/emptyfile \n", testFile.getPathString())); - Map mounts = LinuxSandboxedStrategy.parseManifestFile(targetDir, manifestFile.getPathFile()); + Map mounts = + LinuxSandboxedStrategy.parseManifestFile(targetDir, manifestFile.getPathFile(), false, ""); assertThat(userFriendlyMap(mounts)) .isEqualTo( @@ -251,4 +253,27 @@ public class LinuxSandboxedStrategyTest extends LinuxSandboxedStrategyTestCase { fileSystem.getPath("/runfiles/x/emptyfile"), fileSystem.getPath("/dev/null")))); } + + @Test + public void testParseFilesetManifestFile() throws IOException, UserExecException { + Path targetDir = workspaceDir.getRelative("fileset"); + targetDir.createDirectory(); + + Path testFile = workspaceDir.getRelative("testfile"); + FileSystemUtils.createEmptyFile(testFile); + + Path manifestFile = workspaceDir.getRelative("MANIFEST"); + FileSystemUtils.writeContent( + manifestFile, + Charset.defaultCharset(), + String.format("workspace/x/testfile %s\n0\n", testFile.getPathString())); + + Map mounts = + LinuxSandboxedStrategy.parseManifestFile( + targetDir, manifestFile.getPathFile(), true, "workspace"); + + assertThat(userFriendlyMap(mounts)) + .isEqualTo( + userFriendlyMap(ImmutableMap.of(fileSystem.getPath("/fileset/x/testfile"), testFile))); + } } |