123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- package auto
- import (
- "bytes"
- "fmt"
- "io"
- "os"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "xg_auto_deploy/internal/config"
- "xg_auto_deploy/internal/global"
- "xg_auto_deploy/internal/models"
- "xg_auto_deploy/internal/remote"
- "xg_auto_deploy/internal/utils"
- "golang.org/x/crypto/ssh"
- )
- var wg sync.WaitGroup
- func AutoDeployALL() {
- global.Logs.Infoln("----------------开始部署----------------------------")
- for NodeId, nodeTemp := range global.ServerNodeConfigs {
- wg.Add(1)
- func(serverNodeConfig models.ServerNodeConfig, serverNodeId string) {
- //检查环境
- CheckSysEnv(&serverNodeConfig)
- CheckAppEnv(&serverNodeConfig)
- //上传文件到目标服务器
- UploadFileOrDir(serverNodeId, &serverNodeConfig)
- //设置xugu.ini
- AutoXuguini(&serverNodeConfig)
- //设置cluster
- if global.ClusterConfigMap["local_file"] != "" || global.ClusterConfigMap["template"] != "" {
- AutoCluster(&serverNodeConfig, true)
- } else {
- global.Logs.Printf("%s节点未设置cluser.ini文件\n", serverNodeConfig.NodeId)
- }
- defer wg.Done()
- }(nodeTemp, NodeId)
- }
- wg.Wait()
- for _, serverNodeConfig := range global.ServerNodeConfigs {
- PrintServerNodeEnv(&serverNodeConfig)
- }
- }
- // 上传cluster到目标服务器
- func AutoCluster(nodeTemp *models.ServerNodeConfig, onOFF bool) {
- if !onOFF {
- //获取节点 ,节点ip ,
- //获取集群配置文件
- return
- }
- id, err := strconv.Atoi(nodeTemp.NodeId)
- if err != nil {
- global.Logs.Errorf("%s节点修改cluster文件失败:%s\n", nodeTemp.NodeId, err)
- return
- }
- var ids string
- if id < 10 {
- ids = fmt.Sprintf("000%s", strconv.Itoa(id))
- } else {
- ids = fmt.Sprintf("00%s", strconv.Itoa(id))
- }
- clusterTemp := config.SaveClusterConfigBuffer(global.ClusterInfo, ids)
- err = remote.UploadFileBuffer(nodeTemp, clusterTemp, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/cluster.ini"))
- if err != nil {
- global.Logs.Errorf("%s节点上传cluster文件失败:%s\n", nodeTemp.NodeId, err)
- }
- }
- // 上传xugu.ini到目标服务器
- func AutoXuguini(nodeTemp *models.ServerNodeConfig) {
- xginiLocal := global.XginiConfigMap["local_file"]
- // 创建一个 bytes.Buffer
- xuguIniBuf := new(bytes.Buffer)
- //设置xuguini内存相关优化
- setxginiMemory(nodeTemp, false)
- //指定上传本地文件xugu.ini,
- if xginiLocal != "" {
- // 打开文件
- file, err := os.Open(xginiLocal)
- if err != nil {
- global.Logs.Errorf("%s节点打开xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
- panic(err)
- }
- defer file.Close()
- // 将文件内容复制到 buf 中
- if _, err := io.Copy(xuguIniBuf, file); err != nil {
- global.Logs.Errorf("%s节点修改xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
- panic(err)
- }
- //将配置文件里[xugu]组下的参数替换xugu.ini文件里的参数
- config.SetXginiBuffer(xuguIniBuf, global.XginiConfigMap)
- //上传到目标节点
- err = remote.UploadFileBuffer(nodeTemp, xuguIniBuf, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
- if err != nil {
- global.Logs.Errorf("%s节点上传xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
- }
- } else {
- xuguIniDownloadTempbuf := remote.DownloadFileBuffer(nodeTemp, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
- //将配置文件里[xugu]组下的参数替换xugu.ini文件里的参数
- config.SetXginiBuffer(xuguIniDownloadTempbuf, global.XginiConfigMap)
- err := remote.UploadFileBuffer(nodeTemp, xuguIniDownloadTempbuf, fmt.Sprintf(nodeTemp.XuguAddr+"/SETUP/xugu.ini"))
- if err != nil {
- global.Logs.Errorf("%s节点上传xugu.ini文件失败:%s\n", nodeTemp.NodeId, err)
- }
- }
- }
- // 设置xugu.ini配置文件中的内存相关
- func setxginiMemory(nodeTemp *models.ServerNodeConfig, onOff bool) {
- if !onOff {
- return
- }
- // 检测系统内存大小 free -h | awk 'NR==2{print $2}'
- memoryTemp, err := remote.SingleCmd(nodeTemp, "free -m | awk 'NR==2{print $4}'")
- if err != nil {
- global.Logs.Errorf("%s节点系统内存查询失败,取消自动配置xugu.ini:%s\n", nodeTemp.NodeId, err)
- }
- //分配到XginiMap
- memoryTemp = strings.TrimSpace(memoryTemp)
- memorySize, err := strconv.Atoi(memoryTemp)
- if err != nil {
- // 处理转换错误
- global.Logs.Errorf("%s节点程序内部计算远端内存大小转换错误::%s\n", nodeTemp.NodeId, err)
- return
- }
- setXgMem := func(memorySize int, para string, fls ...float64) {
- if memorySize < 8*1024 {
- } else if memorySize <= 32*1024 {
- global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[0] / 1024) * 1024))
- } else if memorySize <= 64*1024 {
- global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[1] / 1024) * 1024))
- } else if memorySize <= 256*1024 {
- global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[2] / 1024) * 1024))
- } else if memorySize <= 1000*1024 {
- global.XginiConfigMap[para] = strconv.Itoa(int((float64(memorySize) * fls[3] / 1024) * 1024))
- }
- }
- //判断配置文件是否有该参数
- //data_buff_mem
- if global.XginiConfigMap["data_buff_mem"] == "" {
- setXgMem(memorySize, "data_buff_mem", 0.5, 0.6, 0.7, 0.8)
- }
- //system_sga_mem
- if global.XginiConfigMap["system_sga_mem"] == "" {
- setXgMem(memorySize, "system_sga_mem", 0.1, 0.1, 0.1, 0.05)
- }
- }
- // 上传文件到目标服务器
- func UploadFileOrDir(serverNodeId string, serverNodeConfig *models.ServerNodeConfig) {
- //传送文件
- upFiles := func(serverNodeConfig *models.ServerNodeConfig, LocalFile string) {
- //检测上传为文件还是文件夹
- ret, _ := utils.IsFileOrFolder(LocalFile)
- switch ret {
- case "file":
- err := remote.UploadFile(serverNodeConfig, LocalFile, serverNodeConfig.XuguAddr)
- if err != nil {
- global.Logs.Fatalf("----- %s节点上传文件失败: %s\n", serverNodeId, err)
- return
- }
- global.Logs.Printf("----- %s节点上传文件成功\n", serverNodeId)
- remote.SingleCmd(serverNodeConfig, fmt.Sprintf(`chmod -R +x %s`, serverNodeConfig.XuguAddr))
- case "folder":
- // 连接到远程主机
- client, err := ssh.Dial("tcp", serverNodeConfig.IpPort, serverNodeConfig.SSHClient)
- if err != nil {
- panic(err)
- }
- defer client.Close()
- // 检测远端文件夹是否存在,不存在则创建 [ ! -d "/DATA2/GT/test" ] && mkdir -p /DATA2/GT/test
- remote.SingleCmd(serverNodeConfig, fmt.Sprintf(`[ ! -d "%s" ] && mkdir -p %s`, serverNodeConfig.XuguAddr, serverNodeConfig.XuguAddr))
- // 上传文件夹
- err = remote.UploadDir(serverNodeConfig, LocalFile, serverNodeConfig.XuguAddr)
- if err != nil {
- global.Logs.Errorf("----- %s节点上传文件夹错误\n", serverNodeId)
- panic(err)
- }
- global.Logs.Printf("----- %s节点上传文件成功\n", serverNodeId)
- remote.SingleCmd(serverNodeConfig, fmt.Sprintf(`chmod -R +x %s`, serverNodeConfig.XuguAddr))
- }
- }
- //检测服务器是什么架构
- architecture, err := remote.SingleCmd(serverNodeConfig, "uname -m")
- if err != nil {
- global.Logs.Printf("检测节点%s 服务器架构失败\n", serverNodeId)
- panic(err)
- }
- if strings.TrimSpace(architecture) == "aarch64" {
- fileLocal, err := utils.FindDirWithSubstring("./file/xugu", "aarch64")
- if err != nil {
- global.Logs.Printf("未查找到虚谷安装包\n")
- panic(err)
- }
- // 传送文件
- upFiles(serverNodeConfig, fileLocal)
- } else if strings.TrimSpace(architecture) == "x86" || strings.TrimSpace(architecture) == "64" {
- fileLocal, err := utils.FindDirWithSubstring("./file/xugu", "aarch64")
- if err != nil {
- global.Logs.Printf("未查找到虚谷安装包\n")
- panic(err)
- }
- upFiles(serverNodeConfig, fileLocal)
- }
- }
- // 打印节点基础环境
- func PrintServerNodeEnv(nodeTemp *models.ServerNodeConfig) {
- printFieldNames := func(i interface{}) {
- t := reflect.TypeOf(i)
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
- for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- //fmt.Println("Field Name:", field.Name)
- selectNodeEnvInfo(nodeTemp.SysInfo, field.Name)
- }
- for i := 0; i < t.NumField(); i++ {
- field := t.Field(i)
- //fmt.Println("Field Name:", field.Name)
- selectNodeEnvInfo(nodeTemp.AppInfo, field.Name)
- }
- }
- //fmt.Printf("节点%s : %s\n", nodeTemp.NodeId, nodeTemp.SysInfo)
- global.Logs.Printf("--------------------%s节点--------------------------------------:\n", nodeTemp.NodeId)
- // 使用反射打印字段
- printFieldNames(nodeTemp.SysInfo)
- printFieldNames(nodeTemp.AppInfo)
- global.Logs.Printf("--------------------------------------------------------------:\n")
- }
- func selectNodeEnvInfo(target interface{}, key string) {
- switch t := target.(type) {
- case *models.SysInfo:
- switch key {
- case "OsStackSize":
- global.Logs.Printf("系统环境Stack size :%s\n", t.OsStackSize)
- case "OsOpenFiles":
- global.Logs.Printf("系统环境Open files :%s\n", t.OsOpenFiles)
- case "CoreWmemDefault":
- global.Logs.Printf("系统环境Wmem Default :%s\n", t.CoreWmemDefault)
- case "CoreRmemDefault":
- global.Logs.Printf("系统环境Rmem Default :%s\n", t.CoreRmemDefault)
- case "CoreWmemMax":
- global.Logs.Printf("系统环境Wmem Max :%s\n", t.CoreWmemMax)
- }
- case *models.AppInfo:
- // 根据key设置对应字段的值
- switch key {
- case "Gcc":
- global.Logs.Printf("基础包 GCC :%s\n", t.Gcc)
- case "Libaio":
- global.Logs.Printf("基础包 Libaio :%s\n", t.Libaio)
- case "Snmpd":
- global.Logs.Printf("基础包 Snmpd :%s\n", t.Snmpd)
- case "Ntpd":
- global.Logs.Printf("基础包 Ntpd :%s\n", t.Ntpd)
- }
- }
- }
|