compile_plugin.go 9.4 KB

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