Search in sources :

Example 6 with OutErr

use of com.google.devtools.build.lib.util.io.OutErr in project bazel by bazelbuild.

the class SkyframeActionExecutor method dumpRecordedOutErr.

/**
   * Dump the output from the action.
   *
   * @param prefixEvent An event to post before dumping the output
   * @param outErrBuffer The OutErr that recorded the actions output
   */
private void dumpRecordedOutErr(Event prefixEvent, FileOutErr outErrBuffer) {
    // actions will not be interleaved.
    synchronized (reporter) {
        // Only print the output if we're not winding down.
        if (isBuilderAborting()) {
            return;
        }
        reporter.handle(prefixEvent);
        if (outErrBuffer != null && outErrBuffer.hasRecordedOutput()) {
            OutErr outErr = this.reporter.getOutErr();
            outErrBuffer.dumpOutAsLatin1(outErr.getOutputStream());
            outErrBuffer.dumpErrAsLatin1(outErr.getErrorStream());
        }
    }
}
Also used : FileOutErr(com.google.devtools.build.lib.util.io.FileOutErr) OutErr(com.google.devtools.build.lib.util.io.OutErr)

Example 7 with OutErr

use of com.google.devtools.build.lib.util.io.OutErr in project bazel by bazelbuild.

the class BlazeCommandDispatcher method execExclusively.

