fix: 网元软件安装log写入本地文件观察

This commit is contained in:
TsMask
2025-06-11 18:26:23 +08:00
parent cf51e80dc5
commit fa6bc9720f
10 changed files with 95 additions and 57 deletions

View File

@@ -409,7 +409,7 @@ func (s *IMSUserController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag.String(), v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
@@ -489,7 +489,7 @@ func (s *IMSUserController) Import(c *gin.Context) {
go s.imsUserService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.imsUserService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -399,7 +399,7 @@ func (s *VoIPAuthController) Export(c *gin.Context) {
data = append(data, []string{v.UserName, v.Password})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
@@ -479,7 +479,7 @@ func (s *VoIPAuthController) Import(c *gin.Context) {
go s.voipAuthService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.voipAuthService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -397,7 +397,7 @@ func (s *Controller) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
@@ -477,7 +477,7 @@ func (s *Controller) Import(c *gin.Context) {
go s.imsUserService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.imsUserService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -6,25 +6,23 @@ import (
"os"
"path/filepath"
"strings"
"be.ems/src/framework/logger"
)
// WriterFileTXT 写入txt文件 sep 分割符号 需要转换数据
// WriterFileTXTLine 逐行写入txt文件 sep 分割符号 需要转换数据
//
// 例如:
// data := [][]string{}
// data = append(data, []string{"姓名", "年龄", "城市"})
// data = append(data, []string{"1", "2", "3"})
// err := file.WriterFileTXT(data, filePath)
func WriterFileTXT(data [][]string, sep string, filePath string) error {
func WriterFileTXTLine(data [][]string, sep string, filePath string) error {
// 获取文件所在的目录路径
dirPath := filepath.Dir(filePath)
// 确保文件夹路径存在
err := os.MkdirAll(dirPath, 0775)
if err != nil {
logger.Errorf("CreateFile MkdirAll %v", err)
return err
}
// 创建或打开文件
@@ -44,21 +42,19 @@ func WriterFileTXT(data [][]string, sep string, filePath string) error {
// 将缓冲区中的数据刷新到文件中
err = writer.Flush()
if err != nil {
logger.Errorf("CreateFile Flush %v", err)
return err
}
return nil
}
// ReadFileTXT 读取Txt文件sep 分割符号 转换数组数据
func ReadFileTXT(sep string, filePath string) [][]string {
// ReadFileTXTLine 逐行读取Txt文件sep 分割符号 转换数组数据
func ReadFileTXTLine(sep string, filePath string) [][]string {
// 创建 map 存储数据
arr := make([][]string, 0)
// 打开文本文件
file, err := os.Open(filePath)
if err != nil {
logger.Errorf("OpenFile Open %v", err)
return arr
}
defer file.Close()
@@ -66,7 +62,6 @@ func ReadFileTXT(sep string, filePath string) [][]string {
// 创建一个 Scanner 对象,用于逐行读取文件内容
scanner := bufio.NewScanner(file)
if scanner.Err() != nil {
logger.Errorf("OpenFile NewScanner %v", scanner.Err())
return arr
}
@@ -78,3 +73,32 @@ func ReadFileTXT(sep string, filePath string) [][]string {
return arr
}
// WriterFileTXT 写入txt文件
//
// 例如:
// err := file.WriterFileTXT("", filePath)
func WriterFileTXT(text string, filePath string) error {
// 获取文件所在的目录路径
dirPath := filepath.Dir(filePath)
// 确保文件夹路径存在
err := os.MkdirAll(dirPath, 0775)
if err != nil {
return err
}
// 创建或打开文件
file, err := os.Create(filePath)
if err != nil {
return err
}
defer file.Close()
// 将缓冲区中的数据刷新到文件中
_, err = file.WriteString(text)
if err != nil {
return err
}
return nil
}

View File

@@ -120,7 +120,7 @@ func (s BackupExportUDMProcessor) exportAuth(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -168,7 +168,7 @@ func (s BackupExportUDMProcessor) exportSub(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -214,7 +214,7 @@ func (s BackupExportUDMProcessor) exportVOIP(neId, fileType string) string {
data = append(data, []string{v.UserName, v.Password})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}
@@ -260,7 +260,7 @@ func (s BackupExportUDMProcessor) exportVolte(neId, fileType string) string {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
return err.Error()
}
}

View File

@@ -515,7 +515,7 @@ func (s *UDMAuthController) Export(c *gin.Context) {
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
@@ -624,7 +624,7 @@ func (s *UDMAuthController) Import(c *gin.Context) {
go s.udmAuthService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmAuthService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -534,7 +534,7 @@ func (s *UDMSubController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
@@ -627,7 +627,7 @@ func (s *UDMSubController) Import(c *gin.Context) {
go s.udmSubService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmSubService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -455,7 +455,7 @@ func (s *UDMVOIPController) Export(c *gin.Context) {
data = append(data, []string{v.UserName, v.Password})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -553,7 +553,7 @@ func (s *UDMVOIPController) Import(c *gin.Context) {
go s.udmVOIPService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmVOIPService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -484,7 +484,7 @@ func (s *UDMVolteIMSController) Export(c *gin.Context) {
data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI})
}
// 输出到文件
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
if err := file.WriterFileTXTLine(data, ",", filePath); err != nil {
c.JSON(200, resp.ErrMsg(err.Error()))
return
}
@@ -582,7 +582,7 @@ func (s *UDMVolteIMSController) Import(c *gin.Context) {
go s.udmVolteIMSService.InsertData(neInfo.NeId, "csv", data)
}
if strings.HasSuffix(body.UploadPath, ".txt") {
data := file.ReadFileTXT(",", localFilePath)
data := file.ReadFileTXTLine(",", localFilePath)
go s.udmVolteIMSService.InsertData(neInfo.NeId, "txt", data)
}
}

View File

@@ -7,8 +7,8 @@ import (
"strings"
"time"
"be.ems/src/framework/ssh"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/ssh"
neFetchlink "be.ems/src/modules/network_element/fetch_link"
"be.ems/src/modules/network_element/model"
"be.ems/src/modules/network_element/repository"
@@ -17,11 +17,13 @@ import (
// 实例化服务层 NeVersion 结构体
var NewNeVersion = &NeVersion{
neVersionRepository: repository.NewNeVersion,
neInfoService: NewNeInfo,
}
// NeVersion 网元版本信息 服务层处理
type NeVersion struct {
neVersionRepository *repository.NeVersion // 网元版本信息表
neInfoService *NeInfo // 网元信息数据信息
}
// SelectNeHostPage 分页查询列表数据
@@ -54,7 +56,7 @@ func (r *NeVersion) checkNeVersion(arr *[]model.NeVersion) {
for i := range *arr {
item := (*arr)[i]
// 查询网元获取IP
neInfo := NewNeInfo.SelectNeInfoByNeTypeAndNeID(item.NeType, item.NeId)
neInfo := r.neInfoService.FindByNeTypeAndNeID(item.NeType, item.NeId)
if neInfo.NeId != item.NeId || neInfo.IP == "" {
continue
}
@@ -157,7 +159,7 @@ func (r *NeVersion) Operate(action string, neVersion model.NeVersion, preinput m
// ========= 安装时设置 =========
if action == "install" {
// 网元公共配置文件
para5GMap, err := NewNeInfo.NeConfPara5GRead()
para5GMap, err := r.neInfoService.NeConfPara5GRead()
if para5GMap == nil || err != nil {
return "", fmt.Errorf("error read para5G file info")
}
@@ -231,7 +233,7 @@ func (r *NeVersion) operateFile(sshClient *ssh.ConnSSH, softwarePath string) ([]
}
// operateCommand 操作版本-命令生成阶段
func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string) (string, []string, error) {
func (r NeVersion) operateCommand(action, neType string, neFilePaths []string) (string, []string, error) {
neTypeLower := strings.ToLower(neType)
// 命令终止结束标记
okFlagStr := fmt.Sprintf("%s version %s successful!", neTypeLower, action)
@@ -265,13 +267,13 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
omcStrArr = append(omcStrArr, fmt.Sprintf("sudo rm %s", strings.Join(neFilePaths, " ")))
// 2s后执行omc相关命令
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm -f /tmp/omc_%s.out \n", action))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("nohup sh -c \"sleep 2s && %s\" > /tmp/omc_%s.out 2>&1 & \n", strings.Join(omcStrArr, " && "), action))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm -f /tmp/operate_run_%s_omc.out \n", action))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("nohup sh -c \"sleep 2s && %s\" > /tmp/operate_run_%s_omc.out2>&1 & \n", strings.Join(omcStrArr, " && "), action))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s' \n", okFlagStr))
return okFlagStr, cmdStrArr, nil
} else if neType == "IMS" {
if action == "install" {
para5GData := NewNeInfo.Para5GData
para5GData := r.neInfoService.Para5GData
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
// 公网 PLMN地址
@@ -313,7 +315,7 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
}
} else {
if action == "install" {
para5GData := NewNeInfo.Para5GData
para5GData := r.neInfoService.Para5GData
cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n")
// AMF配置修改
@@ -560,14 +562,14 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
if action == "install" && (neTypeLower == "ims" || neTypeLower == "udm") {
// adb
if strings.Contains(pkgCmdStr, "adb") {
para5GData := NewNeInfo.Para5GData
para5GData := r.neInfoService.Para5GData
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/adb/default/adb.conf /usr/local/etc/adb/adb.conf \n")
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["DB_IP"]))
cmdStrArr = append(cmdStrArr, "sudo service adb restart \n")
}
// kvdb
if strings.Contains(pkgCmdStr, "kvdb") {
para5GData := NewNeInfo.Para5GData
para5GData := r.neInfoService.Para5GData
cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/kvdb/default/kvdb.conf /usr/local/etc/kvdb/kvdb.conf \n")
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/kvdb/kvdb.conf \n", para5GData["DB_IP"]))
cmdStrArr = append(cmdStrArr, "sudo service kvdb restart \n")
@@ -583,7 +585,7 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
}
// operateRun 操作版本-执行阶段
func (r *NeVersion) operateRun(sshClient *ssh.ConnSSH, preinput map[string]string, cmdStrArr []string, neType string, okFlagStr string) (string, error) {
func (r NeVersion) operateRun(sshClient *ssh.ConnSSH, preinput map[string]string, cmdStrArr []string, neType string, okFlagStr string) (string, error) {
// ssh连接会话
clientSession, err := sshClient.NewClientSession(127, 42)
if err != nil {
@@ -647,7 +649,18 @@ func (r *NeVersion) operateRun(sshClient *ssh.ConnSSH, preinput map[string]strin
}
// 命令终止符后继续执行命令
suffix := strings.HasSuffix(outputStr, "~]# ") || strings.HasSuffix(outputStr, "~$ ")
// "~]# ":麒麟, "~]$ ":欧拉, "~# ":NXP, "~$ ":Ubuntu
suffixStr := []string{"~]# ", "~]$ ", "~# ", "~$ "}
suffix := false
for _, v := range suffixStr {
if strings.HasSuffix(outputStr, v) {
suffix = true
break
}
}
if !suffix {
suffix = strings.LastIndex(outputStr, "# ") != -1 // 特殊内容中的终端终止符
}
if len(cmdStrArr) > 0 && suffix {
if firstRead {
firstRead = false
@@ -668,28 +681,29 @@ func (r *NeVersion) operateRun(sshClient *ssh.ConnSSH, preinput map[string]strin
}()
// 等待写入协程完成
<-done
// 将安装升级执行结果写入文件
file.WriterFileTXT(commandLineText, fmt.Sprintf("/tmp/operate_run_%s.out", neType))
return commandLineText, nil
}
// operateDome 操作版本-完成阶段
func (r *NeVersion) operateDome(action string, neVersion model.NeVersion) error {
func (r NeVersion) operateDome(action string, neVersion model.NeVersion) error {
if action == "install" {
// 网元信息
neInfo := NewNeInfo.SelectNeInfoByNeTypeAndNeID(neVersion.NeType, neVersion.NeId)
neInfo := r.neInfoService.FindByNeTypeAndNeID(neVersion.NeType, neVersion.NeId)
if neInfo.NeId != neVersion.NeId {
return fmt.Errorf("error found neinfo")
}
// ========= 网元OAM配置文件 start ==========
if err := NewNeInfo.NeConfOAMWirteSync(neInfo, nil, true); err != nil {
if err := r.neInfoService.NeConfOAMWirteSync(neInfo, nil, true); err != nil {
return fmt.Errorf("error wirte OAM file info")
}
// ========= 网元OAM配置文件 end ===========
// SMSC配置修改 IMS/UDM 配置
if neInfo.NeType == "SMSC" {
para5GData := NewNeInfo.Para5GData
para5GData := r.neInfoService.Para5GData
mnc_mcc := fmt.Sprintf("mnc%s.mcc%s", para5GData["MNC_DOMAIN"], para5GData["MCC"])
smscHost := fmt.Sprintf("%s smsc.ims.%s.3gppnetwork.org", para5GData["SMSC_IP"], mnc_mcc)
smscHostCMD := fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", smscHost, smscHost)
@@ -697,24 +711,24 @@ func (r *NeVersion) operateDome(action string, neVersion model.NeVersion) error
smsHost := fmt.Sprintf("sudo sed -i '/^%s smsc.*smsc$/c\\' /etc/hosts", para5GData["SIP_IP"])
// IMS 配置
imsNEs := NewNeInfo.SelectList(model.NeInfo{NeType: "IMS"}, false, false)
imsNEs := r.neInfoService.SelectList(model.NeInfo{NeType: "IMS"}, false, false)
for _, v := range imsNEs {
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscIPCMD)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscHostCMD)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smsHost)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, "sudo sed -i '/^#!define WITH_SMS/ s/^/#/' /usr/local/etc/ims/vars.cfg")
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, "ims-stop || true && ims-start")
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscIPCMD)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscHostCMD)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smsHost)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, "sudo sed -i '/^#!define WITH_SMS/ s/^/#/' /usr/local/etc/ims/vars.cfg")
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, "ims-stop || true && ims-start")
}
// UDM 配置
smscASName := fmt.Sprintf("sudo sed -i \"/- name: 'sms_as'/{n;s|serverName: .*|serverName: 'sip:%s:5060'|}\" /usr/local/etc/udm/as.yaml", para5GData["SMSC_IP"])
smscASAddress := fmt.Sprintf("sudo sed -i \"/- name: 'sms_as'/{n;n;n;s|diameterAddress: .*|diameterAddress: 'smsc.ims.%s.3gppnetwork.org'|}\" /usr/local/etc/udm/as.yaml", mnc_mcc)
udmNEs := NewNeInfo.SelectList(model.NeInfo{NeType: "UDM"}, false, false)
udmNEs := r.neInfoService.SelectList(model.NeInfo{NeType: "UDM"}, false, false)
for _, v := range udmNEs {
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscIPCMD)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscHostCMD)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscASName)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, smscASAddress)
NewNeInfo.NeRunSSHCmd(v.NeType, v.NeId, "sudo service udm restart")
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscIPCMD)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscHostCMD)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscASName)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, smscASAddress)
r.neInfoService.NeRunSSHCmd(v.NeType, v.NeId, "sudo service udm restart")
}
}
}