Files
nms_cxy/src/framework/utils/machine/launch.go
2024-07-10 15:33:45 +08:00

179 lines
4.1 KiB
Go

package machine
import (
"encoding/json"
"fmt"
"hash/fnv"
"os"
"runtime"
"time"
"nms_cxy/src/framework/constants/common"
"nms_cxy/src/framework/logger"
"nms_cxy/src/framework/utils/cmd"
"nms_cxy/src/framework/utils/crypto"
"nms_cxy/src/framework/utils/parse"
)
// 机器的唯一标识符
var Code string
// 初始信息
var LaunchInfo map[string]any
// codeGenerate 生成机器的唯一标识符
func codeGenerate() string {
var machineID string
// 获取主机名
hostname, err := os.Hostname()
if err != nil {
panic(err)
}
machineID += hostname
// 获取 CPU 信息
numCPU := runtime.NumCPU()
machineID += fmt.Sprintf("%d", numCPU)
// 获取操作系统信息
osInfo := runtime.GOOS
machineID += osInfo
// 使用哈希函数生成机器码
h := fnv.New32a()
h.Write([]byte(machineID))
machineCode := h.Sum32()
return fmt.Sprintf("%x", machineCode)
}
// 网管本地路径
func filePath() string {
filePath := "/usr/local/etc/omc/machine.ini"
if runtime.GOOS == "windows" {
filePath = fmt.Sprintf("C:%s", filePath)
}
return filePath
}
// codeFileRead 读取机器保留的信息
func codeFileRead() (map[string]any, error) {
var mapData map[string]any
// 读取文件内容
bytes, err := os.ReadFile(filePath())
if err != nil {
logger.Warnf("CodeFileRead ReadFile => %s", err.Error())
return mapData, fmt.Errorf("not file")
}
content := string(bytes)
// 解密
contentDe, err := crypto.StringDecryptByAES(content)
if err != nil {
logger.Errorf("CodeFileRead decrypt: %v", err.Error())
return mapData, fmt.Errorf("decrypt fail")
}
// 序列化Map
mapData, err = parse.ConvertConfigToMap("json", string(contentDe))
if err != nil {
logger.Warnf("CodeFileRead ConvertConfigToMap => %s", err.Error())
return mapData, fmt.Errorf("content error")
}
return mapData, nil
}
// codeFileWrite 写入机器保留的信息
func codeFileWrite(data map[string]any) error {
jsonByte, _ := json.Marshal(data)
// 加密
contentEn, err := crypto.StringEncryptByAES(string(jsonByte))
if err != nil {
logger.Errorf("insert encrypt: %v", err.Error())
return fmt.Errorf("encrypt fail")
}
return parse.ConvertConfigToFile("txt", filePath(), contentEn)
}
// Launch 记录首次安装启动初始信息
func Launch() {
Code = codeGenerate()
// 检查文件是否存在
if _, err := os.Stat(filePath()); err != nil {
LaunchInfo = map[string]any{
"code": Code, // 机器码
"useTime": time.Now().UnixMilli(), // 首次使用时间
common.LAUNCH_BOOTLOADER: true, // 启动引导
common.LAUNCH_BOOTLOADER + "Time": 0, // 引导完成时间
}
codeFileWrite(LaunchInfo)
} else {
// 读取记录文件
data, err := codeFileRead()
if err != nil {
// 文件异常就重新生成
os.Remove(filePath())
Launch()
return
}
LaunchInfo = data
}
}
// SetLaunchInfo 新增额外的初始信息
func SetLaunchInfo(info map[string]any) error {
if info == nil {
return fmt.Errorf("not info")
}
// 固定值禁止变更
constKeys := []string{"code", "useTime"}
for k, v := range info {
constKey := false
for _, ck := range constKeys {
if ck == k {
constKey = true
break
}
}
if constKey {
continue
} else {
LaunchInfo[k] = v
}
}
return codeFileWrite(LaunchInfo)
}
// Bootloader 启动引导标记
func Bootloader(flag bool) error {
return SetLaunchInfo(map[string]any{
common.LAUNCH_BOOTLOADER: flag, // 启动引导 true开 false关
common.LAUNCH_BOOTLOADER + "Time": time.Now().UnixMilli(), // 引导完成时间
})
}
// Reset 引导数据重置
func Reset() error {
// 重置数据库
if runtime.GOOS == "windows" {
// return fmt.Errorf("not support window")
} else {
// 重置数据库
if _, err := cmd.Execf("sudo /usr/local/omc/bin/setomc.sh -m install"); err != nil {
return err
}
// 重启服务
if _, err := cmd.Execf("nohup sh -c \"sleep 1s && %s\" > /dev/null 2>&1 &", "sudo systemctl restart omc"); err != nil {
return err
}
}
// 重置引导标记
if err := Bootloader(true); err != nil {
return err
}
return nil
}