package handler import ( "cicv-data-closedloop/common/config/c_log" "cicv-data-closedloop/common/entity" util2 "cicv-data-closedloop/common/util" "cicv-data-closedloop/tools/plugin-compile/package/config" "encoding/json" "fmt" "github.com/google/uuid" "net/http" "os" ) var ( compileCmd = "go" compileCmdArgs = []string{"build", "--buildmode=plugin"} ) // Device 设备 type Device struct { Name string CodeDir string } // CompileHandler implements http.Handler type CompileHandler struct{} func (h *CompileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { codeDir := config.ApplicationYaml.CodeDir vaildateCmd := config.ApplicationYaml.VaildateCmd // /root/cicv-data-closedloop/plugin-vaildate/plugin-vaildate.exe /root/rosbag-handle-pji/trigger/431a4254/main/431a4254.so c_log.GlobalLogger.Error("CompileHandler 开始处理。") // 1 校验参数 queryParams := r.URL.Query() goObjectKey := queryParams.Get("goObjectKey") if goObjectKey == "" { c_log.GlobalLogger.Error("参数 goObjectKey 不能为空。") result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 goObjectKey 不能为空。"}) _, _ = fmt.Fprintf(w, string(result)) return } soObjectKey := queryParams.Get("soObjectKey") if soObjectKey == "" { c_log.GlobalLogger.Error("参数 soObjectKey 不能为空。") result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 soObjectKey 不能为空。"}) _, _ = fmt.Fprintf(w, string(result)) return } //c_log.GlobalLogger.Infof("接收到参数【deviceType】=%v,【goObjectKey】=%v,【soObjectKey】=%v", deviceType, goObjectKey, soObjectKey) c_log.GlobalLogger.Infof("接收到参数【goObjectKey】=%v,【soObjectKey】=%v", goObjectKey, soObjectKey) // 2 从 oss 上下载 go 文件 tempMiddlePath := uuid.New().String()[:8] goLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".go" c_log.GlobalLogger.Infof("下载源代码 %v --> %v", goObjectKey, goLocalPath) if err := util2.LimitDownload(config.OssBucket, 41943040, goObjectKey, goLocalPath); err != nil { c_log.GlobalLogger.Error("下载源代码 ", goObjectKey, " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1004", Message: "下载源代码 " + goObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 修改文件权限为 777 if err := os.Chmod(goLocalPath, 0777); err != nil { c_log.GlobalLogger.Error("修改文件权限 "+goLocalPath+" 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1005", Message: "修改文件权限 " + goLocalPath + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 3 编译 go 文件 soLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".so" copiedCompileCmdArgs := make([]string, len(compileCmdArgs)) copy(copiedCompileCmdArgs, compileCmdArgs) copiedCompileCmdArgs = append(copiedCompileCmdArgs, "-o", soLocalPath, goLocalPath) if _, output, err := util2.ExecuteWithEnvAndDir(os.Environ(), codeDir, compileCmd, copiedCompileCmdArgs...); err != nil { c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 出错:【命令】=", compileCmd, " ", copiedCompileCmdArgs, "【output】=", output, ",【err】=", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1006", Message: "编译插件 " + goObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 4 校验插件是否能用 if _, output, err := util2.Execute(vaildateCmd, soLocalPath); err != nil || output != "0" { c_log.GlobalLogger.Error("插件 ", goLocalPath, " 校验失败:【命令】=", vaildateCmd, " ", soLocalPath, "【output】=", output) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1007", Message: "插件 " + soObjectKey + " 校验失败。"}) _, _ = fmt.Fprintf(w, string(result)) return } c_log.GlobalLogger.Error("插件 ", soLocalPath, " 校验成功。") // 5 如果插件能用,将插件上传到 oss if err := util2.LimitUpload(config.OssBucket, 41943040, soObjectKey, soLocalPath); err != nil { c_log.GlobalLogger.Error("上传插件 ", soObjectKey, " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1008", Message: "上传插件 " + soObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 6 删除本地缓存的源代码和插件 if err := util2.RemoveDir(codeDir + tempMiddlePath + "/"); err != nil { c_log.GlobalLogger.Error("删除本地缓存目录 ", codeDir+tempMiddlePath+"/", " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1009", Message: "删除本地缓存出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 7 返回成功数据 c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 成功。") result, _ := json.Marshal(entity.HttpResult{Status: true, Code: "2000", Message: "编译插件" + goObjectKey + "成功。"}) _, _ = fmt.Fprintf(w, string(result)) } // PjiCompileHandler implements http.Handler type PjiCompileHandler struct{} func (h *PjiCompileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { codeDir := config.ApplicationYaml.CodeDir vaildateCmd := config.ApplicationYaml.VaildateCmd // /root/cicv-data-closedloop/plugin-vaildate/plugin-vaildate.exe /root/rosbag-handle-pji/trigger/431a4254/main/431a4254.so c_log.GlobalLogger.Error("PjiCompileHandler 开始处理。") // 1 校验参数 queryParams := r.URL.Query() goObjectKey := queryParams.Get("goObjectKey") if goObjectKey == "" { c_log.GlobalLogger.Error("参数 goObjectKey 不能为空。") result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 goObjectKey 不能为空。"}) _, _ = fmt.Fprintf(w, string(result)) return } soObjectKey := queryParams.Get("soObjectKey") if soObjectKey == "" { c_log.GlobalLogger.Error("参数 soObjectKey 不能为空。") result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 soObjectKey 不能为空。"}) _, _ = fmt.Fprintf(w, string(result)) return } //c_log.GlobalLogger.Infof("接收到参数【deviceType】=%v,【goObjectKey】=%v,【soObjectKey】=%v", deviceType, goObjectKey, soObjectKey) c_log.GlobalLogger.Infof("接收到参数【goObjectKey】=%v,【soObjectKey】=%v", goObjectKey, soObjectKey) // 2 从 oss 上下载 go 文件 tempMiddlePath := uuid.New().String()[:8] goLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".go" c_log.GlobalLogger.Infof("下载源代码 %v --> %v", goObjectKey, goLocalPath) if err := util2.LimitDownload(config.OssBucket2, 41943040, goObjectKey, goLocalPath); err != nil { c_log.GlobalLogger.Error("下载源代码 ", goObjectKey, " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1004", Message: "下载源代码 " + goObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 修改文件权限为 777 if err := os.Chmod(goLocalPath, 0777); err != nil { c_log.GlobalLogger.Error("修改文件权限 "+goLocalPath+" 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1005", Message: "修改文件权限 " + goLocalPath + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 3 编译 go 文件 soLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".so" copiedCompileCmdArgs := make([]string, len(compileCmdArgs)) copy(copiedCompileCmdArgs, compileCmdArgs) copiedCompileCmdArgs = append(copiedCompileCmdArgs, "-o", soLocalPath, goLocalPath) if _, output, err := util2.ExecuteWithEnvAndDir(os.Environ(), codeDir, compileCmd, copiedCompileCmdArgs...); err != nil { c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 出错:【命令】=", compileCmd, " ", copiedCompileCmdArgs, "【output】=", output, ",【err】=", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1006", Message: "编译插件 " + goObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 4 校验插件是否能用 if _, output, err := util2.Execute(vaildateCmd, soLocalPath); err != nil || output != "0" { c_log.GlobalLogger.Error("插件 ", goLocalPath, " 校验失败:【命令】=", vaildateCmd, " ", soLocalPath, "【output】=", output) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1007", Message: "插件 " + soObjectKey + " 校验失败。"}) _, _ = fmt.Fprintf(w, string(result)) return } c_log.GlobalLogger.Error("插件 ", soLocalPath, " 校验成功。") // 5 如果插件能用,将插件上传到 oss if err := util2.LimitUpload(config.OssBucket2, 41943040, soObjectKey, soLocalPath); err != nil { c_log.GlobalLogger.Error("上传插件 ", soObjectKey, " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1008", Message: "上传插件 " + soObjectKey + " 出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 6 删除本地缓存的源代码和插件 if err := util2.RemoveDir(codeDir + tempMiddlePath + "/"); err != nil { c_log.GlobalLogger.Error("删除本地缓存目录 ", codeDir+tempMiddlePath+"/", " 出错:", err) result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1009", Message: "删除本地缓存出错。"}) _, _ = fmt.Fprintf(w, string(result)) return } // 7 返回成功数据 c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 成功。") result, _ := json.Marshal(entity.HttpResult{Status: true, Code: "2000", Message: "编译插件" + goObjectKey + "成功。"}) _, _ = fmt.Fprintf(w, string(result)) }