diff options
8 files changed, 65 insertions, 227 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedStrategy.java index c248648ecf..cd1429fe6d 100644 --- a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxedStrategy.java @@ -35,6 +35,7 @@ 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.buildtool.BuildRequest; 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; @@ -75,9 +76,9 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { private final ImmutableMap<String, String> clientEnv; private final BlazeDirectories blazeDirs; private final Path execRoot; + private final BuildRequest buildRequest; private final SandboxOptions sandboxOptions; private final boolean verboseFailures; - private final boolean unblockNetwork; private final String productName; private final ImmutableList<Path> confPaths; @@ -85,32 +86,30 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { private final AtomicInteger execCounter = new AtomicInteger(); private DarwinSandboxedStrategy( - SandboxOptions options, + BuildRequest buildRequest, Map<String, String> clientEnv, BlazeDirectories blazeDirs, ExecutorService backgroundWorkers, boolean verboseFailures, - boolean unblockNetwork, String productName, ImmutableList<Path> confPaths) { - this.sandboxOptions = options; + this.buildRequest = buildRequest; + this.sandboxOptions = buildRequest.getOptions(SandboxOptions.class); this.clientEnv = ImmutableMap.copyOf(clientEnv); this.blazeDirs = blazeDirs; this.execRoot = blazeDirs.getExecRoot(); this.backgroundWorkers = Preconditions.checkNotNull(backgroundWorkers); this.verboseFailures = verboseFailures; - this.unblockNetwork = unblockNetwork; this.productName = productName; this.confPaths = confPaths; } public static DarwinSandboxedStrategy create( - SandboxOptions options, + BuildRequest buildRequest, Map<String, String> clientEnv, BlazeDirectories blazeDirs, ExecutorService backgroundWorkers, boolean verboseFailures, - boolean unblockNetwork, String productName) throws IOException { // On OS X, in addition to what is specified in $TMPDIR, two other temporary directories may be @@ -125,12 +124,11 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { } return new DarwinSandboxedStrategy( - options, + buildRequest, clientEnv, blazeDirs, backgroundWorkers, verboseFailures, - unblockNetwork, productName, writablePaths.build()); } @@ -264,9 +262,7 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { DarwinSandboxRunner runner; try { Path sandboxConfigPath = - generateScriptFile( - sandboxPath, - unblockNetwork || spawn.getExecutionInfo().containsKey("requires-network")); + generateScriptFile(sandboxPath, SandboxHelpers.shouldAllowNetwork(buildRequest, spawn)); runner = new DarwinSandboxRunner( execRoot, @@ -297,7 +293,7 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { return dirs.build(); } - private Path generateScriptFile(Path sandboxPath, boolean network) throws IOException { + private Path generateScriptFile(Path sandboxPath, boolean allowNetwork) throws IOException { FileSystemUtils.createDirectoryAndParents(sandboxPath); Path sandboxConfigPath = sandboxPath.getParentDirectory().getRelative(sandboxPath.getBaseName() + ".sb"); @@ -316,7 +312,7 @@ public class DarwinSandboxedStrategy implements SpawnActionContext { out.println("(allow network* (remote unix-socket (subpath \"/\")))"); out.println("(allow network* (local unix-socket (subpath \"/\")))"); // check network - if (network) { + if (allowNetwork) { out.println("(allow network*)"); } 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 06c84de165..4a786100f3 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 @@ -122,7 +122,7 @@ public class LinuxSandboxRunner { Map<PathFragment, Path> inputs, Collection<PathFragment> outputs, int timeout, - boolean blockNetwork) + boolean allowNetwork) throws IOException, ExecException { createFileSystem(inputs, outputs); @@ -159,7 +159,7 @@ public class LinuxSandboxRunner { fileArgs.add(inaccessiblePath.getPathString()); } - if (blockNetwork) { + if (!allowNetwork) { // Block network access out of the namespace. fileArgs.add("-N"); } 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 4ee34e891e..d6e65c34d7 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,6 +30,7 @@ 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.buildtool.BuildRequest; 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; @@ -69,28 +70,27 @@ public class LinuxSandboxedStrategy implements SpawnActionContext { private final ExecutorService backgroundWorkers; + private final BuildRequest buildRequest; private final SandboxOptions sandboxOptions; private final BlazeDirectories blazeDirs; private final Path execRoot; private final boolean verboseFailures; - private final boolean unblockNetwork; private final UUID uuid = UUID.randomUUID(); private final AtomicInteger execCounter = new AtomicInteger(); private final String productName; LinuxSandboxedStrategy( - SandboxOptions options, + BuildRequest buildRequest, BlazeDirectories blazeDirs, ExecutorService backgroundWorkers, boolean verboseFailures, - boolean unblockNetwork, String productName) { - this.sandboxOptions = options; + this.buildRequest = buildRequest; + this.sandboxOptions = buildRequest.getOptions(SandboxOptions.class); this.blazeDirs = blazeDirs; this.execRoot = blazeDirs.getExecRoot(); this.backgroundWorkers = Preconditions.checkNotNull(backgroundWorkers); this.verboseFailures = verboseFailures; - this.unblockNetwork = unblockNetwork; this.productName = productName; } @@ -170,7 +170,7 @@ public class LinuxSandboxedStrategy implements SpawnActionContext { mounts, outputFiles.build(), timeout, - !this.unblockNetwork && !spawn.getExecutionInfo().containsKey("requires-network")); + SandboxHelpers.shouldAllowNetwork(buildRequest, spawn)); } finally { // Due to the Linux kernel behavior, if we try to remove the sandbox too quickly after the // process has exited, we get "Device busy" errors because some of the mounts have not yet 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 7bf38c901b..40f11aaf0e 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 @@ -16,7 +16,6 @@ package com.google.devtools.build.lib.sandbox; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.ActionContextProvider; import com.google.devtools.build.lib.actions.Executor.ActionContext; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.buildtool.BuildRequest; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.exec.ExecutionOptions; @@ -46,11 +45,6 @@ public class SandboxActionContextProvider extends ActionContextProvider { CommandEnvironment env, BuildRequest buildRequest, ExecutorService backgroundWorkers) throws IOException { boolean verboseFailures = buildRequest.getOptions(ExecutionOptions.class).verboseFailures; - boolean unblockNetwork = - buildRequest - .getOptions(BuildConfiguration.Options.class) - .testArguments - .contains("--wrapper_script_flag=--debug"); ImmutableList.Builder<ActionContext> contexts = ImmutableList.builder(); switch (OS.getCurrent()) { @@ -58,11 +52,10 @@ public class SandboxActionContextProvider extends ActionContextProvider { if (LinuxSandboxedStrategy.isSupported(env)) { contexts.add( new LinuxSandboxedStrategy( - buildRequest.getOptions(SandboxOptions.class), + buildRequest, env.getDirectories(), backgroundWorkers, verboseFailures, - unblockNetwork, env.getRuntime().getProductName())); } else if (!buildRequest.getOptions(SandboxOptions.class).ignoreUnsupportedSandboxing) { env.getReporter().handle(Event.warn(SANDBOX_NOT_SUPPORTED_MESSAGE)); @@ -72,12 +65,11 @@ public class SandboxActionContextProvider extends ActionContextProvider { if (DarwinSandboxRunner.isSupported()) { contexts.add( DarwinSandboxedStrategy.create( - buildRequest.getOptions(SandboxOptions.class), + buildRequest, env.getClientEnv(), env.getDirectories(), backgroundWorkers, verboseFailures, - unblockNetwork, env.getRuntime().getProductName())); } break; 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 new file mode 100644 index 0000000000..bd8c365c3c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxHelpers.java @@ -0,0 +1,45 @@ +// 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.actions.Spawn; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.buildtool.BuildRequest; + +/** Helper methods that are shared by the different sandboxing strategies in this package. */ +final class SandboxHelpers { + + static boolean shouldAllowNetwork(BuildRequest buildRequest, Spawn spawn) { + // If we don't run tests, allow network access. + if (!buildRequest.shouldRunTests()) { + return true; + } + + // If the Spawn specifically requests network access, allow it. + if (spawn.getExecutionInfo().containsKey("requires-network")) { + return true; + } + + // Allow network access, when --java_debug is specified, otherwise we can't connect to the + // remote debug server of the test. + if (buildRequest + .getOptions(BuildConfiguration.Options.class) + .testArguments + .contains("--wrapper_script_flag=--debug")) { + return true; + } + + return false; + } +} diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java index a80074a9fa..c9e96501fa 100644 --- a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java @@ -13,29 +13,11 @@ // limitations under the License. package com.google.devtools.build.lib.sandbox; -import static com.google.common.truth.Truth.assertThat; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.eventbus.EventBus; -import com.google.common.util.concurrent.MoreExecutors; -import com.google.devtools.build.lib.actions.ActionContextProvider; -import com.google.devtools.build.lib.actions.BlazeExecutor; -import com.google.devtools.build.lib.actions.Executor.ActionContext; -import com.google.devtools.build.lib.actions.SpawnActionContext; -import com.google.devtools.build.lib.analysis.BlazeDirectories; -import com.google.devtools.build.lib.events.PrintingEventHandler; -import com.google.devtools.build.lib.events.Reporter; -import com.google.devtools.build.lib.exec.ExecutionOptions; -import com.google.devtools.build.lib.testutil.BlazeTestUtils; -import com.google.devtools.build.lib.testutil.TestFileOutErr; import com.google.devtools.build.lib.testutil.TestUtils; -import com.google.devtools.build.lib.util.BlazeClock; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.util.FileSystems; -import com.google.devtools.common.options.OptionsParser; import java.io.IOException; import org.junit.Before; @@ -43,70 +25,15 @@ import org.junit.Before; * Common parts of all {@link LinuxSandboxedStrategy} tests. */ public class LinuxSandboxedStrategyTestCase { - private Reporter reporter = new Reporter(PrintingEventHandler.ERRORS_AND_WARNINGS_TO_STDERR); - private Path outputBase; - protected FileSystem fileSystem; protected Path workspaceDir; - protected BlazeExecutor executor; - protected BlazeDirectories blazeDirs; - - protected TestFileOutErr outErr = new TestFileOutErr(); - - protected String out() { - return outErr.outAsLatin1(); - } - - protected String err() { - return outErr.errAsLatin1(); - } - @Before public final void createDirectoriesAndExecutor() throws Exception { Path testRoot = createTestRoot(); workspaceDir = testRoot.getRelative("workspace"); workspaceDir.createDirectory(); - - outputBase = testRoot.getRelative("outputBase"); - outputBase.createDirectory(); - - blazeDirs = new BlazeDirectories(outputBase, outputBase, workspaceDir, "mock-product-name"); - BlazeTestUtils.getIntegrationBinTools(blazeDirs); - - OptionsParser optionsParser = - OptionsParser.newOptionsParser(ExecutionOptions.class, SandboxOptions.class); - - EventBus bus = new EventBus(); - - this.executor = - new BlazeExecutor( - blazeDirs.getExecRoot(), - blazeDirs.getOutputPath(), - reporter, - bus, - BlazeClock.instance(), - optionsParser, - /* verboseFailures */ true, - /* showSubcommands */ false, - ImmutableList.<ActionContext>of(), - ImmutableMap.<String, SpawnActionContext>of( - "", - new LinuxSandboxedStrategy( - optionsParser.getOptions(SandboxOptions.class), - blazeDirs, - MoreExecutors.newDirectExecutorService(), - true, - false, - "mock-product-name")), - ImmutableList.<ActionContextProvider>of()); - } - - protected LinuxSandboxedStrategy getLinuxSandboxedStrategy() { - SpawnActionContext spawnActionContext = executor.getSpawnActionContext(""); - assertThat(spawnActionContext).isInstanceOf(LinuxSandboxedStrategy.class); - return (LinuxSandboxedStrategy) spawnActionContext; } private Path createTestRoot() throws IOException { diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LocalLinuxSandboxedStrategyTest.java b/src/test/java/com/google/devtools/build/lib/sandbox/LocalLinuxSandboxedStrategyTest.java deleted file mode 100644 index abf8630fe4..0000000000 --- a/src/test/java/com/google/devtools/build/lib/sandbox/LocalLinuxSandboxedStrategyTest.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2015 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 static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -import com.google.common.collect.ImmutableMap; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ActionExecutionMetadata; -import com.google.devtools.build.lib.actions.BaseSpawn; -import com.google.devtools.build.lib.actions.ResourceSet; -import com.google.devtools.build.lib.actions.Spawn; -import com.google.devtools.build.lib.actions.UserExecException; -import com.google.devtools.build.lib.actions.util.ActionsTestUtil; -import com.google.devtools.build.lib.exec.SingleBuildFileCache; -import com.google.devtools.build.lib.shell.BadExitStatusException; -import com.google.devtools.build.lib.testutil.TestSpec; -import com.google.devtools.build.lib.util.OS; -import com.google.devtools.build.lib.vfs.Path; -import java.util.Arrays; -import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@code LinuxSandboxedStrategy} that must run locally, because they need to actually run - * the linux-sandbox binary. - */ -@TestSpec(localOnly = true, supportedOs = OS.LINUX) -@RunWith(JUnit4.class) -public class LocalLinuxSandboxedStrategyTest extends LinuxSandboxedStrategyTestCase { - protected Spawn createSpawn(String... arguments) { - Map<String, String> environment = ImmutableMap.<String, String>of(); - Map<String, String> executionInfo = ImmutableMap.<String, String>of(); - ActionExecutionMetadata action = new ActionsTestUtil.NullAction(); - ResourceSet localResources = ResourceSet.ZERO; - return new BaseSpawn( - Arrays.asList(arguments), environment, executionInfo, action, localResources); - } - - protected ActionExecutionContext createContext() { - Path execRoot = executor.getExecRoot(); - return new ActionExecutionContext( - executor, - new SingleBuildFileCache(execRoot.getPathString(), execRoot.getFileSystem()), - null, - outErr, - ImmutableMap.of(), - null); - } - - @Test - public void testExecutionSuccess() throws Exception { - Spawn spawn = createSpawn("/bin/sh", "-c", "echo Hello, world.; touch dummy"); - getLinuxSandboxedStrategy().exec(spawn, createContext()); - assertThat(out()).isEqualTo("Hello, world.\n"); - assertThat(err()).isEmpty(); - } - - @Test - public void testExecutionFailurePrintsCorrectMessage() throws Exception { - Spawn spawn = createSpawn("/bin/sh", "-c", "echo ERROR >&2; exit 1"); - try { - getLinuxSandboxedStrategy().exec(spawn, createContext()); - fail(); - } catch (UserExecException e) { - assertThat(err()).isEqualTo("ERROR\n"); - assertThat(e.getCause()).isInstanceOf(BadExitStatusException.class); - } - } -} diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/SandboxLocalTests.java b/src/test/java/com/google/devtools/build/lib/sandbox/SandboxLocalTests.java deleted file mode 100644 index 55bf209084..0000000000 --- a/src/test/java/com/google/devtools/build/lib/sandbox/SandboxLocalTests.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 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.common.base.Predicates; -import com.google.devtools.build.lib.testutil.BlazeTestSuiteBuilder; -import com.google.devtools.build.lib.testutil.CustomSuite; - -import org.junit.runner.RunWith; - -import java.util.Set; - -/** - * Test suite that runs all tests that are local-only. - */ -@RunWith(CustomSuite.class) -public class SandboxLocalTests extends BlazeTestSuiteBuilder { - public static Set<Class<?>> suite() { - return new SandboxLocalTests() - .getBuilder() - .matchClasses( - Predicates.and( - BlazeTestSuiteBuilder.TEST_IS_LOCAL_ONLY, - BlazeTestSuiteBuilder.TEST_SUPPORTS_CURRENT_OS)) - .create(); - } -} |