Files
my-rook-config/pkg/util/exec/exec.go
T

100 lines
2.6 KiB
Go
Raw Normal View History

package exec
2016-09-15 08:00:43 -07:00
import (
"bufio"
"io"
"log"
"os/exec"
"strings"
)
type Executor interface {
StartExecuteCommand(actionName string, command string, arg ...string) (*exec.Cmd, error)
2016-09-15 08:00:43 -07:00
ExecuteCommand(actionName string, command string, arg ...string) error
ExecuteCommandPipeline(actionName string, command string) (string, error)
ExecuteCommandWithOutput(actionName string, command string, arg ...string) (string, error)
}
type CommandExecutor struct {
}
// Start a process and return immediately
func (*CommandExecutor) StartExecuteCommand(actionName string, command string, arg ...string) (*exec.Cmd, error) {
cmd, stdout, stderr, err := startCommand(command, arg...)
if err != nil {
return cmd, createCommandError(err, actionName)
}
go logOutput(stdout, stderr)
return cmd, nil
}
// Start a process and wait for its completion
2016-09-15 08:00:43 -07:00
func (*CommandExecutor) ExecuteCommand(actionName string, command string, arg ...string) error {
cmd, stdout, stderr, err := startCommand(command, arg...)
if err != nil {
return createCommandError(err, actionName)
2016-09-15 08:00:43 -07:00
}
logOutput(stdout, stderr)
2016-09-15 08:00:43 -07:00
if err := cmd.Wait(); err != nil {
return createCommandError(err, actionName)
}
return nil
}
func (*CommandExecutor) ExecuteCommandWithOutput(actionName string, command string, arg ...string) (string, error) {
logCommand(command, arg...)
cmd := exec.Command(command, arg...)
2016-09-15 08:00:43 -07:00
return runCommandWithOutput(actionName, cmd)
}
func (*CommandExecutor) ExecuteCommandPipeline(actionName string, command string) (string, error) {
logCommand(command)
cmd := exec.Command("bash", "-c", command)
2016-09-15 08:00:43 -07:00
return runCommandWithOutput(actionName, cmd)
}
func startCommand(command string, arg ...string) (*exec.Cmd, io.ReadCloser, io.ReadCloser, error) {
logCommand(command, arg...)
cmd := exec.Command(command, arg...)
stdout, _ := cmd.StdoutPipe()
stderr, _ := cmd.StderrPipe()
err := cmd.Start()
return cmd, stdout, stderr, err
}
func logOutput(stdout, stderr io.ReadCloser) {
if stdout == nil || stderr == nil {
log.Printf("failed to collect stdout and stderr")
return
}
// read command's stdout line by line and write it to the log
in := bufio.NewScanner(io.MultiReader(stdout, stderr))
lastLine := ""
for in.Scan() {
lastLine = in.Text()
log.Printf(lastLine)
}
}
2016-09-15 08:00:43 -07:00
func runCommandWithOutput(actionName string, cmd *exec.Cmd) (string, error) {
output, err := cmd.Output()
if err != nil {
return "", createCommandError(err, actionName)
}
return strings.TrimSpace(string(output)), nil
}
func logCommand(command string, arg ...string) {
log.Printf("Running command: %s %s", command, strings.Join(arg, " "))
}