Files
my-rook-config/e2e/framework/utils/exec_utils.go
T

210 lines
4.6 KiB
Go
Raw Normal View History

2017-04-28 08:02:37 -07:00
package utils
import (
"bufio"
"bytes"
"fmt"
"github.com/rook/rook/e2e/framework/objects"
"log"
"os/exec"
"strings"
"syscall"
)
func ExecuteCommand(cmdStruct objects.CommandArgs) objects.CommandOut {
var outBuffer, errBuffer bytes.Buffer
cmd := exec.Command(cmdStruct.Command, cmdStruct.CmdArgs...)
cmd.Env = append(cmd.Env, cmdStruct.EnvironmentVariable...)
stdOut, err := cmd.StdoutPipe()
if err != nil {
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: err}
}
stdin, err := cmd.StdinPipe()
if err != nil {
return objects.CommandOut{Err: err}
}
defer stdOut.Close()
scanner := bufio.NewScanner(stdOut)
go func() {
for scanner.Scan() {
outBuffer.WriteString(scanner.Text())
fmt.Printf("%s\n", scanner.Text())
}
}()
stdErr, err := cmd.StderrPipe()
if err != nil {
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: err}
}
defer stdErr.Close()
stdErrScanner := bufio.NewScanner(stdErr)
go func() {
for stdErrScanner.Scan() {
txt := stdErrScanner.Text()
if !strings.Contains(txt, "no buildable Go source files in") {
errBuffer.WriteString(txt)
fmt.Printf("%s\n", txt)
}
}
}()
err = cmd.Start()
if err != nil {
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: err}
}
if cmdStruct.PipeToStdIn != "" {
stdin.Write([]byte(cmdStruct.PipeToStdIn))
stdin.Close()
}
if err := cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
// The program has exited with an exit code != 0
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
log.Printf("Exit Status: %d", status.ExitStatus())
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: exiterr}
}
} else {
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: nil}
}
}
return objects.CommandOut{StdErr: errBuffer.String(), StdOut: outBuffer.String(), Err: err}
}
func ExecuteCmdWithEnv(Cmd string, cmdArgs []string, env []string) (stdout string, stderr string, exitCode int) {
var outbuf, errbuf bytes.Buffer
cmd := exec.Command(Cmd, strings.Join(cmdArgs, " "))
cmd.Env = append(cmd.Env, env...)
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
err := cmd.Run()
stdout = outbuf.String()
stderr = errbuf.String()
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
ws := exitError.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
} else {
exitCode = 1
if stderr == "" {
stderr = err.Error() + stdout
}
}
} else {
ws := cmd.ProcessState.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
}
return
}
func ExecuteCmd(Cmd string, cmdArgs []string) (stdout string, stderr string, exitCode int) {
var outbuf, errbuf bytes.Buffer
cmd := exec.Command(Cmd, cmdArgs...)
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
err := cmd.Run()
stdout = outbuf.String()
stderr = errbuf.String()
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
ws := exitError.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
} else {
exitCode = 1
if stderr == "" {
stderr = err.Error() + stdout
}
}
} else {
ws := cmd.ProcessState.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
}
return
}
//TODO add timeout parameter
func ExecuteCmdAndLogToConsole(command string, cmdArgs []string, cmdEnv []string) (stdout string, stderr string, err error) {
var outbuf, errbuf bytes.Buffer
cmd := exec.Command(command, cmdArgs...)
cmd.Env = append(cmd.Env, cmdEnv...)
stdOut, err := cmd.StdoutPipe()
if err != nil {
return errbuf.String(), outbuf.String(), err
}
defer stdOut.Close()
scanner := bufio.NewScanner(stdOut)
go func() {
for scanner.Scan() {
outbuf.WriteString(scanner.Text())
fmt.Printf("%s\n", scanner.Text())
}
}()
stdErr, err := cmd.StderrPipe()
if err != nil {
return errbuf.String(), outbuf.String(), err
}
defer stdErr.Close()
stdErrScanner := bufio.NewScanner(stdErr)
go func() {
for stdErrScanner.Scan() {
txt := stdErrScanner.Text()
errbuf.WriteString(txt)
fmt.Printf("%s\n", txt)
}
}()
err = cmd.Start()
if err != nil {
return errbuf.String(), outbuf.String(), err
}
if err := cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
// The program has exited with an exit code != 0
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
log.Printf("Exit Status: %d", status.ExitStatus())
return errbuf.String(), outbuf.String(), exiterr
}
} else {
return errbuf.String(), outbuf.String(), nil
}
}
return errbuf.String(), outbuf.String(), err
}