mirror of
https://github.com/vee1e/kubeedge.git
synced 2026-09-01 18:27:38 +00:00
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package execs
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// Command defines commands to be executed and captures std out and std error
|
|
type Command struct {
|
|
Cmd *exec.Cmd
|
|
StdOut []byte
|
|
StdErr []byte
|
|
ExitCode int
|
|
}
|
|
|
|
// Exec run command and exit formatted error, callers can print err directly
|
|
// Any running error or non-zero exitcode is consider as error
|
|
func (cmd *Command) Exec() error {
|
|
var stdoutBuf, stderrBuf bytes.Buffer
|
|
cmd.Cmd.Stdout = &stdoutBuf
|
|
cmd.Cmd.Stderr = &stderrBuf
|
|
|
|
errString := fmt.Sprintf("failed to exec [%s]", cmd.GetCommand())
|
|
|
|
if err := cmd.Cmd.Start(); err != nil {
|
|
errString = fmt.Sprintf("%s, err: %v", errString, err)
|
|
return errors.New(errString)
|
|
}
|
|
|
|
if err := cmd.Cmd.Wait(); err != nil {
|
|
cmd.StdOut, cmd.StdErr = stdoutBuf.Bytes(), stderrBuf.Bytes()
|
|
errString = cmd.handleWaitError(err, errString)
|
|
return errors.New(errString)
|
|
}
|
|
|
|
cmd.StdOut, cmd.StdErr = stdoutBuf.Bytes(), stderrBuf.Bytes()
|
|
return nil
|
|
}
|
|
|
|
// handleWaitError processes the error returned by cmd.Cmd.Wait() and returns
|
|
// a formatted error string. Extracted to allow direct unit testing of both
|
|
// the *exec.ExitError path and the generic error path.
|
|
func (cmd *Command) handleWaitError(err error, errString string) string {
|
|
if exit, ok := err.(*exec.ExitError); ok {
|
|
message := string(cmd.StdErr)
|
|
if message == "" {
|
|
message = string(cmd.StdOut)
|
|
}
|
|
cmd.ExitCode = exit.ExitCode()
|
|
return fmt.Sprintf("%s, err: %s", errString, message)
|
|
}
|
|
cmd.ExitCode = 1
|
|
return fmt.Sprintf("%s, err: %v", errString, err)
|
|
}
|
|
|
|
func (cmd Command) GetCommand() string {
|
|
return strings.Join(cmd.Cmd.Args, " ")
|
|
}
|