diff --git a/automation/agent/exec-script/controller/script.go b/automation/agent/exec-script/controller/script.go index a08f327f622c97deaf3c4196aa61c63122802685..a593e49cf5906e61b47ad3ae7b3a1ed76260c6f3 100644 --- a/automation/agent/exec-script/controller/script.go +++ b/automation/agent/exec-script/controller/script.go @@ -4,6 +4,7 @@ import ( "ant-agent/exec-script/model" "ant-agent/exec-script/service" + "gitee.com/openeuler/PilotGo/sdk/logger" "github.com/gin-gonic/gin" "openeuler.org/PilotGo/PilotGo-plugin-automation/pkg/response" ) @@ -14,6 +15,7 @@ func ExecScript(c *gin.Context) { response.Fail(c, nil, "参数错误") return } + logger.Info("script: %v", script) result, err := service.ExecScript(&script) if err != nil { response.Fail(c, nil, err.Error()) diff --git a/automation/agent/exec-script/model/script.go b/automation/agent/exec-script/model/script.go index 8299431b9e976e2ec2143f02040f0ccdf5d0bb94..efffcf549456accdf10dd774acac7c6ddf12f5c8 100644 --- a/automation/agent/exec-script/model/script.go +++ b/automation/agent/exec-script/model/script.go @@ -6,10 +6,18 @@ type CmdResult struct { Stderr string } +type ResultResponse struct { + JobId string + ScriptId string + Result *CmdResult +} + type ScriptsRun struct { - JobId string - ScriptType string - ScriptContent string - Params string - TimeOut int + JobId string `json:"job_id"` + ScriptId string `json:"script_id"` + ScriptTag string `json:"script_tag"` + ScriptType string `json:"script_type"` + ScriptContent string `json:"script_content"` + Params string `json:"params"` + TimeOut int `json:"time_out"` } diff --git a/automation/agent/exec-script/service/script.go b/automation/agent/exec-script/service/script.go index 348e06c646b227877ed555c2b953f5d562dce1e8..3d688cb019c9991993a8c761132328493b6393f5 100644 --- a/automation/agent/exec-script/service/script.go +++ b/automation/agent/exec-script/service/script.go @@ -5,9 +5,11 @@ import ( "bytes" "context" "encoding/base64" + "encoding/json" "fmt" "os" "os/exec" + "strings" "time" "gitee.com/openeuler/PilotGo/sdk/logger" @@ -31,36 +33,65 @@ func getScriptInfo(scriptType string) (suffix string, interpreter string, err er return } -func createTempScriptFile(workDir, suffix, encodedScript string) (string, error) { +// 解析转义字符的函数 +// 简单的转义字符解析函数 +func parseEscapeSequences(s string) string { + s = strings.ReplaceAll(s, `\n`, "\n") + s = strings.ReplaceAll(s, `\t`, "\t") + s = strings.ReplaceAll(s, `\r`, "\r") + s = strings.ReplaceAll(s, `\\`, "\\") + s = strings.ReplaceAll(s, `\"`, "\"") + s = strings.ReplaceAll(s, `\'`, "'") + return s +} + +func createScriptFile(tag, scriptId, suffix, encodedScript string) (string, error) { + var baseDir = "./srv/scripts" decodedScript, err := base64.StdEncoding.DecodeString(encodedScript) if err != nil { return "", fmt.Errorf("脚本内容base64解码失败: %s", err.Error()) } - if _, err := os.Stat(workDir); os.IsNotExist(err) { - if err := os.MkdirAll(workDir, 0755); err != nil { - return "", fmt.Errorf("创建临时工作目录失败: %s", err.Error()) + // 解析转义字符 + parsedScript := parseEscapeSequences(string(decodedScript)) + + scriptDir := fmt.Sprintf("%s/%s", baseDir, tag) + if _, err := os.Stat(scriptDir); os.IsNotExist(err) { + if err := os.MkdirAll(scriptDir, 0755); err != nil { + return "", fmt.Errorf("创建脚本存储目录失败: %s", err.Error()) } } - tmpFile, err := os.CreateTemp(workDir, "script_*"+suffix) - if err != nil { - return "", fmt.Errorf("创建临时脚本文件失败: %s", err.Error()) + scriptPath := fmt.Sprintf("%s/%s%s", scriptDir, scriptId, suffix) + if err := os.WriteFile(scriptPath, []byte(parsedScript), 0755); err != nil { + return "", fmt.Errorf("写入脚本文件失败: %s", err.Error()) } - if _, err = tmpFile.Write(decodedScript); err != nil { - tmpFile.Close() - os.Remove(tmpFile.Name()) - return "", fmt.Errorf("内容写入到脚本文件失败: %s", err.Error()) + if err := os.Chmod(scriptPath, 0755); err != nil { + os.Remove(scriptPath) + return "", fmt.Errorf("设置脚本可执行权限失败: %s", err.Error()) } - tmpFile.Close() - if err := os.Chmod(tmpFile.Name(), 0755); err != nil { - os.Remove(tmpFile.Name()) - return "", fmt.Errorf("设置脚本可执行权限失败: %s", err.Error()) + return scriptPath, nil +} + +func createJobResultPath(jobId, scriptId string) (string, error) { + var baseDir = "./srv/jobs" + + resultDir := fmt.Sprintf("%s/jobId_%s", baseDir, jobId) + if _, err := os.Stat(resultDir); os.IsNotExist(err) { + if err := os.MkdirAll(resultDir, 0755); err != nil { + return "", fmt.Errorf("创建执行结果存储目录失败: %s", err.Error()) + } } - return tmpFile.Name(), nil + resultFilePath := fmt.Sprintf("%s/result_%s.json", resultDir, scriptId) + if _, err := os.Stat(resultFilePath); os.IsNotExist(err) { + if err := os.WriteFile(resultFilePath, []byte("{}"), 0644); err != nil { + return "", fmt.Errorf("创建空的 result_%s.json 文件失败: %s", scriptId, err.Error()) + } + } + return resultFilePath, nil } func runScript(interpreter, scriptPath string, params string, timeoutSec int) (string, string, int, error) { @@ -98,19 +129,20 @@ func runScript(interpreter, scriptPath string, params string, timeoutSec int) (s } func ExecScript(script *model.ScriptsRun) (interface{}, error) { - var workDir = "/tmp/scripts/" - suffix, interpreter, err := getScriptInfo(script.ScriptType) if err != nil { return "", fmt.Errorf("获取脚本类型失败: %s", err.Error()) } - scriptPath, err := createTempScriptFile(workDir, suffix, script.ScriptContent) + scriptPath, err := createScriptFile(script.ScriptTag, script.ScriptId, suffix, script.ScriptContent) if err != nil { - return "", fmt.Errorf("创建临时脚本失败: %s", err.Error()) + return "", fmt.Errorf("创建脚本失败: %s", err.Error()) } - defer os.Remove(scriptPath) + resultFilePath, err := createJobResultPath(script.JobId, script.ScriptId) + if err != nil { + return "", fmt.Errorf("创建任务结果存储路径失败: %s", err.Error()) + } logger.Debug("run script timeout: %v", script.TimeOut) logger.Debug("process run script command: %s %s %v", interpreter, scriptPath, script.Params) @@ -120,9 +152,25 @@ func ExecScript(script *model.ScriptsRun) (interface{}, error) { Stderr: stderr, RetCode: execCode, } - if err != nil || execCode != 0 { + if err != nil { return "", fmt.Errorf("脚本执行错误: %s", err.Error()) } + resultResponse := &model.ResultResponse{ + JobId: script.JobId, + ScriptId: script.ScriptId, + Result: result, + } + logger.Debug("script execution result: %+v", resultResponse) + // 将结果写入文件 + data, err := json.MarshalIndent(resultResponse, "", " ") + if err != nil { + return "", fmt.Errorf("序列化结果失败: %s", err.Error()) + } + + if err := os.WriteFile(resultFilePath, data, 0644); err != nil { + return "", fmt.Errorf("写入结果文件失败: %s", err.Error()) + } + logger.Info("脚本执行结果已写入文件: %s", resultFilePath) return result, nil }