private int execExclusively(List<String> args, OutErr outErr, long firstContactTime, String commandName, BlazeCommand command, long waitTimeInMs) throws ShutdownBlazeServerException {
    Command commandAnnotation = command.getClass().getAnnotation(Command.class);
    // Record the start time for the profiler. Do not put anything before this!
    long execStartTimeNanos = runtime.getClock().nanoTime();
    // The initCommand call also records the start time for the timestamp granularity monitor.
    CommandEnvironment env = runtime.getWorkspace().initCommand();
    // Record the command's starting time for use by the commands themselves.
    env.recordCommandStartTime(firstContactTime);
    AbruptExitException exitCausingException = null;
    for (BlazeModule module : runtime.getBlazeModules()) {
        try {
            module.beforeCommand(commandAnnotation, env);
        } catch (AbruptExitException e) {
            // Don't let one module's complaints prevent the other modules from doing necessary
            // setup. We promised to call beforeCommand exactly once per-module before each command
            // and will be calling afterCommand soon in the future - a module's afterCommand might
            // rightfully assume its beforeCommand has already been called.
            outErr.printErrLn(e.getMessage());
            // It's not ideal but we can only return one exit code, so we just pick the code of the
            // last exception.
            exitCausingException = e;
        }
    }
    if (exitCausingException != null) {
        return exitCausingException.getExitCode().getNumericExitCode();
    }
    try {
        Path commandLog = getCommandLogPath(env.getOutputBase());
        // Unlink old command log from previous build, if present, so scripts
        // reading it don't conflate it with the command log we're about to write.
        closeSilently(logOutputStream);
        logOutputStream = null;
        commandLog.delete();
        if (env.getRuntime().writeCommandLog() && commandAnnotation.writeCommandLog()) {
            logOutputStream = commandLog.getOutputStream();
            outErr = tee(outErr, OutErr.create(logOutputStream, logOutputStream));
        }
    } catch (IOException ioException) {
        LoggingUtil.logToRemote(Level.WARNING, "Unable to delete or open command.log", ioException);
    }
    ExitCode result = checkCwdInWorkspace(env, commandAnnotation, commandName, outErr);
    if (!result.equals(ExitCode.SUCCESS)) {
        return result.getNumericExitCode();
    }
    OptionsParser optionsParser;
    // Delay output of notes regarding the parsed rc file, so it's possible to disable this in the
    // rc file.
    List<String> rcfileNotes = new ArrayList<>();
    try {
        optionsParser = createOptionsParser(command);
        parseArgsAndConfigs(env, optionsParser, commandAnnotation, args, rcfileNotes, outErr);
        InvocationPolicyEnforcer optionsPolicyEnforcer = new InvocationPolicyEnforcer(runtime.getInvocationPolicy());
        optionsPolicyEnforcer.enforce(optionsParser, commandName);
        optionsPolicyEnforcer = InvocationPolicyEnforcer.create(getRuntime().getStartupOptionsProvider().getOptions(BlazeServerStartupOptions.class).invocationPolicy);
        optionsPolicyEnforcer.enforce(optionsParser, commandName);
    } catch (OptionsParsingException e) {
        for (String note : rcfileNotes) {
            outErr.printErrLn("INFO: " + note);
        }
        outErr.printErrLn(e.getMessage());
        return ExitCode.COMMAND_LINE_ERROR.getNumericExitCode();
    }
    // Setup log filtering
    BlazeCommandEventHandler.Options eventHandlerOptions = optionsParser.getOptions(BlazeCommandEventHandler.Options.class);
    OutErr colorfulOutErr = outErr;
    if (!eventHandlerOptions.useColor()) {
        outErr = ansiStripOut(ansiStripErr(outErr));
        if (!commandAnnotation.binaryStdOut()) {
            colorfulOutErr = ansiStripOut(colorfulOutErr);
        }
        if (!commandAnnotation.binaryStdErr()) {
            colorfulOutErr = ansiStripErr(colorfulOutErr);
        }
    }
    if (!commandAnnotation.binaryStdOut()) {
        outErr = lineBufferOut(outErr);
    }
    if (!commandAnnotation.binaryStdErr()) {
        outErr = lineBufferErr(outErr);
    }
    CommonCommandOptions commonOptions = optionsParser.getOptions(CommonCommandOptions.class);
    if (!commonOptions.verbosity.equals(lastLogVerbosityLevel)) {
        BlazeRuntime.setupLogging(commonOptions.verbosity);
        lastLogVerbosityLevel = commonOptions.verbosity;
    }
    // Do this before an actual crash so we don't have to worry about
    // allocating memory post-crash.
    String[] crashData = env.getCrashData();
    int numericExitCode = ExitCode.BLAZE_INTERNAL_ERROR.getNumericExitCode();
    PrintStream savedOut = System.out;
    PrintStream savedErr = System.err;
    EventHandler handler = createEventHandler(outErr, eventHandlerOptions);
    Reporter reporter = env.getReporter();
    reporter.addHandler(handler);
    env.getEventBus().register(handler);
    // We register an ANSI-allowing handler associated with {@code handler} so that ANSI control
    // codes can be re-introduced later even if blaze is invoked with --color=no. This is useful
    // for commands such as 'blaze run' where the output of the final executable shouldn't be
    // modified.
    EventHandler ansiAllowingHandler = null;
    if (!eventHandlerOptions.useColor()) {
        ansiAllowingHandler = createEventHandler(colorfulOutErr, eventHandlerOptions);
        reporter.registerAnsiAllowingHandler(handler, ansiAllowingHandler);
        if (ansiAllowingHandler instanceof ExperimentalEventHandler) {
            env.getEventBus().register(new PassiveExperimentalEventHandler((ExperimentalEventHandler) ansiAllowingHandler));
        }
    }
    try {
        // While a Blaze command is active, direct all errors to the client's
        // event handler (and out/err streams).
        OutErr reporterOutErr = reporter.getOutErr();
        System.setOut(new PrintStream(reporterOutErr.getOutputStream(), /*autoflush=*/
        true));
        System.setErr(new PrintStream(reporterOutErr.getErrorStream(), /*autoflush=*/
        true));
        for (BlazeModule module : runtime.getBlazeModules()) {
            module.checkEnvironment(env);
        }
        if (commonOptions.announceRcOptions) {
            for (String note : rcfileNotes) {
                reporter.handle(Event.info(note));
            }
        }
        try {
            // Notify the BlazeRuntime, so it can do some initial setup.
            env.beforeCommand(commandAnnotation, optionsParser, commonOptions, execStartTimeNanos, waitTimeInMs);
            // Allow the command to edit options after parsing:
            command.editOptions(env, optionsParser);
        } catch (AbruptExitException e) {
            reporter.handle(Event.error(e.getMessage()));
            return e.getExitCode().getNumericExitCode();
        }
        for (BlazeModule module : runtime.getBlazeModules()) {
            module.handleOptions(optionsParser);
        }
        // Print warnings for odd options usage
        for (String warning : optionsParser.getWarnings()) {
            reporter.handle(Event.warn(warning));
        }
        ExitCode outcome = command.exec(env, optionsParser);
        outcome = env.precompleteCommand(outcome);
        numericExitCode = outcome.getNumericExitCode();
        return numericExitCode;
    } catch (ShutdownBlazeServerException e) {
        numericExitCode = e.getExitStatus();
        throw e;
    } catch (Throwable e) {
        e.printStackTrace();
        BugReport.printBug(outErr, e);
        BugReport.sendBugReport(e, args, crashData);
        numericExitCode = BugReport.getExitCodeForThrowable(e);
        throw new ShutdownBlazeServerException(numericExitCode, e);
    } finally {
        env.getEventBus().post(new AfterCommandEvent());
        runtime.afterCommand(env, numericExitCode);
        // Swallow IOException, as we are already in a finally clause
        Flushables.flushQuietly(outErr.getOutputStream());
        Flushables.flushQuietly(outErr.getErrorStream());
        System.setOut(savedOut);
        System.setErr(savedErr);
        reporter.removeHandler(handler);
        releaseHandler(handler);
        if (!eventHandlerOptions.useColor()) {
            reporter.removeHandler(ansiAllowingHandler);
            releaseHandler(ansiAllowingHandler);
        }
        env.getTimestampGranularityMonitor().waitForTimestampGranularity(outErr);
    }
}
Also used : ExitCode(com.google.devtools.build.lib.util.ExitCode) ArrayList(java.util.ArrayList) EventHandler(com.google.devtools.build.lib.events.EventHandler) Path(com.google.devtools.build.lib.vfs.Path) PrintStream(java.io.PrintStream) DelegatingOutErr(com.google.devtools.build.lib.util.io.DelegatingOutErr) OutErr(com.google.devtools.build.lib.util.io.OutErr) Reporter(com.google.devtools.build.lib.events.Reporter) IOException(java.io.IOException) OptionsParser(com.google.devtools.common.options.OptionsParser) InvocationPolicyEnforcer(com.google.devtools.build.lib.flags.InvocationPolicyEnforcer) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException) AbruptExitException(com.google.devtools.build.lib.util.AbruptExitException)

