Files
ProjectOctopus/agent-go/executor/CommandExecutor.go
2023-03-30 16:10:34 +08:00

134 lines
3.1 KiB
Go

package executor
import (
logger2 "agent-go/logger"
"bufio"
"bytes"
"fmt"
"os/exec"
)
type ExecutionMessage struct {
NeedResultReplay bool `json:"needResultReplay"`
DurationTask bool `json:"durationTask,default:false"`
Type string `json:"type"`
SingleLineCommand []string `json:"singleLineCommand"`
MultiLineCommand [][]string `json:"multiLineCommand"`
PipeLineCommand [][]string `json:"pipeLineCommand"`
ResultKey string `json:"resultKey"`
}
var log = logger2.Log
func Execute(em *ExecutionMessage) ([]string, error) {
var resultLog []string
var err error
var realCommand [][]string
if em.PipeLineCommand != nil && len(em.PipeLineCommand) != 0 {
// 管道命令
resultLog, err = PipeLineCommandExecutor(em.PipeLineCommand)
realCommand = em.PipeLineCommand
} else if em.MultiLineCommand != nil && len(em.MultiLineCommand) != 0 {
// 多行命令
resultLog, err = MultiLineCommandExecutor(em.MultiLineCommand)
realCommand = em.MultiLineCommand
} else {
// 单行命令
resultLog, err = SingleLineCommandExecutor(em.SingleLineCommand)
realCommand = [][]string{em.SingleLineCommand}
}
// 归一化错误和日志
if err != nil {
resultLog = append(resultLog, fmt.Sprintf("Error: %s", err.Error()))
}
commandResult := fmt.Sprintf("Excution Comand are=> %v, Executor Result: %v", realCommand, resultLog)
log.Info(commandResult)
return resultLog, err
}
func PipeLineCommandExecutor(pipeLineCommand [][]string) ([]string, error) {
var cmds []*exec.Cmd
// 创建每个命令对象,并将前一个命令的标准输出连接到当前命令的标准输入
for i, partOfCommand := range pipeLineCommand {
cmd := exec.Command(partOfCommand[0], partOfCommand[1:]...)
if i > 0 {
prevCmd := cmds[i-1]
out, err := prevCmd.StdoutPipe()
if err != nil {
return nil, err
}
cmd.Stdin = out
}
cmds = append(cmds, cmd)
}
// 执行最后一个命令,并获取其输出
lastCmd := cmds[len(cmds)-1]
var out bytes.Buffer
lastCmd.Stdout = &out
lastCmd.Stderr = &out
err := lastCmd.Run()
scanner := bufio.NewScanner(&out)
var result []string
for scanner.Scan() {
result = append(result, scanner.Text())
}
if err != nil {
return nil, err
}
return result, nil
}
func MultiLineCommandExecutor(multiLineCommandExecutor [][]string) ([]string, error) {
var res []string
for _, singleLineCommand := range multiLineCommandExecutor {
singleLogs, err := SingleLineCommandExecutor(singleLineCommand)
res = append(res, singleLogs...)
if err != nil {
log.Error(fmt.Sprintf("Execution error ! command is %v, error is %v", singleLineCommand, err))
return res, err
}
}
return res, nil
}
// SingleLineCommandExecutor 执行单行命令
func SingleLineCommandExecutor(singleLineCommand []string) ([]string, error) {
cmd := exec.Command(singleLineCommand[0], singleLineCommand[1:]...)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
err := cmd.Run()
scanner := bufio.NewScanner(&out)
var result []string
for scanner.Scan() {
result = append(result, scanner.Text())
}
if err != nil {
return nil, err
}
return result, nil
}