compile_plugin.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package handler
  2. import (
  3. "cicv-data-closedloop/common/config/c_log"
  4. "cicv-data-closedloop/common/config/c_oss"
  5. "cicv-data-closedloop/common/entity"
  6. util2 "cicv-data-closedloop/common/util"
  7. "cicv-data-closedloop/tools/plugin-compile/package/config"
  8. "encoding/json"
  9. "fmt"
  10. "github.com/google/uuid"
  11. "net/http"
  12. "os"
  13. )
  14. var (
  15. compileCmd = "go"
  16. compileCmdArgs = []string{"build", "--buildmode=plugin"}
  17. codeDir = "/root/cicv-data-closedloop/trigger/"
  18. // /root/cicv-data-closedloop/plugin-vaildate/plugin-vaildate.exe /root/rosbag-handle-pji/trigger/431a4254/main/431a4254.so
  19. vaildateCmd = "/root/cicv-data-closedloop/exe/plugin-vaildate.exe"
  20. )
  21. // Device 设备
  22. type Device struct {
  23. Name string
  24. CodeDir string
  25. }
  26. // CompileHandler implements http.Handler
  27. type CompileHandler struct{}
  28. func (h *CompileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  29. c_log.GlobalLogger.Error("CompileHandler 开始处理。")
  30. // 1 校验参数
  31. queryParams := r.URL.Query()
  32. goObjectKey := queryParams.Get("goObjectKey")
  33. if goObjectKey == "" {
  34. c_log.GlobalLogger.Error("参数 goObjectKey 不能为空。")
  35. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 goObjectKey 不能为空。"})
  36. _, _ = fmt.Fprintf(w, string(result))
  37. return
  38. }
  39. soObjectKey := queryParams.Get("soObjectKey")
  40. if soObjectKey == "" {
  41. c_log.GlobalLogger.Error("参数 soObjectKey 不能为空。")
  42. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 soObjectKey 不能为空。"})
  43. _, _ = fmt.Fprintf(w, string(result))
  44. return
  45. }
  46. //c_log.GlobalLogger.Infof("接收到参数【deviceType】=%v,【goObjectKey】=%v,【soObjectKey】=%v", deviceType, goObjectKey, soObjectKey)
  47. c_log.GlobalLogger.Infof("接收到参数【goObjectKey】=%v,【soObjectKey】=%v", goObjectKey, soObjectKey)
  48. // 2 从 oss 上下载 go 文件
  49. tempMiddlePath := uuid.New().String()[:8]
  50. goLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".go"
  51. c_log.GlobalLogger.Infof("下载源代码 %v --> %v", goObjectKey, goLocalPath)
  52. if err := util2.LimitDownload(c_oss.OssBucket, 41943040, goObjectKey, goLocalPath); err != nil {
  53. c_log.GlobalLogger.Error("下载源代码 ", goObjectKey, " 出错:", err)
  54. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1004", Message: "下载源代码 " + goObjectKey + " 出错。"})
  55. _, _ = fmt.Fprintf(w, string(result))
  56. return
  57. }
  58. // 修改文件权限为 777
  59. if err := os.Chmod(goLocalPath, 0777); err != nil {
  60. c_log.GlobalLogger.Error("修改文件权限 "+goLocalPath+" 出错:", err)
  61. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1005", Message: "修改文件权限 " + goLocalPath + " 出错。"})
  62. _, _ = fmt.Fprintf(w, string(result))
  63. return
  64. }
  65. // 3 编译 go 文件
  66. soLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".so"
  67. copiedCompileCmdArgs := make([]string, len(compileCmdArgs))
  68. copy(copiedCompileCmdArgs, compileCmdArgs)
  69. copiedCompileCmdArgs = append(copiedCompileCmdArgs, "-o", soLocalPath, goLocalPath)
  70. if _, output, err := util2.ExecuteWithEnvAndDir(os.Environ(), codeDir, compileCmd, copiedCompileCmdArgs...); err != nil {
  71. c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 出错:【命令】=", compileCmd, " ", copiedCompileCmdArgs, "【output】=", output, ",【err】=", err)
  72. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1006", Message: "编译插件 " + goObjectKey + " 出错。"})
  73. _, _ = fmt.Fprintf(w, string(result))
  74. return
  75. }
  76. // 4 校验插件是否能用
  77. if _, output, err := util2.Execute(vaildateCmd, soLocalPath); err != nil || output != "0" {
  78. c_log.GlobalLogger.Error("插件 ", goLocalPath, " 校验失败:【命令】=", vaildateCmd, " ", soLocalPath, "【output】=", output)
  79. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1007", Message: "插件 " + soObjectKey + " 校验失败。"})
  80. _, _ = fmt.Fprintf(w, string(result))
  81. return
  82. }
  83. c_log.GlobalLogger.Error("插件 ", soLocalPath, " 校验成功。")
  84. // 5 如果插件能用,将插件上传到 oss
  85. if err := util2.LimitUpload(config.OssBucket, 41943040, soObjectKey, soLocalPath); err != nil {
  86. c_log.GlobalLogger.Error("上传插件 ", soObjectKey, " 出错:", err)
  87. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1008", Message: "上传插件 " + soObjectKey + " 出错。"})
  88. _, _ = fmt.Fprintf(w, string(result))
  89. return
  90. }
  91. // 6 删除本地缓存的源代码和插件
  92. if err := util2.RemoveDir(codeDir + tempMiddlePath + "/"); err != nil {
  93. c_log.GlobalLogger.Error("删除本地缓存目录 ", codeDir+tempMiddlePath+"/", " 出错:", err)
  94. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1009", Message: "删除本地缓存出错。"})
  95. _, _ = fmt.Fprintf(w, string(result))
  96. return
  97. }
  98. // 7 返回成功数据
  99. c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 成功。")
  100. result, _ := json.Marshal(entity.HttpResult{Status: true, Code: "2000", Message: "编译插件" + goObjectKey + "成功。"})
  101. _, _ = fmt.Fprintf(w, string(result))
  102. }
  103. // PjiCompileHandler implements http.Handler
  104. type PjiCompileHandler struct{}
  105. func (h *PjiCompileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  106. c_log.GlobalLogger.Error("PjiCompileHandler 开始处理。")
  107. // 1 校验参数
  108. queryParams := r.URL.Query()
  109. goObjectKey := queryParams.Get("goObjectKey")
  110. if goObjectKey == "" {
  111. c_log.GlobalLogger.Error("参数 goObjectKey 不能为空。")
  112. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 goObjectKey 不能为空。"})
  113. _, _ = fmt.Fprintf(w, string(result))
  114. return
  115. }
  116. soObjectKey := queryParams.Get("soObjectKey")
  117. if soObjectKey == "" {
  118. c_log.GlobalLogger.Error("参数 soObjectKey 不能为空。")
  119. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1003", Message: "参数 soObjectKey 不能为空。"})
  120. _, _ = fmt.Fprintf(w, string(result))
  121. return
  122. }
  123. //c_log.GlobalLogger.Infof("接收到参数【deviceType】=%v,【goObjectKey】=%v,【soObjectKey】=%v", deviceType, goObjectKey, soObjectKey)
  124. c_log.GlobalLogger.Infof("接收到参数【goObjectKey】=%v,【soObjectKey】=%v", goObjectKey, soObjectKey)
  125. // 2 从 oss 上下载 go 文件
  126. tempMiddlePath := uuid.New().String()[:8]
  127. goLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".go"
  128. c_log.GlobalLogger.Infof("下载源代码 %v --> %v", goObjectKey, goLocalPath)
  129. if err := util2.LimitDownload(config.OssBucket2, 41943040, goObjectKey, goLocalPath); err != nil {
  130. c_log.GlobalLogger.Error("下载源代码 ", goObjectKey, " 出错:", err)
  131. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1004", Message: "下载源代码 " + goObjectKey + " 出错。"})
  132. _, _ = fmt.Fprintf(w, string(result))
  133. return
  134. }
  135. // 修改文件权限为 777
  136. if err := os.Chmod(goLocalPath, 0777); err != nil {
  137. c_log.GlobalLogger.Error("修改文件权限 "+goLocalPath+" 出错:", err)
  138. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1005", Message: "修改文件权限 " + goLocalPath + " 出错。"})
  139. _, _ = fmt.Fprintf(w, string(result))
  140. return
  141. }
  142. // 3 编译 go 文件
  143. soLocalPath := codeDir + tempMiddlePath + "/main/" + tempMiddlePath + ".so"
  144. copiedCompileCmdArgs := make([]string, len(compileCmdArgs))
  145. copy(copiedCompileCmdArgs, compileCmdArgs)
  146. copiedCompileCmdArgs = append(copiedCompileCmdArgs, "-o", soLocalPath, goLocalPath)
  147. if _, output, err := util2.ExecuteWithEnvAndDir(os.Environ(), codeDir, compileCmd, copiedCompileCmdArgs...); err != nil {
  148. c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 出错:【命令】=", compileCmd, " ", copiedCompileCmdArgs, "【output】=", output, ",【err】=", err)
  149. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1006", Message: "编译插件 " + goObjectKey + " 出错。"})
  150. _, _ = fmt.Fprintf(w, string(result))
  151. return
  152. }
  153. // 4 校验插件是否能用
  154. if _, output, err := util2.Execute(vaildateCmd, soLocalPath); err != nil || output != "0" {
  155. c_log.GlobalLogger.Error("插件 ", goLocalPath, " 校验失败:【命令】=", vaildateCmd, " ", soLocalPath, "【output】=", output)
  156. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1007", Message: "插件 " + soObjectKey + " 校验失败。"})
  157. _, _ = fmt.Fprintf(w, string(result))
  158. return
  159. }
  160. c_log.GlobalLogger.Error("插件 ", soLocalPath, " 校验成功。")
  161. // 5 如果插件能用,将插件上传到 oss
  162. if err := util2.LimitUpload(config.OssBucket2, 41943040, soObjectKey, soLocalPath); err != nil {
  163. c_log.GlobalLogger.Error("上传插件 ", soObjectKey, " 出错:", err)
  164. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1008", Message: "上传插件 " + soObjectKey + " 出错。"})
  165. _, _ = fmt.Fprintf(w, string(result))
  166. return
  167. }
  168. // 6 删除本地缓存的源代码和插件
  169. if err := util2.RemoveDir(codeDir + tempMiddlePath + "/"); err != nil {
  170. c_log.GlobalLogger.Error("删除本地缓存目录 ", codeDir+tempMiddlePath+"/", " 出错:", err)
  171. result, _ := json.Marshal(entity.HttpResult{Status: false, Code: "1009", Message: "删除本地缓存出错。"})
  172. _, _ = fmt.Fprintf(w, string(result))
  173. return
  174. }
  175. // 7 返回成功数据
  176. c_log.GlobalLogger.Error("编译插件 ", goLocalPath, " 成功。")
  177. result, _ := json.Marshal(entity.HttpResult{Status: true, Code: "2000", Message: "编译插件" + goObjectKey + "成功。"})
  178. _, _ = fmt.Fprintf(w, string(result))
  179. }