package executor import ( logger2 "agent-go/logger" "bufio" "bytes" "fmt" "os/exec" "strings" ) type ExecutionMessage struct { NeedResultReplay bool `json:"needResultReplay"` DurationTask bool `json:"durationTask,default:false"` Type string `json:"type"` FuncContent []string `json:"funcContent"` SingleLineCommand []string `json:"singleLineCommand"` MultiLineCommand [][]string `json:"multiLineCommand"` PipeLineCommand [][]string `json:"pipeLineCommand"` ResultKey string `json:"resultKey"` } var log = logger2.Log var AgentOsOperatorCache = &AgentOsOperator{} func Execute(em *ExecutionMessage) ([]string, error) { var resultLog []string var err error var realCommand [][]string if strings.HasPrefix(em.Type, "BASE") { // base function resultLog = AgentOsOperatorCache.Exec(em.FuncContent[0], em.FuncContent[1:]...) err = nil } else if strings.HasPrefix(em.Type, "APP") { // app function ok, resultLog := AgentOsOperatorCache.Deploy(em.FuncContent[0], em.FuncContent[1:]...) if ok { return resultLog, nil } else { return resultLog, nil } } else { // shell command 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 = AllOutputCommandExecutor(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 output []byte var err error for i, command := range pipeLineCommand { cmd := exec.Command(command[0], command[1:]...) cmd.Stdin = bytes.NewReader(output) output, err = cmd.Output() if err != nil { return strings.Split(string(output), "\n"), err } if i == len(pipeLineCommand)-1 { return strings.Split(string(output), "\n"), nil } } return []string{}, 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 }