use of com.google.devtools.build.lib.actions.UserExecException in project bazel by bazelbuild.
the class RemoteSpawnStrategy method execLocally.
/**
* Fallback: execute the spawn locally. If an ActionKey is provided, try to upload results to
* remote action cache.
*/
private void execLocally(Spawn spawn, ActionExecutionContext actionExecutionContext, RemoteActionCache actionCache, ActionKey actionKey) throws ExecException, InterruptedException {
standaloneStrategy.exec(spawn, actionExecutionContext);
if (options.remoteLocalExecUploadResults && actionCache != null && actionKey != null) {
ArrayList<Path> outputFiles = new ArrayList<>();
for (ActionInput output : spawn.getOutputFiles()) {
outputFiles.add(execRoot.getRelative(output.getExecPathString()));
}
try {
ActionResult.Builder result = ActionResult.newBuilder();
actionCache.uploadAllResults(execRoot, outputFiles, result);
actionCache.setCachedActionResult(actionKey, result.build());
// Handle all cache errors here.
} catch (IOException e) {
throw new UserExecException("Unexpected IO error.", e);
} catch (UnsupportedOperationException e) {
actionExecutionContext.getExecutor().getEventHandler().handle(Event.warn(spawn.getMnemonic() + " unsupported operation for action cache (" + e + ")"));
} catch (StatusRuntimeException e) {
actionExecutionContext.getExecutor().getEventHandler().handle(Event.warn(spawn.getMnemonic() + " failed uploading results (" + e + ")"));
}
}
}
use of com.google.devtools.build.lib.actions.UserExecException in project bazel by bazelbuild.
the class SpawnGccStrategy method execWithReply.
@Override
public CppCompileActionContext.Reply execWithReply(CppCompileAction action, ActionExecutionContext actionExecutionContext) throws ExecException, InterruptedException {
if (action.getDotdFile() != null && action.getDotdFile().artifact() == null) {
throw new UserExecException("cannot execute remotely or locally: " + action.getPrimaryInput().getExecPathString());
}
Iterable<Artifact> inputs = Iterables.concat(action.getInputs(), action.getAdditionalInputs());
Spawn spawn = new SimpleSpawn(action, ImmutableList.copyOf(action.getArgv()), ImmutableMap.copyOf(action.getEnvironment()), ImmutableMap.copyOf(action.getExecutionInfo()), EmptyRunfilesSupplier.INSTANCE, ImmutableList.<Artifact>copyOf(inputs), /*tools=*/
ImmutableList.<Artifact>of(), /*filesetManifests=*/
ImmutableList.<Artifact>of(), action.getOutputs().asList(), action.estimateResourceConsumptionLocal());
actionExecutionContext.getExecutor().getSpawnActionContext(action.getMnemonic()).exec(spawn, actionExecutionContext);
return null;
}
use of com.google.devtools.build.lib.actions.UserExecException in project bazel by bazelbuild.
the class SandboxStrategy method runSpawn.
protected void runSpawn(Spawn spawn, ActionExecutionContext actionExecutionContext, Map<String, String> spawnEnvironment, SandboxExecRoot sandboxExecRoot, Set<PathFragment> outputs, SandboxRunner runner, AtomicReference<Class<? extends SpawnActionContext>> writeOutputFiles) throws ExecException, InterruptedException {
EventHandler eventHandler = actionExecutionContext.getExecutor().getEventHandler();
ExecException execException = null;
OutErr outErr = actionExecutionContext.getFileOutErr();
try {
runner.run(spawn.getArguments(), spawnEnvironment, outErr, Spawns.getTimeoutSeconds(spawn), SandboxHelpers.shouldAllowNetwork(buildRequest, spawn), sandboxOptions.sandboxDebug, sandboxOptions.sandboxFakeHostname);
} catch (ExecException e) {
execException = e;
}
if (writeOutputFiles != null && !writeOutputFiles.compareAndSet(null, SandboxStrategy.class)) {
throw new InterruptedException();
}
try {
// We copy the outputs even when the command failed, otherwise StandaloneTestStrategy
// won't be able to get the test logs of a failed test. (We should probably do this in
// some better way.)
sandboxExecRoot.copyOutputs(execRoot, outputs);
} catch (IOException e) {
if (execException == null) {
throw new UserExecException("Could not move output artifacts from sandboxed execution", e);
} else {
// Catch the IOException and turn it into an error message, otherwise this might hide an
// exception thrown during runner.run earlier.
eventHandler.handle(Event.error("I/O exception while extracting output artifacts from sandboxed execution: " + e));
}
}
if (execException != null) {
outErr.printErr("Use --strategy=" + spawn.getMnemonic() + "=standalone to disable sandboxing for the failing actions.\n");
throw execException;
}
}
use of com.google.devtools.build.lib.actions.UserExecException in project bazel by bazelbuild.
the class LinuxSandboxedStrategy method actuallyExec.
public void actuallyExec(Spawn spawn, ActionExecutionContext actionExecutionContext, AtomicReference<Class<? extends SpawnActionContext>> writeOutputFiles) throws ExecException, InterruptedException {
Executor executor = actionExecutionContext.getExecutor();
SandboxHelpers.reportSubcommand(executor, spawn);
// Each invocation of "exec" gets its own sandbox.
Path sandboxPath = SandboxHelpers.getSandboxRoot(blazeDirs, productName, uuid, execCounter);
Path sandboxExecRoot = sandboxPath.getRelative("execroot").getRelative(execRoot.getBaseName());
Path sandboxTempDir = sandboxPath.getRelative("tmp");
Set<Path> writableDirs = getWritableDirs(sandboxExecRoot, spawn.getEnvironment());
SymlinkedExecRoot symlinkedExecRoot = new SymlinkedExecRoot(sandboxExecRoot);
ImmutableSet<PathFragment> outputs = SandboxHelpers.getOutputFiles(spawn);
try {
symlinkedExecRoot.createFileSystem(getMounts(spawn, actionExecutionContext), outputs, writableDirs);
sandboxTempDir.createDirectory();
} catch (IOException e) {
throw new UserExecException("I/O error during sandboxed execution", e);
}
SandboxRunner runner = getSandboxRunner(spawn, sandboxPath, sandboxExecRoot, sandboxTempDir);
try {
runSpawn(spawn, actionExecutionContext, spawn.getEnvironment(), symlinkedExecRoot, outputs, runner, writeOutputFiles);
} finally {
if (!sandboxOptions.sandboxDebug) {
try {
FileSystemUtils.deleteTree(sandboxPath);
} catch (IOException e) {
executor.getEventHandler().handle(Event.warn(String.format("Cannot delete sandbox directory after action execution: %s (%s)", sandboxPath.getPathString(), e)));
}
}
}
}
use of com.google.devtools.build.lib.actions.UserExecException in project bazel by bazelbuild.
the class LinuxSandboxedStrategy method validateBindMounts.
/**
* This method does the following things: - If mount source does not exist on the host system,
* throw an error message - If mount target exists, check whether the source and target are of the
* same type - If mount target does not exist on the host system, throw an error message
*
* @param bindMounts the bind mounts map with target as key and source as value
* @throws UserExecException
*/
private void validateBindMounts(SortedMap<Path, Path> bindMounts) throws UserExecException {
for (SortedMap.Entry<Path, Path> bindMount : bindMounts.entrySet()) {
final Path source = bindMount.getValue();
final Path target = bindMount.getKey();
// Mount source should exist in the file system
if (!source.exists()) {
throw new UserExecException(String.format("Mount source '%s' does not exist.", source));
}
// If target exists, but is not of the same type as the source, then we cannot mount it.
if (target.exists()) {
boolean areBothDirectories = source.isDirectory() && target.isDirectory();
boolean isSourceFile = source.isFile() || source.isSymbolicLink();
boolean isTargetFile = target.isFile() || target.isSymbolicLink();
boolean areBothFiles = isSourceFile && isTargetFile;
if (!(areBothDirectories || areBothFiles)) {
// Source and target are not of the same type; we cannot mount it.
throw new UserExecException(String.format("Mount target '%s' is not of the same type as mount source '%s'.", target, source));
}
} else {
// Mount target should exist in the file system
throw new UserExecException(String.format("Mount target '%s' does not exist. Bazel only supports bind mounting on top of " + "existing files/directories. Please create an empty file or directory at " + "the mount target path according to the type of mount source.", target));
}
}
}
Aggregations