gms_tools.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package gm_services
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "gadmin/config"
  7. "gadmin/internal/admin/consts"
  8. "gadmin/internal/admin/forms"
  9. "gadmin/internal/admin/ws"
  10. "gadmin/internal/gorm/model"
  11. "gadmin/internal/gorm/query"
  12. "gadmin/utility"
  13. "gadmin/utility/token"
  14. "github.com/gin-gonic/gin"
  15. "github.com/sirupsen/logrus"
  16. "os"
  17. "os/exec"
  18. "strings"
  19. "time"
  20. )
  21. // ToolsRestart 重启服务
  22. func ToolsRestart(ctx *gin.Context, params forms.ToolsRestartReq) (err error) {
  23. // 执行重启命令
  24. command := os.Getenv("BIN_PATH") + `/restart.sh ` + params.Version
  25. //logrus.Info(fmt.Sprintf("ToolsRestart run, command:%v", command))
  26. //
  27. //cmd := exec.Command("/bin/bash", "-c", command)
  28. //_, err = cmd.Output()
  29. //if err != nil {
  30. // logrus.Warning(fmt.Sprintf("ToolsRestart err, command:%v err:%v", command, err))
  31. // return
  32. //}
  33. // 重启记录
  34. createData := model.ToolsRestartLog{
  35. Version: params.Version,
  36. AdminID: token.GetUID(ctx),
  37. Username: token.GetUserName(ctx),
  38. IP: ctx.ClientIP(),
  39. UserAgent: ctx.Request.UserAgent(),
  40. Command: command,
  41. }
  42. if err = query.Use(config.DB).ToolsRestartLog.WithContext(ctx).Create(&createData); err != nil {
  43. return
  44. }
  45. if createData.ID < 1 {
  46. return errors.New("创建重启记录失败,请稍后重试!")
  47. }
  48. if err := RunCommand(token.GetUID(ctx), createData, "/bin/bash", "-c", command); err != nil {
  49. logrus.Warning(fmt.Sprintf("ToolsRestart err, command:%v err:%v", command, err))
  50. return err
  51. }
  52. logrus.Println("OK..")
  53. return
  54. }
  55. func RunCommand(adminId int64, restartModel model.ToolsRestartLog, name string, arg ...string) error {
  56. var (
  57. cmd = exec.Command(name, arg...)
  58. std string
  59. q = query.Use(config.DB).ToolsRestartLog
  60. )
  61. loadStdout(restartModel, "执行命令:"+cmd.String()+"\r\n", &std)
  62. // 命令的错误输出和标准输出都连接到同一个管道
  63. stdout, err := cmd.StdoutPipe()
  64. cmd.Stderr = cmd.Stdout
  65. if err != nil {
  66. return err
  67. }
  68. if err = cmd.Start(); err != nil {
  69. return err
  70. }
  71. go func() {
  72. // 从管道中实时获取输出并打印到终端
  73. for {
  74. tmp := make([]byte, 1024)
  75. _, err := stdout.Read(tmp)
  76. if err != nil {
  77. if err.Error() != "EOF" {
  78. loadStdout(restartModel, "stdout.Read err:"+err.Error()+"\r\n", &std)
  79. }
  80. break
  81. }
  82. loadStdout(restartModel, string(tmp), &std)
  83. }
  84. if err = cmd.Wait(); err != nil {
  85. if err.Error() != "EOF" {
  86. loadStdout(restartModel, "cmd.Wait() err:"+err.Error()+"\r\n", &std)
  87. }
  88. }
  89. restartModel.Stdout = std
  90. restartModel.Latency = int64(time.Now().Sub(restartModel.CreatedAt).Seconds())
  91. _, err := q.WithContext(context.TODO()).Where(q.ID.Eq(restartModel.ID)).Updates(&restartModel)
  92. if err != nil {
  93. logrus.Println("restartModel Updates err:", err)
  94. }
  95. loadStdout(restartModel, "restart complete", &std)
  96. }()
  97. return nil
  98. }
  99. // loadStdout 装载重启日志消息
  100. func loadStdout(restartModel model.ToolsRestartLog, msg string, std *string) {
  101. msg = utility.Rmu0000(msg)
  102. msg = strings.ReplaceAll(msg, "\\n\\t", "\r\n")
  103. logrus.Info("loadStdout:", msg)
  104. *std = *std + msg
  105. if restartModel.AdminID > 0 {
  106. msgData := ws.Msg{
  107. Id: restartModel.ID,
  108. Type: consts.SocketRestartLog,
  109. Code: consts.CodeSuccess,
  110. Msg: msg,
  111. }
  112. go ws.SendToAdmin(restartModel.AdminID, msgData)
  113. }
  114. }
  115. func ToolsRestartView(ctx *gin.Context, params forms.ToolsRestartViewReq) (models *model.ToolsRestartLog, err error) {
  116. q := query.Use(config.DB).ToolsRestartLog
  117. models, err = q.WithContext(ctx).Where(q.ID.Eq(params.ID)).Last()
  118. if err != nil {
  119. return nil, err
  120. }
  121. return
  122. }
  123. // ToolsRestartLogList 重启记录
  124. func ToolsRestartLogList(ctx *gin.Context, params forms.ToolsRestartLogReq) (models forms.ToolsRestartLogRes, err error) {
  125. q := query.Use(config.DB).ToolsRestartLog
  126. m := q.WithContext(ctx)
  127. // 设置分页
  128. if params.Limit <= 0 {
  129. params.Limit = 10
  130. }
  131. if params.Page <= 0 {
  132. params.Page = 1
  133. }
  134. offset := (params.Page - 1) * params.Limit
  135. lists, err := m.Select(q.ID, q.AdminID, q.CreatedAt, q.Username, q.Version, q.IP, q.Command, q.Latency).
  136. Order(q.ID.Desc()).Limit(params.Limit).Offset(offset).Find()
  137. if err != nil {
  138. return models, err
  139. }
  140. count, err := m.Count()
  141. if err != nil {
  142. return models, err
  143. }
  144. models.List = lists
  145. models.Limit = params.Limit
  146. models.Page = params.Page
  147. models.TotalCount = count
  148. return
  149. }