in integration_test/gce-testing-internal/gce/gce_testing.go [708:745]
func runCommand(ctx context.Context, logger *log.Logger, stdin io.Reader, args []string, env map[string]string) (CommandOutput, error) {
var output CommandOutput
if len(args) < 1 {
return output, fmt.Errorf("runCommand() needs a nonempty argument slice, got %v", args)
}
cmd := exec.CommandContext(ctx, args[0], args[1:]...)
cmd.Stdin = stdin
var stdoutBuilder strings.Builder
var stderrBuilder strings.Builder
var interleavedBuilder strings.Builder
interleavedWriter := &ThreadSafeWriter{guarded: &interleavedBuilder}
cmd.Stdout = io.MultiWriter(&stdoutBuilder, interleavedWriter)
cmd.Stderr = io.MultiWriter(&stderrBuilder, interleavedWriter)
if len(env) > 0 {
environment := []string{}
for k, v := range env {
environment = append(environment, fmt.Sprintf("%s=%s", k, v))
}
cmd.Env = environment
}
err := cmd.Run()
if err != nil {
err = fmt.Errorf("Command failed: %v\n%v\nstdout+stderr: %s", args, err, interleavedBuilder.String())
}
logger.Printf("exit code: %v", cmd.ProcessState.ExitCode())
logger.Printf("stdout+stderr: %s", interleavedBuilder.String())
output.Stdout = stdoutBuilder.String()
output.Stderr = stderrBuilder.String()
return output, err
}