Turn SandboxHelpers into a stateful class.
This is to simplify an upcoming fix, which requires tracking an option,
and an upcoming optimization, which requires carrying state around the
various sandbox instances.
RELNOTES: None.
PiperOrigin-RevId: 301837964
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
index e2a5658..85dc8b0 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedSpawnRunner.java
@@ -99,6 +99,7 @@
return true;
}
+ private final SandboxHelpers helpers;
private final Path execRoot;
private final boolean allowNetwork;
private final Path processWrapper;
@@ -120,6 +121,7 @@
* Creates a sandboxed spawn runner that uses the {@code process-wrapper} tool and the MacOS
* {@code sandbox-exec} binary.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param sandboxBase path to the sandbox base directory
* @param timeoutKillDelay additional grace period before killing timing out commands
@@ -128,6 +130,7 @@
* @param sandboxfsMapSymlinkTargets map the targets of symlinks within the sandbox if true
*/
DarwinSandboxedSpawnRunner(
+ SandboxHelpers helpers,
CommandEnvironment cmdEnv,
Path sandboxBase,
Duration timeoutKillDelay,
@@ -136,8 +139,9 @@
TreeDeleter treeDeleter)
throws IOException {
super(cmdEnv);
+ this.helpers = helpers;
this.execRoot = cmdEnv.getExecRoot();
- this.allowNetwork = SandboxHelpers.shouldAllowNetwork(cmdEnv.getOptions());
+ this.allowNetwork = helpers.shouldAllowNetwork(cmdEnv.getOptions());
this.alwaysWritableDirs = getAlwaysWritableDirs(cmdEnv.getRuntime().getFileSystem());
this.processWrapper = ProcessWrapperUtil.getProcessWrapper(cmdEnv);
this.localEnvProvider = LocalEnvProvider.forCurrentOs(cmdEnv.getClientEnv());
@@ -231,13 +235,13 @@
writableDirs.addAll(extraWritableDirs);
SandboxInputs inputs =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(
getSandboxOptions().symlinkedSandboxExpandsTreeArtifactsInRunfilesTree),
spawn,
context.getArtifactExpander(),
execRoot);
- SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
+ SandboxOutputs outputs = helpers.getOutputs(spawn);
final Path sandboxConfigPath = sandboxPath.getRelative("sandbox.sb");
Duration timeout = context.getTimeout();
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
index dfda924..ccbd38b 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DockerSandboxedSpawnRunner.java
@@ -137,6 +137,7 @@
private static final ConcurrentHashMap<String, String> imageMap = new ConcurrentHashMap<>();
+ private final SandboxHelpers helpers;
private final Path execRoot;
private final boolean allowNetwork;
private final Path dockerClient;
@@ -157,6 +158,7 @@
/**
* Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param dockerClient path to the `docker` executable
* @param sandboxBase path to the sandbox base directory
@@ -166,6 +168,7 @@
* @param treeDeleter scheduler for tree deletions
*/
DockerSandboxedSpawnRunner(
+ SandboxHelpers helpers,
CommandEnvironment cmdEnv,
Path dockerClient,
Path sandboxBase,
@@ -174,8 +177,9 @@
boolean useCustomizedImages,
TreeDeleter treeDeleter) {
super(cmdEnv);
+ this.helpers = helpers;
this.execRoot = cmdEnv.getExecRoot();
- this.allowNetwork = SandboxHelpers.shouldAllowNetwork(cmdEnv.getOptions());
+ this.allowNetwork = helpers.shouldAllowNetwork(cmdEnv.getOptions());
this.dockerClient = dockerClient;
this.processWrapper = ProcessWrapperUtil.getProcessWrapper(cmdEnv);
this.sandboxBase = sandboxBase;
@@ -218,13 +222,13 @@
localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), binTools, "/tmp");
SandboxInputs inputs =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(
getSandboxOptions().symlinkedSandboxExpandsTreeArtifactsInRunfilesTree),
spawn,
context.getArtifactExpander(),
execRoot);
- SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
+ SandboxOutputs outputs = helpers.getOutputs(spawn);
Duration timeout = context.getTimeout();
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
index d569c9b..3332796 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
@@ -86,6 +86,7 @@
return true;
}
+ private final SandboxHelpers helpers;
private final FileSystem fileSystem;
private final BlazeDirectories blazeDirs;
private final Path execRoot;
@@ -103,6 +104,7 @@
/**
* Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param sandboxBase path to the sandbox base directory
* @param inaccessibleHelperFile path to a file that is (already) inaccessible
@@ -113,6 +115,7 @@
* @param sandboxfsMapSymlinkTargets map the targets of symlinks within the sandbox if true
*/
LinuxSandboxedSpawnRunner(
+ SandboxHelpers helpers,
CommandEnvironment cmdEnv,
Path sandboxBase,
Path inaccessibleHelperFile,
@@ -122,10 +125,11 @@
boolean sandboxfsMapSymlinkTargets,
TreeDeleter treeDeleter) {
super(cmdEnv);
+ this.helpers = helpers;
this.fileSystem = cmdEnv.getRuntime().getFileSystem();
this.blazeDirs = cmdEnv.getDirectories();
this.execRoot = cmdEnv.getExecRoot();
- this.allowNetwork = SandboxHelpers.shouldAllowNetwork(cmdEnv.getOptions());
+ this.allowNetwork = helpers.shouldAllowNetwork(cmdEnv.getOptions());
this.linuxSandbox = LinuxSandboxUtil.getLinuxSandbox(cmdEnv);
this.sandboxBase = sandboxBase;
this.inaccessibleHelperFile = inaccessibleHelperFile;
@@ -161,13 +165,13 @@
ImmutableSet<Path> writableDirs = getWritableDirs(sandboxExecRoot, environment);
SandboxInputs inputs =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(
getSandboxOptions().symlinkedSandboxExpandsTreeArtifactsInRunfilesTree),
spawn,
context.getArtifactExpander(),
execRoot);
- SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
+ SandboxOutputs outputs = helpers.getOutputs(spawn);
Duration timeout = context.getTimeout();
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 a31938b..70f4325 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
@@ -38,6 +38,7 @@
/**
* Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param sandboxBase path to the sandbox base directory
* @param timeoutKillDelay additional grace period before killing timing out commands
@@ -46,6 +47,7 @@
* @param sandboxfsMapSymlinkTargets map the targets of symlinks within the sandbox if true
*/
static LinuxSandboxedSpawnRunner create(
+ SandboxHelpers helpers,
CommandEnvironment cmdEnv,
Path sandboxBase,
Duration timeoutKillDelay,
@@ -66,6 +68,7 @@
inaccessibleHelperDir.setExecutable(false);
return new LinuxSandboxedSpawnRunner(
+ helpers,
cmdEnv,
sandboxBase,
inaccessibleHelperFile,
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
index 489ac89..65f6748 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperSandboxedSpawnRunner.java
@@ -37,6 +37,7 @@
return OS.isPosixCompatible() && ProcessWrapperUtil.isSupported(cmdEnv);
}
+ private final SandboxHelpers helpers;
private final Path processWrapper;
private final Path execRoot;
private final Path sandboxBase;
@@ -49,6 +50,7 @@
/**
* Creates a sandboxed spawn runner that uses the {@code process-wrapper} tool.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param sandboxBase path to the sandbox base directory
* @param timeoutKillDelay additional grace period before killing timing out commands
@@ -57,6 +59,7 @@
* @param sandboxfsMapSymlinkTargets map the targets of symlinks within the sandbox if true
*/
ProcessWrapperSandboxedSpawnRunner(
+ SandboxHelpers helpers,
CommandEnvironment cmdEnv,
Path sandboxBase,
Duration timeoutKillDelay,
@@ -64,6 +67,7 @@
boolean sandboxfsMapSymlinkTargets,
TreeDeleter treeDeleter) {
super(cmdEnv);
+ this.helpers = helpers;
this.processWrapper = ProcessWrapperUtil.getProcessWrapper(cmdEnv);
this.execRoot = cmdEnv.getExecRoot();
this.localEnvProvider = LocalEnvProvider.forCurrentOs(cmdEnv.getClientEnv());
@@ -109,13 +113,13 @@
}
SandboxInputs inputs =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(
getSandboxOptions().symlinkedSandboxExpandsTreeArtifactsInRunfilesTree),
spawn,
context.getArtifactExpander(),
execRoot);
- SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
+ SandboxOutputs outputs = helpers.getOutputs(spawn);
if (sandboxfsProcess != null) {
return new SandboxfsSandboxedSpawn(
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java
index 5d9ee96..f7dc09b 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java
@@ -35,7 +35,11 @@
import java.util.Map;
import java.util.TreeMap;
-/** Helper methods that are shared by the different sandboxing strategies in this package. */
+/**
+ * Helper methods that are shared by the different sandboxing strategies.
+ *
+ * <p>All sandboxed strategies within a build should share the same instance of this object.
+ */
public final class SandboxHelpers {
/** Wrapper class for the inputs of a sandbox. */
public static final class SandboxInputs {
@@ -64,7 +68,7 @@
*
* @throws IOException If any files could not be written.
*/
- public static SandboxInputs processInputFiles(
+ public SandboxInputs processInputFiles(
Map<PathFragment, ActionInput> inputMap,
Spawn spawn,
ArtifactExpander artifactExpander,
@@ -140,7 +144,7 @@
}
}
- public static SandboxOutputs getOutputs(Spawn spawn) {
+ public SandboxOutputs getOutputs(Spawn spawn) {
ImmutableSet.Builder<PathFragment> files = ImmutableSet.builder();
ImmutableSet.Builder<PathFragment> dirs = ImmutableSet.builder();
for (ActionInput output : spawn.getOutputFiles()) {
@@ -161,7 +165,7 @@
* reference to the full set of build options (and also for performance, since this only needs to
* be checked once-per-build).
*/
- static boolean shouldAllowNetwork(OptionsParsingResult buildOptions) {
+ boolean shouldAllowNetwork(OptionsParsingResult buildOptions) {
// Allow network access, when --java_debug is specified, otherwise we can't connect to the
// remote debug server of the test. This intentionally overrides the "block-network" execution
// tag.
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxModule.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxModule.java
index 10ae634..21fe4ac 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxModule.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxModule.java
@@ -180,6 +180,8 @@
SandboxOptions options = checkNotNull(env.getOptions().getOptions(SandboxOptions.class));
sandboxBase = computeSandboxBase(options, env);
+ SandboxHelpers helpers = new SandboxHelpers();
+
// Do not remove the sandbox base when --sandbox_debug was specified so that people can check
// out the contents of the generated sandbox directories.
shouldCleanupSandboxBase = !options.sandboxDebug;
@@ -269,6 +271,7 @@
withFallback(
cmdEnv,
new ProcessWrapperSandboxedSpawnRunner(
+ helpers,
cmdEnv,
sandboxBase,
timeoutKillDelay,
@@ -296,6 +299,7 @@
withFallback(
cmdEnv,
new DockerSandboxedSpawnRunner(
+ helpers,
cmdEnv,
pathToDocker,
sandboxBase,
@@ -321,6 +325,7 @@
withFallback(
cmdEnv,
LinuxSandboxedStrategy.create(
+ helpers,
cmdEnv,
sandboxBase,
timeoutKillDelay,
@@ -341,6 +346,7 @@
withFallback(
cmdEnv,
new DarwinSandboxedSpawnRunner(
+ helpers,
cmdEnv,
sandboxBase,
timeoutKillDelay,
@@ -359,7 +365,8 @@
SpawnRunner spawnRunner =
withFallback(
cmdEnv,
- new WindowsSandboxedSpawnRunner(cmdEnv, timeoutKillDelay, windowsSandboxPath));
+ new WindowsSandboxedSpawnRunner(
+ helpers, cmdEnv, timeoutKillDelay, windowsSandboxPath));
spawnRunners.add(spawnRunner);
builder.addActionContext(
SpawnStrategy.class,
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
index ceb0757..afbfa6e 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/WindowsSandboxedSpawnRunner.java
@@ -31,6 +31,7 @@
/** Spawn runner that uses BuildXL Sandbox APIs to execute a local subprocess. */
final class WindowsSandboxedSpawnRunner extends AbstractSandboxSpawnRunner {
+ private final SandboxHelpers helpers;
private final Path execRoot;
private final PathFragment windowsSandbox;
private final LocalEnvProvider localEnvProvider;
@@ -39,13 +40,18 @@
/**
* Creates a sandboxed spawn runner that uses the {@code windows-sandbox} tool.
*
+ * @param helpers common tools and state across all spawns during sandboxed execution
* @param cmdEnv the command environment to use
* @param timeoutKillDelay an additional grace period before killing timing out commands
* @param windowsSandboxPath path to windows-sandbox binary
*/
WindowsSandboxedSpawnRunner(
- CommandEnvironment cmdEnv, Duration timeoutKillDelay, PathFragment windowsSandboxPath) {
+ SandboxHelpers helpers,
+ CommandEnvironment cmdEnv,
+ Duration timeoutKillDelay,
+ PathFragment windowsSandboxPath) {
super(cmdEnv);
+ this.helpers = helpers;
this.execRoot = cmdEnv.getExecRoot();
this.windowsSandbox = windowsSandboxPath;
this.timeoutKillDelay = timeoutKillDelay;
@@ -63,7 +69,7 @@
spawn.getEnvironment(), binTools, commandTmpDir.getPathString());
SandboxInputs readablePaths =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(
getSandboxOptions().symlinkedSandboxExpandsTreeArtifactsInRunfilesTree),
spawn,
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerModule.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerModule.java
index 4d521cd..adcf574 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerModule.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerModule.java
@@ -34,6 +34,7 @@
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.runtime.commands.CleanCommand.CleanStartingEvent;
+import com.google.devtools.build.lib.sandbox.SandboxHelpers;
import com.google.devtools.build.lib.sandbox.SandboxOptions;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.worker.WorkerOptions.MultiResourceConverter;
@@ -144,6 +145,7 @@
LocalEnvProvider localEnvProvider = LocalEnvProvider.forCurrentOs(env.getClientEnv());
WorkerSpawnRunner spawnRunner =
new WorkerSpawnRunner(
+ new SandboxHelpers(),
env.getExecRoot(),
workerPool,
extraFlags,
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
index 244d321..e9b54c3 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
@@ -75,6 +75,7 @@
/** Pattern for @flagfile.txt and --flagfile=flagfile.txt */
private static final Pattern FLAG_FILE_PATTERN = Pattern.compile("(?:@|--?flagfile=)(.+)");
+ private final SandboxHelpers helpers;
private final Path execRoot;
private final WorkerPool workers;
private final Multimap<String, String> extraFlags;
@@ -87,6 +88,7 @@
private final RunfilesTreeUpdater runfilesTreeUpdater;
public WorkerSpawnRunner(
+ SandboxHelpers helpers,
Path execRoot,
WorkerPool workers,
Multimap<String, String> extraFlags,
@@ -97,6 +99,7 @@
BinTools binTools,
ResourceManager resourceManager,
RunfilesTreeUpdater runfilesTreeUpdater) {
+ this.helpers = helpers;
this.execRoot = execRoot;
this.workers = Preconditions.checkNotNull(workers);
this.extraFlags = extraFlags;
@@ -171,12 +174,12 @@
HashCode workerFilesCombinedHash = WorkerFilesHash.getCombinedHash(workerFiles);
SandboxInputs inputFiles =
- SandboxHelpers.processInputFiles(
+ helpers.processInputFiles(
context.getInputMapping(sandboxUsesExpandedTreeArtifactsInRunfiles),
spawn,
context.getArtifactExpander(),
execRoot);
- SandboxOutputs outputs = SandboxHelpers.getOutputs(spawn);
+ SandboxOutputs outputs = helpers.getOutputs(spawn);
WorkerKey key =
new WorkerKey(