aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Yue Gan <yueg@google.com>2016-08-29 11:21:52 +0000
committerGravatar Klaus Aehlig <aehlig@google.com>2016-08-29 13:00:21 +0000
commitd0d6cf7f2a88624e443a7f5e50e21e6653f73d3e (patch)
tree4cc41b7ea41233b96a311d1135ed6b4725140272 /src/main
parent080dfc1ecb6fa3f7dd0f4e96e96b45a548724e4b (diff)
Add LinuxAlmostSandboxRunner which uses process-wrapper instead of linux-sandbox in the same sandbox execution environment.
-- Change-Id: I51a875a87d92ae13ad575eb41026ce5d3db94f8b Reviewed-on: https://bazel-review.googlesource.com/#/c/5611/ MOS_MIGRATED_REVID=131578077
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/LinuxAlmostSandboxRunner.java82
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java80
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java38
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextConsumer.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java10
5 files changed, 175 insertions, 39 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxAlmostSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxAlmostSandboxRunner.java
new file mode 100644
index 0000000000..73185f3bf0
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxAlmostSandboxRunner.java
@@ -0,0 +1,82 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.sandbox;
+
+import com.google.devtools.build.lib.runtime.CommandEnvironment;
+import com.google.devtools.build.lib.util.OsUtils;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Helper class for running the Linux sandbox. This runner is a subclass of LinuxSandboxRunner which
+ * uses process-wrapper instead of linux-sandbox in the same sandbox execution environment.
+ */
+public class LinuxAlmostSandboxRunner extends LinuxSandboxRunner {
+
+ LinuxAlmostSandboxRunner(
+ Path execRoot,
+ Path sandboxExecRoot,
+ Set<Path> writablePaths,
+ List<Path> inaccessiblePaths,
+ boolean verboseFailures,
+ boolean sandboxDebug) {
+ super(
+ execRoot, sandboxExecRoot, writablePaths, inaccessiblePaths, verboseFailures, sandboxDebug);
+ }
+
+ static boolean isSupported(CommandEnvironment commandEnv) {
+ PathFragment embeddedTool =
+ commandEnv
+ .getBlazeWorkspace()
+ .getBinTools()
+ .getExecPath("process-wrapper" + OsUtils.executableExtension());
+ if (embeddedTool == null) {
+ // The embedded tool does not exist, meaning that we don't support sandboxing (e.g., while
+ // bootstrapping).
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void runPreparation(int timeout, boolean allowNetwork) throws IOException {
+ // Create all needed directories.
+ for (Path writablePath : super.getWritablePaths()) {
+ if (writablePath.startsWith(super.getSandboxExecRoot())) {
+ FileSystemUtils.createDirectoryAndParents(writablePath);
+ }
+ }
+ }
+
+ @Override
+ protected List<String> runCommandLineArgs(List<String> spawnArguments, int timeout) {
+ List<String> commandLineArgs = new ArrayList<>();
+
+ commandLineArgs.add(super.getExecRoot().getRelative("_bin/process-wrapper").getPathString());
+ commandLineArgs.add(Integer.toString(timeout));
+ commandLineArgs.add("5"); /* kill delay: give some time to print stacktraces and whatnot. */
+ commandLineArgs.add("-"); /* stdout. */
+ commandLineArgs.add("-"); /* stderr. */
+
+ commandLineArgs.addAll(spawnArguments);
+
+ return commandLineArgs;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
index 4a786100f3..38c4db558c 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
@@ -47,7 +47,24 @@ import java.util.Set;
* handles sandbox output, performs cleanup and changes invocation if necessary.
*/
public class LinuxSandboxRunner {
- private static final String LINUX_SANDBOX = "linux-sandbox" + OsUtils.executableExtension();
+ protected static final String LINUX_SANDBOX = "linux-sandbox" + OsUtils.executableExtension();
+
+ protected Path getExecRoot() {
+ return execRoot;
+ }
+
+ protected Path getSandboxExecRoot() {
+ return sandboxExecRoot;
+ }
+
+ protected Set<Path> getWritablePaths() {
+ return writablePaths;
+ }
+
+ protected boolean isVerboseFailures() {
+ return verboseFailures;
+ }
+
private final Path execRoot;
private final Path sandboxExecRoot;
private final Path argumentsFilePath;
@@ -106,30 +123,10 @@ public class LinuxSandboxRunner {
return true;
}
- /**
- * Runs given
- *
- * @param spawnArguments - arguments of spawn to run inside the sandbox
- * @param env - environment to run sandbox in
- * @param outErr - error output to capture sandbox's and command's stderr
- * @param outputs - files to extract from the sandbox, paths are relative to the exec root @throws
- * ExecException
- */
- public void run(
- List<String> spawnArguments,
- Map<String, String> env,
- FileOutErr outErr,
- Map<PathFragment, Path> inputs,
- Collection<PathFragment> outputs,
- int timeout,
- boolean allowNetwork)
- throws IOException, ExecException {
- createFileSystem(inputs, outputs);
- List<String> fileArgs = new ArrayList<>();
- List<String> commandLineArgs = new ArrayList<>();
+ protected void runPreparation(int timeout, boolean allowNetwork) throws IOException {
- commandLineArgs.add(execRoot.getRelative("_bin/linux-sandbox").getPathString());
+ List<String> fileArgs = new ArrayList<>();
if (sandboxDebug) {
fileArgs.add("-D");
@@ -165,11 +162,44 @@ public class LinuxSandboxRunner {
}
FileSystemUtils.writeLinesAs(argumentsFilePath, StandardCharsets.ISO_8859_1, fileArgs);
+ }
+
+ protected List<String> runCommandLineArgs(List<String> spawnArguments, int timeout) {
+ List<String> commandLineArgs = new ArrayList<>();
+
+ commandLineArgs.add(execRoot.getRelative("_bin/linux-sandbox").getPathString());
+
commandLineArgs.add("@" + argumentsFilePath.getPathString());
commandLineArgs.add("--");
commandLineArgs.addAll(spawnArguments);
+ return commandLineArgs;
+ }
+
+ /**
+ * Runs given
+ *
+ * @param spawnArguments - arguments of spawn to run inside the sandbox
+ * @param env - environment to run sandbox in
+ * @param outErr - error output to capture sandbox's and command's stderr
+ * @param outputs - files to extract from the sandbox, paths are relative to the exec root @throws
+ * ExecException
+ */
+ public void run(
+ List<String> spawnArguments,
+ Map<String, String> env,
+ FileOutErr outErr,
+ Map<PathFragment, Path> inputs,
+ Collection<PathFragment> outputs,
+ int timeout,
+ boolean allowNetwork)
+ throws IOException, ExecException {
+ createFileSystem(inputs, outputs);
+
+ runPreparation(timeout, allowNetwork);
+
+ List<String> commandLineArgs = runCommandLineArgs(spawnArguments, timeout);
Command cmd =
new Command(commandLineArgs.toArray(new String[0]), env, sandboxExecRoot.getPathFile());
@@ -196,7 +226,7 @@ public class LinuxSandboxRunner {
}
}
- private void createFileSystem(Map<PathFragment, Path> inputs, Collection<PathFragment> outputs)
+ protected void createFileSystem(Map<PathFragment, Path> inputs, Collection<PathFragment> outputs)
throws IOException {
Set<Path> createdDirs = new HashSet<>();
FileSystemUtils.createDirectoryAndParentsWithCache(createdDirs, sandboxExecRoot);
@@ -245,7 +275,7 @@ public class LinuxSandboxRunner {
}
}
- private void copyOutputs(Collection<PathFragment> outputs) throws IOException {
+ protected void copyOutputs(Collection<PathFragment> outputs) throws IOException {
for (PathFragment output : outputs) {
Path source = sandboxExecRoot.getRelative(output);
if (source.isFile() || source.isSymbolicLink()) {
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 d6e65c34d7..962d24a349 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
@@ -63,7 +63,9 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
public static boolean isSupported(CommandEnvironment env) {
if (sandboxingSupported == null) {
- sandboxingSupported = LinuxSandboxRunner.isSupported(env);
+ // Currently LinuxSandboxRunner support <= LinuxAlmostSandboxRunner support
+ sandboxingSupported =
+ LinuxAlmostSandboxRunner.isSupported(env) || LinuxSandboxRunner.isSupported(env);
}
return sandboxingSupported.booleanValue();
}
@@ -78,13 +80,15 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
private final UUID uuid = UUID.randomUUID();
private final AtomicInteger execCounter = new AtomicInteger();
private final String productName;
+ private final boolean fullySupported;
LinuxSandboxedStrategy(
BuildRequest buildRequest,
BlazeDirectories blazeDirs,
ExecutorService backgroundWorkers,
boolean verboseFailures,
- String productName) {
+ String productName,
+ boolean fullySupported) {
this.buildRequest = buildRequest;
this.sandboxOptions = buildRequest.getOptions(SandboxOptions.class);
this.blazeDirs = blazeDirs;
@@ -92,6 +96,7 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
this.backgroundWorkers = Preconditions.checkNotNull(backgroundWorkers);
this.verboseFailures = verboseFailures;
this.productName = productName;
+ this.fullySupported = fullySupported;
}
/**
@@ -154,14 +159,27 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
}
try {
- final LinuxSandboxRunner runner =
- new LinuxSandboxRunner(
- execRoot,
- sandboxExecRoot,
- writablePaths,
- inaccessiblePaths,
- verboseFailures,
- sandboxOptions.sandboxDebug);
+ final LinuxSandboxRunner runner;
+ if (fullySupported) {
+ runner =
+ new LinuxSandboxRunner(
+ execRoot,
+ sandboxExecRoot,
+ writablePaths,
+ inaccessiblePaths,
+ verboseFailures,
+ sandboxOptions.sandboxDebug);
+ } else {
+ // Then LinuxAlmostSandboxRunner must be supported
+ runner =
+ new LinuxAlmostSandboxRunner(
+ execRoot,
+ sandboxExecRoot,
+ writablePaths,
+ inaccessiblePaths,
+ verboseFailures,
+ sandboxOptions.sandboxDebug);
+ }
try {
runner.run(
spawn.getArguments(),
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextConsumer.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextConsumer.java
index 7b4e30218a..83edc09130 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextConsumer.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextConsumer.java
@@ -20,6 +20,7 @@ import com.google.devtools.build.lib.actions.ActionContextConsumer;
import com.google.devtools.build.lib.actions.Executor.ActionContext;
import com.google.devtools.build.lib.actions.SpawnActionContext;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
+import com.google.devtools.build.lib.util.OS;
/**
* {@link ActionContextConsumer} that requests the action contexts necessary for sandboxed
@@ -33,7 +34,8 @@ public class SandboxActionContextConsumer implements ActionContextConsumer {
ImmutableMultimap.Builder<Class<? extends ActionContext>, String> contexts =
ImmutableMultimap.builder();
- if (LinuxSandboxedStrategy.isSupported(env)) {
+ if ((OS.getCurrent() == OS.LINUX && LinuxSandboxedStrategy.isSupported(env))
+ || (OS.getCurrent() == OS.DARWIN && DarwinSandboxRunner.isSupported())) {
contexts.put(SpawnActionContext.class, "sandboxed");
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
index 40f11aaf0e..0c7d7aa318 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
@@ -50,15 +50,19 @@ public class SandboxActionContextProvider extends ActionContextProvider {
switch (OS.getCurrent()) {
case LINUX:
if (LinuxSandboxedStrategy.isSupported(env)) {
+ boolean fullySupported = LinuxSandboxRunner.isSupported(env);
+ if (!fullySupported
+ && !buildRequest.getOptions(SandboxOptions.class).ignoreUnsupportedSandboxing) {
+ env.getReporter().handle(Event.warn(SANDBOX_NOT_SUPPORTED_MESSAGE));
+ }
contexts.add(
new LinuxSandboxedStrategy(
buildRequest,
env.getDirectories(),
backgroundWorkers,
verboseFailures,
- env.getRuntime().getProductName()));
- } else if (!buildRequest.getOptions(SandboxOptions.class).ignoreUnsupportedSandboxing) {
- env.getReporter().handle(Event.warn(SANDBOX_NOT_SUPPORTED_MESSAGE));
+ env.getRuntime().getProductName(),
+ fullySupported));
}
break;
case DARWIN: