mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-30 05:18:47 +02:00
91 lines
2.4 KiB
Go
91 lines
2.4 KiB
Go
package exec
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
|
|
"github.com/argoproj/gitops-engine/pkg/utils/tracing"
|
|
argoexec "github.com/argoproj/pkg/exec"
|
|
|
|
"github.com/argoproj/argo-cd/v2/util/log"
|
|
)
|
|
|
|
var timeout time.Duration
|
|
|
|
type ExecRunOpts struct {
|
|
// Redactor redacts tokens from the output
|
|
Redactor func(text string) string
|
|
// TimeoutBehavior configures what to do in case of timeout
|
|
TimeoutBehavior argoexec.TimeoutBehavior
|
|
// SkipErrorLogging determines whether to skip logging of execution errors (rc > 0)
|
|
SkipErrorLogging bool
|
|
// CaptureStderr determines whether to capture stderr in addition to stdout
|
|
CaptureStderr bool
|
|
}
|
|
|
|
func init() {
|
|
initTimeout()
|
|
}
|
|
|
|
func initTimeout() {
|
|
var err error
|
|
timeout, err = time.ParseDuration(os.Getenv("ARGOCD_EXEC_TIMEOUT"))
|
|
if err != nil {
|
|
timeout = 90 * time.Second
|
|
}
|
|
}
|
|
|
|
func Run(cmd *exec.Cmd) (string, error) {
|
|
return RunWithRedactor(cmd, nil)
|
|
}
|
|
|
|
func RunWithRedactor(cmd *exec.Cmd, redactor func(text string) string) (string, error) {
|
|
opts := ExecRunOpts{Redactor: redactor}
|
|
return RunWithExecRunOpts(cmd, opts)
|
|
}
|
|
|
|
func RunWithExecRunOpts(cmd *exec.Cmd, opts ExecRunOpts) (string, error) {
|
|
cmdOpts := argoexec.CmdOpts{Timeout: timeout, Redactor: opts.Redactor, TimeoutBehavior: opts.TimeoutBehavior, SkipErrorLogging: opts.SkipErrorLogging}
|
|
span := tracing.NewLoggingTracer(log.NewLogrusLogger(log.NewWithCurrentConfig())).StartSpan(fmt.Sprintf("exec %v", cmd.Args[0]))
|
|
span.SetBaggageItem("dir", fmt.Sprintf("%v", cmd.Dir))
|
|
if cmdOpts.Redactor != nil {
|
|
span.SetBaggageItem("args", opts.Redactor(fmt.Sprintf("%v", cmd.Args)))
|
|
} else {
|
|
span.SetBaggageItem("args", fmt.Sprintf("%v", cmd.Args))
|
|
}
|
|
defer span.Finish()
|
|
return argoexec.RunCommandExt(cmd, cmdOpts)
|
|
}
|
|
|
|
// GetCommandArgsToLog represents the given command in a way that we can copy-and-paste into a terminal
|
|
func GetCommandArgsToLog(cmd *exec.Cmd) string {
|
|
var argsToLog []string
|
|
for _, arg := range cmd.Args {
|
|
if arg == "" {
|
|
argsToLog = append(argsToLog, `""`)
|
|
continue
|
|
}
|
|
|
|
containsSpace := false
|
|
for _, r := range arg {
|
|
if unicode.IsSpace(r) {
|
|
containsSpace = true
|
|
break
|
|
}
|
|
}
|
|
if containsSpace {
|
|
// add quotes and escape any internal quotes
|
|
argsToLog = append(argsToLog, strconv.Quote(arg))
|
|
} else {
|
|
argsToLog = append(argsToLog, arg)
|
|
}
|
|
}
|
|
args := strings.Join(argsToLog, " ")
|
|
return args
|
|
}
|