mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-19 04:26:34 +00:00
Upgrade to go-execute/v2
Upgrades to go-execute/v2 and updates various other dependencies. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
This commit is contained in:
193
vendor/github.com/alexellis/go-execute/v2/exec.go
generated
vendored
Normal file
193
vendor/github.com/alexellis/go-execute/v2/exec.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
package execute
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ExecTask struct {
|
||||
// Command is the command to execute. This can be the path to an executable
|
||||
// or the executable with arguments. The arguments are detected by looking for
|
||||
// a space.
|
||||
//
|
||||
// Any arguments must be given via Args
|
||||
Command string
|
||||
|
||||
// Args are the arguments to pass to the command. These are ignored if the
|
||||
// Command contains arguments.
|
||||
Args []string
|
||||
|
||||
// Shell run the command in a bash shell.
|
||||
// Note that the system must have `bash` installed in the PATH or in /bin/bash
|
||||
Shell bool
|
||||
|
||||
// Env is a list of environment variables to add to the current environment,
|
||||
// these are used to override any existing environment variables.
|
||||
Env []string
|
||||
|
||||
// Cwd is the working directory for the command
|
||||
Cwd string
|
||||
|
||||
// Stdin connect a reader to stdin for the command
|
||||
// being executed.
|
||||
Stdin io.Reader
|
||||
|
||||
// PrintCommand prints the command before executing
|
||||
PrintCommand bool
|
||||
|
||||
// StreamStdio prints stdout and stderr directly to os.Stdout/err as
|
||||
// the command runs.
|
||||
StreamStdio bool
|
||||
|
||||
// DisableStdioBuffer prevents any output from being saved in the
|
||||
// TaskResult, which is useful for when the result is very large, or
|
||||
// when you want to stream the output to another writer exclusively.
|
||||
DisableStdioBuffer bool
|
||||
|
||||
// StdoutWriter when set will receive a copy of stdout from the command
|
||||
StdOutWriter io.Writer
|
||||
|
||||
// StderrWriter when set will receive a copy of stderr from the command
|
||||
StdErrWriter io.Writer
|
||||
}
|
||||
|
||||
type ExecResult struct {
|
||||
Stdout string
|
||||
Stderr string
|
||||
ExitCode int
|
||||
Cancelled bool
|
||||
}
|
||||
|
||||
func (et ExecTask) Execute(ctx context.Context) (ExecResult, error) {
|
||||
argsSt := ""
|
||||
if len(et.Args) > 0 {
|
||||
argsSt = strings.Join(et.Args, " ")
|
||||
}
|
||||
|
||||
if et.PrintCommand {
|
||||
fmt.Println("exec: ", et.Command, argsSt)
|
||||
}
|
||||
|
||||
// don't try to run if the context is already cancelled
|
||||
if ctx.Err() != nil {
|
||||
return ExecResult{
|
||||
// the exec package returns -1 for cancelled commands
|
||||
ExitCode: -1,
|
||||
Cancelled: ctx.Err() == context.Canceled,
|
||||
}, ctx.Err()
|
||||
}
|
||||
|
||||
var command string
|
||||
var commandArgs []string
|
||||
if et.Shell {
|
||||
|
||||
// On a NixOS system, /bin/bash doesn't exist at /bin/bash
|
||||
// the default behavior of exec.Command is to look for the
|
||||
// executable in PATH.
|
||||
|
||||
command = "bash"
|
||||
// There is a chance that PATH is not populate or propagated, therefore
|
||||
// when bash cannot be resolved, set it to /bin/bash instead.
|
||||
if _, err := exec.LookPath(command); err != nil {
|
||||
command = "/bin/bash"
|
||||
}
|
||||
|
||||
if len(et.Args) == 0 {
|
||||
// use Split and Join to remove any extra whitespace?
|
||||
startArgs := strings.Split(et.Command, " ")
|
||||
script := strings.Join(startArgs, " ")
|
||||
commandArgs = append([]string{"-c"}, script)
|
||||
|
||||
} else {
|
||||
script := strings.Join(et.Args, " ")
|
||||
commandArgs = append([]string{"-c"}, fmt.Sprintf("%s %s", et.Command, script))
|
||||
}
|
||||
} else {
|
||||
|
||||
command = et.Command
|
||||
commandArgs = et.Args
|
||||
|
||||
// AE: This had to be removed to fix: #117 where Windows users
|
||||
// have spaces in their paths, which are misinterpreted as
|
||||
// arguments for the command.
|
||||
// if strings.Contains(et.Command, " ") {
|
||||
// parts := strings.Split(et.Command, " ")
|
||||
// command = parts[0]
|
||||
// commandArgs = parts[1:]
|
||||
// }
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, command, commandArgs...)
|
||||
cmd.Dir = et.Cwd
|
||||
|
||||
if len(et.Env) > 0 {
|
||||
overrides := map[string]bool{}
|
||||
for _, env := range et.Env {
|
||||
key := strings.Split(env, "=")[0]
|
||||
overrides[key] = true
|
||||
cmd.Env = append(cmd.Env, env)
|
||||
}
|
||||
|
||||
for _, env := range os.Environ() {
|
||||
key := strings.Split(env, "=")[0]
|
||||
|
||||
if _, ok := overrides[key]; !ok {
|
||||
cmd.Env = append(cmd.Env, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
if et.Stdin != nil {
|
||||
cmd.Stdin = et.Stdin
|
||||
}
|
||||
|
||||
stdoutBuff := bytes.Buffer{}
|
||||
stderrBuff := bytes.Buffer{}
|
||||
|
||||
var stdoutWriters []io.Writer
|
||||
var stderrWriters []io.Writer
|
||||
|
||||
if !et.DisableStdioBuffer {
|
||||
stdoutWriters = append(stdoutWriters, &stdoutBuff)
|
||||
stderrWriters = append(stderrWriters, &stderrBuff)
|
||||
}
|
||||
|
||||
if et.StreamStdio {
|
||||
stdoutWriters = append(stdoutWriters, os.Stdout)
|
||||
stderrWriters = append(stderrWriters, os.Stderr)
|
||||
}
|
||||
|
||||
if et.StdOutWriter != nil {
|
||||
stdoutWriters = append(stdoutWriters, et.StdOutWriter)
|
||||
}
|
||||
if et.StdErrWriter != nil {
|
||||
stderrWriters = append(stderrWriters, et.StdErrWriter)
|
||||
}
|
||||
|
||||
cmd.Stdout = io.MultiWriter(stdoutWriters...)
|
||||
cmd.Stderr = io.MultiWriter(stderrWriters...)
|
||||
|
||||
startErr := cmd.Start()
|
||||
if startErr != nil {
|
||||
return ExecResult{}, startErr
|
||||
}
|
||||
|
||||
exitCode := 0
|
||||
execErr := cmd.Wait()
|
||||
if execErr != nil {
|
||||
if exitError, ok := execErr.(*exec.ExitError); ok {
|
||||
exitCode = exitError.ExitCode()
|
||||
}
|
||||
}
|
||||
|
||||
return ExecResult{
|
||||
Stdout: stdoutBuff.String(),
|
||||
Stderr: stderrBuff.String(),
|
||||
ExitCode: exitCode,
|
||||
Cancelled: ctx.Err() == context.Canceled,
|
||||
}, ctx.Err()
|
||||
}
|
Reference in New Issue
Block a user