Example 8 with OutErr

use of com.google.devtools.build.lib.util.io.OutErr in project bazel by bazelbuild.

the class InfoCommand method exec.

@Override
public ExitCode exec(final CommandEnvironment env, final OptionsProvider optionsProvider) {
    final BlazeRuntime runtime = env.getRuntime();
    env.getReporter().switchToAnsiAllowingHandler();
    Options infoOptions = optionsProvider.getOptions(Options.class);
    OutErr outErr = env.getReporter().getOutErr();
    // Creating a BuildConfiguration is expensive and often unnecessary. Delay the creation until
    // it is needed.
    Supplier<BuildConfiguration> configurationSupplier = new Supplier<BuildConfiguration>() {

        private BuildConfiguration configuration;

        @Override
        public BuildConfiguration get() {
            if (configuration != null) {
                return configuration;
            }
            try {
                // In order to be able to answer configuration-specific queries, we need to setup the
                // package path. Since info inherits all the build options, all the necessary information
                // is available here.
                env.setupPackageCache(optionsProvider, runtime.getDefaultsPackageContent(optionsProvider));
                // TODO(bazel-team): What if there are multiple configurations? [multi-config]
                configuration = env.getConfigurations(optionsProvider).getTargetConfigurations().get(0);
                return configuration;
            } catch (InvalidConfigurationException e) {
                env.getReporter().handle(Event.error(e.getMessage()));
                throw new ExitCausingRuntimeException(ExitCode.COMMAND_LINE_ERROR);
            } catch (AbruptExitException e) {
                throw new ExitCausingRuntimeException("unknown error: " + e.getMessage(), e.getExitCode());
            } catch (InterruptedException e) {
                env.getReporter().handle(Event.error("interrupted"));
                throw new ExitCausingRuntimeException(ExitCode.INTERRUPTED);
            }
        }
    };
    Map<String, InfoItem> items = getInfoItemMap(env, optionsProvider);
    try {
        if (infoOptions.showMakeEnvironment) {
            Map<String, String> makeEnv = configurationSupplier.get().getMakeEnvironment();
            for (Map.Entry<String, String> entry : makeEnv.entrySet()) {
                InfoItem item = new InfoItem.MakeInfoItem(entry.getKey(), entry.getValue());
                items.put(item.getName(), item);
            }
        }
        List<String> residue = optionsProvider.getResidue();
        if (residue.size() > 1) {
            env.getReporter().handle(Event.error("at most one key may be specified"));
            return ExitCode.COMMAND_LINE_ERROR;
        }
        String key = residue.size() == 1 ? residue.get(0) : null;
        env.getEventBus().post(new NoBuildEvent());
        if (key != null) {
            // print just the value for the specified key:
            byte[] value;
            if (items.containsKey(key)) {
                value = items.get(key).get(configurationSupplier, env);
            } else {
                env.getReporter().handle(Event.error("unknown key: '" + key + "'"));
                return ExitCode.COMMAND_LINE_ERROR;
            }
            try {
                outErr.getOutputStream().write(value);
                outErr.getOutputStream().flush();
            } catch (IOException e) {
                env.getReporter().handle(Event.error("Cannot write info block: " + e.getMessage()));
                return ExitCode.ANALYSIS_FAILURE;
            }
        } else {
            // print them all
            // We'll need this later anyway
            configurationSupplier.get();
            for (InfoItem infoItem : items.values()) {
                if (infoItem.isHidden()) {
                    continue;
                }
                outErr.getOutputStream().write((infoItem.getName() + ": ").getBytes(StandardCharsets.UTF_8));
                outErr.getOutputStream().write(infoItem.get(configurationSupplier, env));
            }
        }
    } catch (AbruptExitException e) {
        return e.getExitCode();
    } catch (ExitCausingRuntimeException e) {
        return e.getExitCode();
    } catch (IOException e) {
        return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
    } catch (InterruptedException e) {
        return ExitCode.INTERRUPTED;
    }
    return ExitCode.SUCCESS;
}
Also used : OutErr(com.google.devtools.build.lib.util.io.OutErr) NoBuildEvent(com.google.devtools.build.lib.analysis.NoBuildEvent) IOException(java.io.IOException) BlazeRuntime(com.google.devtools.build.lib.runtime.BlazeRuntime) InvalidConfigurationException(com.google.devtools.build.lib.analysis.config.InvalidConfigurationException) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) Supplier(com.google.common.base.Supplier) AbruptExitException(com.google.devtools.build.lib.util.AbruptExitException) ImmutableMap(com.google.common.collect.ImmutableMap) TreeMap(java.util.TreeMap) Map(java.util.Map)

