xugu_deploy.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package auto
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "os"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "xg_auto_deploy/internal/config"
  11. "xg_auto_deploy/internal/global"
  12. "xg_auto_deploy/internal/models"
  13. "xg_auto_deploy/internal/remote"
  14. "xg_auto_deploy/internal/utils"
  15. "golang.org/x/crypto/ssh"
  16. )
  17. func AutoDeployALL() {
  18. for serverNodeId, serverNodeConfig := range global.ServerNodeConfigs {
  19. //检查环境
  20. CheckSysEnv(&serverNodeConfig)
  21. //上传文件到目标服务器
  22. UploadFileOrDir(serverNodeId, serverNodeConfig)
  23. //设置xugu.ini
  24. AutoXuguini(&serverNodeConfig)
  25. //设置cluster
  26. AutoCluster(&serverNodeConfig)
  27. }
  28. for _, serverNodeConfig := range global.ServerNodeConfigs {
  29. PrintServerNodeEnv(&serverNodeConfig)
  30. }
  31. }
  32. // 上传cluster到目标服务器
  33. func AutoCluster(nodeTemp *models.ServerNodeConfig) {
  34. id, err := strconv.Atoi(nodeTemp.NodeId)
  35. if err != nil {
  36. global.Logs.Errorf("%s节点修改cluster文件失败:%s\n", nodeTemp.NodeId, err)
  37. return
  38. }
  39. var ids string
  40. if id < 10 {
  41. ids = fmt.Sprintf("000%s", strconv.Itoa(id))
  42. } else {
  43. ids = fmt.Sprintf("00%s", strconv.Itoa(id))
  44. }
  45. clusterTemp := config.SaveClusterConfigBuffer(global.ClusterInfo, ids)
  46. err = remote.UploadFileBuffer(nodeTemp, clusterTemp, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/cluster.ini"))
  47. if err != nil {
  48. global.Logs.Errorf("%s节点上传cluster文件失败:%s\n", nodeTemp.NodeId, err)
  49. }
  50. }
  51. // 上传xugu.ini到目标服务器
  52. func AutoXuguini(nodeTemp *models.ServerNodeConfig) {
  53. xginiLocal := global.XginiConfigMap["local_file"]
  54. // 创建一个 bytes.Buffer
  55. xuguIniBuf := new(bytes.Buffer)
  56. //设置xuguini内存相关优化
  57. setxginiMemory(nodeTemp)
  58. //指定上传本地文件xugu.ini,
  59. if xginiLocal != "" {
  60. // 打开文件
  61. file, err := os.Open(xginiLocal)
  62. if err != nil {
  63. global.Logs.Errorf("%s节点打开xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
  64. panic(err)
  65. }
  66. defer file.Close()
  67. // 将文件内容复制到 buf 中
  68. if _, err := io.Copy(xuguIniBuf, file); err != nil {
  69. global.Logs.Errorf("%s节点修改xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
  70. panic(err)
  71. }
  72. //将配置文件里[xugu]组下的参数替换xugu.ini文件里的参数
  73. config.SetXginiBuffer(xuguIniBuf, global.XginiConfigMap)
  74. //上传到目标节点
  75. err = remote.UploadFileBuffer(nodeTemp, xuguIniBuf, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
  76. if err != nil {
  77. global.Logs.Errorf("%s节点上传xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
  78. }
  79. } else {
  80. xuguIniDownloadTempbuf := remote.DownloadFileBuffer(nodeTemp, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
  81. //将配置文件里[xugu]组下的参数替换xugu.ini文件里的参数
  82. config.SetXginiBuffer(xuguIniDownloadTempbuf, global.XginiConfigMap)
  83. err := remote.UploadFileBuffer(nodeTemp, xuguIniDownloadTempbuf, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
  84. if err != nil {
  85. global.Logs.Errorf("%s节点上传xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
  86. }
  87. }
  88. }
  89. // 设置xugu.ini配置文件中的内存相关
  90. func setxginiMemory(nodeTemp *models.ServerNodeConfig) {
  91. // 检测系统内存大小 free -h | awk 'NR==2{print $2}'
  92. memoryTemp, err := remote.SingleCmd(nodeTemp, "free -m | awk 'NR==2{print $4}'")
  93. if err != nil {
  94. global.Logs.Errorf("%s节点系统内存查询失败,取消自动配置xugu.ini:%s\n", nodeTemp.NodeId, err)
  95. }
  96. //分配到XginiMap
  97. memoryTemp = strings.TrimSpace(memoryTemp)
  98. memorySize, err := strconv.Atoi(memoryTemp)
  99. if err != nil {
  100. // 处理转换错误
  101. global.Logs.Errorf("%s节点程序内部计算远端内存大小转换错误::%s\n", nodeTemp.NodeId, err)
  102. return
  103. }
  104. setXgMem := func(memorySize int, para string, fls ...float64) {
  105. if memorySize < 8*1024 {
  106. } else if memorySize <= 32*1024 {
  107. global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[0] / 1024) * 1024))
  108. } else if memorySize <= 64*1024 {
  109. global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[1] / 1024) * 1024))
  110. } else if memorySize <= 256*1024 {
  111. global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[2] / 1024) * 1024))
  112. } else if memorySize <= 1000*1024 {
  113. global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[3] / 1024) * 1024))
  114. }
  115. }
  116. //判断配置文件是否有该参数
  117. //data_buff_mem
  118. if global.XginiConfigMap["data_buff_mem"] == "" {
  119. setXgMem(memorySize, "data_buff_mem", 0.5, 0.6, 0.7, 0.8)
  120. }
  121. //system_sga_mem
  122. if global.XginiConfigMap["system_sga_mem"] == "" {
  123. setXgMem(memorySize, "system_sga_mem", 0.1, 0.1, 0.1, 0.05)
  124. }
  125. }
  126. // 上传文件到目标服务器
  127. func UploadFileOrDir(serverNodeId string, serverNodeConfig models.ServerNodeConfig) {
  128. //传送文件
  129. //检测上传为文件还是文件夹
  130. ret, _ := utils.IsFileOrFolder(serverNodeConfig.LocalFile)
  131. switch ret {
  132. case "file":
  133. err := remote.UploadFile(&serverNodeConfig, serverNodeConfig.LocalFile, serverNodeConfig.TargetFile)
  134. if err != nil {
  135. global.Logs.Fatalf("%s节点上传文件失败: %s\n", serverNodeId, err)
  136. return
  137. }
  138. global.Logs.Printf("%s节点上传文件成功\n", serverNodeId)
  139. case "folder":
  140. // 连接到远程主机
  141. client, err := ssh.Dial("tcp", serverNodeConfig.IpPort, serverNodeConfig.SSHClient)
  142. if err != nil {
  143. panic(err)
  144. }
  145. defer client.Close()
  146. // 检测远端文件夹是否存在,不存在则创建 [ ! -d "/DATA2/GT/test" ] && mkdir -p /DATA2/GT/test
  147. remote.SingleCmd(&serverNodeConfig, fmt.Sprintf(`[ ! -d "%s" ] && mkdir -p %s`, serverNodeConfig.TargetFile, serverNodeConfig.TargetFile))
  148. // 上传文件夹
  149. err = remote.UploadDir(&serverNodeConfig, serverNodeConfig.LocalFile, serverNodeConfig.TargetFile)
  150. if err != nil {
  151. panic(err)
  152. }
  153. global.Logs.Printf("%s节点上传文件成功\n", serverNodeId)
  154. }
  155. }
  156. // 打印节点基础环境
  157. func PrintServerNodeEnv(nodeTemp *models.ServerNodeConfig) {
  158. printFieldNames := func(i interface{}) {
  159. t := reflect.TypeOf(i)
  160. if t.Kind() == reflect.Ptr {
  161. t = t.Elem()
  162. }
  163. for i := 0; i < t.NumField(); i++ {
  164. field := t.Field(i)
  165. //fmt.Println("Field Name:", field.Name)
  166. selectNodeEnvInfo(nodeTemp.SysInfo, field.Name)
  167. }
  168. for i := 0; i < t.NumField(); i++ {
  169. field := t.Field(i)
  170. //fmt.Println("Field Name:", field.Name)
  171. selectNodeEnvInfo(nodeTemp.AppInfo, field.Name)
  172. }
  173. }
  174. //fmt.Printf("节点%s : %s\n", nodeTemp.NodeId, nodeTemp.SysInfo)
  175. global.Logs.Printf("--------------------%s节点--------------------------------------:\n", nodeTemp.NodeId)
  176. // 使用反射打印字段
  177. printFieldNames(nodeTemp.SysInfo)
  178. printFieldNames(nodeTemp.AppInfo)
  179. global.Logs.Printf("--------------------------------------------------------------:\n")
  180. }
  181. func selectNodeEnvInfo(target interface{}, key string) {
  182. switch t := target.(type) {
  183. case *models.SysInfo:
  184. switch key {
  185. case "OsStackSize":
  186. global.Logs.Printf("系统环境Stack size :%s\n", t.OsStackSize)
  187. case "OsOpenFiles":
  188. global.Logs.Printf("系统环境Open files :%s\n", t.OsOpenFiles)
  189. case "CoreWmemDefault":
  190. global.Logs.Printf("系统环境Wmem Default :%s\n", t.CoreWmemDefault)
  191. case "CoreRmemDefault":
  192. global.Logs.Printf("系统环境Rmem Default :%s\n", t.CoreRmemDefault)
  193. case "CoreWmemMax":
  194. global.Logs.Printf("系统环境Wmem Max :%s\n", t.CoreWmemMax)
  195. }
  196. case *models.AppInfo:
  197. // 根据key设置对应字段的值
  198. switch key {
  199. case "Gcc":
  200. global.Logs.Printf("基础包 GCC :%s\n", t.Gcc)
  201. case "Libaio":
  202. global.Logs.Printf("基础包 Libaio :%s\n", t.Libaio)
  203. case "Snmpd":
  204. global.Logs.Printf("基础包 Snmpd :%s\n", t.Snmpd)
  205. case "Ntpd":
  206. global.Logs.Printf("基础包 Ntpd :%s\n", t.Ntpd)
  207. }
  208. }
  209. }