Example 9 with OutErr

use of com.google.devtools.build.lib.util.io.OutErr 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;
    }
}
Also used : OutErr(com.google.devtools.build.lib.util.io.OutErr) EnvironmentalExecException(com.google.devtools.build.lib.actions.EnvironmentalExecException) UserExecException(com.google.devtools.build.lib.actions.UserExecException) ExecException(com.google.devtools.build.lib.actions.ExecException) UserExecException(com.google.devtools.build.lib.actions.UserExecException) EventHandler(com.google.devtools.build.lib.events.EventHandler) IOException(java.io.IOException)

Example 10 with OutErr

use of com.google.devtools.build.lib.util.io.OutErr in project bazel by bazelbuild.

the class GrpcServerImpl method executeCommand.

private void executeCommand(RunRequest request, StreamObserver<RunResponse> observer, GrpcSink sink) {
    sink.setCommandThread(Thread.currentThread());
    if (!request.getCookie().equals(requestCookie) || request.getClientDescription().isEmpty()) {
        try {
            observer.onNext(RunResponse.newBuilder().setExitCode(ExitCode.LOCAL_ENVIRONMENTAL_ERROR.getNumericExitCode()).build());
            observer.onCompleted();
        } catch (StatusRuntimeException e) {
            log.info("Client cancelled command while rejecting it: " + e.getMessage());
        }
        return;
    }
    // case by explicitly checking for disconnection here.
    if (sink.disconnected()) {
        return;
    }
    ImmutableList.Builder<String> args = ImmutableList.builder();
    for (ByteString requestArg : request.getArgList()) {
        args.add(requestArg.toString(CHARSET));
    }
    String commandId;
    int exitCode;
    try (RunningCommand command = new RunningCommand()) {
        commandId = command.id;
        try {
            // Send the client the command id as soon as we know it.
            observer.onNext(RunResponse.newBuilder().setCookie(responseCookie).setCommandId(commandId).build());
        } catch (StatusRuntimeException e) {
            log.info("The client cancelled the command before receiving the command id: " + e.getMessage());
        }
        OutErr rpcOutErr = OutErr.create(new RpcOutputStream(command.id, responseCookie, StreamType.STDOUT, sink), new RpcOutputStream(command.id, responseCookie, StreamType.STDERR, sink));
        exitCode = commandExecutor.exec(args.build(), rpcOutErr, request.getBlockForLock() ? LockingMode.WAIT : LockingMode.ERROR_OUT, request.getClientDescription(), clock.currentTimeMillis());
    } catch (InterruptedException e) {
        exitCode = ExitCode.INTERRUPTED.getNumericExitCode();
        // The default value, the client will ignore it
        commandId = "";
    }
    if (sink.finish()) {
        // Client disconnected. Then we are not allowed to call any methods on the observer.
        log.info(String.format("Client disconnected before we could send exit code for command %s", commandId));
        return;
    }
    // There is a chance that an Uninterruptibles#getUninterruptibly() leaves us with the
    // interrupt bit set. So we just reset the interruption state here to make these cancel
    // requests not have any effect outside of command execution (after the try block above,
    // the cancel request won't find the thread to interrupt)
    Thread.interrupted();
    RunResponse response = RunResponse.newBuilder().setCookie(responseCookie).setCommandId(commandId).setFinished(true).setExitCode(exitCode).build();
    try {
        observer.onNext(response);
        observer.onCompleted();
    } catch (StatusRuntimeException e) {
        // The client cancelled the call. Log an error and go on.
        log.info(String.format("Client cancelled command %s just right before its end: %s", commandId, e.getMessage()));
    }
    if (commandExecutor.shutdown()) {
        pidFileWatcherThread.signalShutdown();
        server.shutdown();
    }
}
Also used : OutErr(com.google.devtools.build.lib.util.io.OutErr) ImmutableList(com.google.common.collect.ImmutableList) ByteString(com.google.protobuf.ByteString) RunResponse(com.google.devtools.build.lib.server.CommandProtos.RunResponse) StatusRuntimeException(io.grpc.StatusRuntimeException) ByteString(com.google.protobuf.ByteString)

Aggregations

OutErr (com.google.devtools.build.lib.util.io.OutErr)10 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 Artifact (com.google.devtools.build.lib.actions.Artifact)2 InputFileConfiguredTarget (com.google.devtools.build.lib.analysis.InputFileConfiguredTarget)2 NoBuildEvent (com.google.devtools.build.lib.analysis.NoBuildEvent)2 OutputFileConfiguredTarget (com.google.devtools.build.lib.analysis.OutputFileConfiguredTarget)2 TopLevelArtifactContext (com.google.devtools.build.lib.analysis.TopLevelArtifactContext)2 BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)2 EventHandler (com.google.devtools.build.lib.events.EventHandler)2 BlazeRuntime (com.google.devtools.build.lib.runtime.BlazeRuntime)2 AspectValue (com.google.devtools.build.lib.skyframe.AspectValue)2 AbruptExitException (com.google.devtools.build.lib.util.AbruptExitException)2 ExitCode (com.google.devtools.build.lib.util.ExitCode)2 Path (com.google.devtools.build.lib.vfs.Path)2 Supplier (com.google.common.base.Supplier)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 EnvironmentalExecException (com.google.devtools.build.lib.actions.EnvironmentalExecException)1