package service import ( "encoding/json" "os/exec" "reflect" "strconv" "strings" "time" "vamicro/config" "vamicro/extend/util" "vamicro/system-service/models" "vamicro/system-service/sys" "vamicro/system-service/vo" "basic.com/valib/bhomedbapi.git" "basic.com/valib/licence.git" "basic.com/valib/logger.git" uuid "github.com/satori/go.uuid" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/host" "github.com/shirou/gopsutil/mem" ) func StartSyncDev() { tk := time.NewTicker(30 * time.Second) for { select { case <-tk.C: syncDevToCloud() default: time.Sleep(2 * time.Second) } } } const ( token = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ3NDUwMjU5MjMsInVzZXIiOiJ7XCJpZFwiOlwiZTZjY2QzNmQtNGYxNi00NmZjLTg4ZDUtMDczNjU4NjZkMjA1XCIsXCJwZXJtaXNzaW9uc1wiOltcInByb2R1Y3RNYW5nZTpwdWJsaXNoXCIsXCJjb2RlTWFuZ2U6dmlld1wiLFwiZGV2aWNlTWFuYWdlOmFkZFwiLFwiYWRtaW5NYW5hZ2VcIixcIm9yZGVyTWFuZ2VcIixcImRldmljZU1hbmFnZTp2aWV3XCIsXCJwcm9kdWN0TWFuZ2U6YWRkXCIsXCJhZG1pbk1hbmFnZTp2aWV3XCIsXCJjb2RlTWFuZ2U6YWRkXCIsXCJwcm9kdWN0TWFuZ2U6b2ZmU2FsZVwiLFwib3JkZXJNYW5nZTpjYW5jZWxcIixcInByb2R1Y3RDZW50ZXI6ZG93bmxvYWRcIixcInByb2R1Y3RDZW50ZXI6YnV5XCIsXCJwcm9kdWN0TWFuZ2U6dmlld1wiLFwiYXBpXCIsXCJob21lXCIsXCJvcmRlck1hbmdlOnBheVwiLFwiYWRtaW5NYW5hZ2U6YWRkXCIsXCJvcmRlck1hbmdlOmRvd25sb2FkXCIsXCJwcm9kdWN0Q2VudGVyXCIsXCJkZXZpY2VNYW5hZ2U6dW5iaW5kXCIsXCJvcmRlck1hbmdlOnZpZXdcIixcImFkbWluTWFuYWdlOmVkaXRcIixcImRldmljZU1hbmFnZVwiLFwidmlwTWFuYWdlOmFkZFwiLFwidmlwTWFuYWdlOnZpZXdcIixcInByb2R1Y3RDZW50ZXI6dmlld1wiLFwidmlwTWFuYWdlOmVkaXRcIixcInZpcE1hbmFnZVwiLFwicHJvZHVjdE1hbmdlOmVkaXRcIixcImNvZGVNYW5nZVwiLFwicHJvZHVjdE1hbmdlXCJdLFwidXNlcm5hbWVcIjpcImJhc2ljXCJ9In0.vwjAFkWuEyadRLvIOGK8LFE3MjpY3SQ7j6AlTXnQDG8" tokenForSaas = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ3NDUwMjU5MjMsInVzZXIiOiJ7XCJpZFwiOlwiZTZjY2QzNmQtNGYxNi00NmZjLTg4ZDUtMDczNjU4NjZkMjA1XCIsXCJwZXJtaXNzaW9uc1wiOltcInByb2R1Y3RNYW5nZTpwdWJsaXNoXCIsXCJjb2RlTWFuZ2U6dmlld1wiLFwiZGV2aWNlTWFuYWdlOmFkZFwiLFwiYWRtaW5NYW5hZ2VcIixcIm9yZGVyTWFuZ2VcIixcImRldmljZU1hbmFnZTp2aWV3XCIsXCJwcm9kdWN0TWFuZ2U6YWRkXCIsXCJhZG1pbk1hbmFnZTp2aWV3XCIsXCJjb2RlTWFuZ2U6YWRkXCIsXCJwcm9kdWN0TWFuZ2U6b2ZmU2FsZVwiLFwib3JkZXJNYW5nZTpjYW5jZWxcIixcInByb2R1Y3RDZW50ZXI6ZG93bmxvYWRcIixcInByb2R1Y3RDZW50ZXI6YnV5XCIsXCJwcm9kdWN0TWFuZ2U6dmlld1wiLFwiYXBpXCIsXCJob21lXCIsXCJvcmRlck1hbmdlOnBheVwiLFwiYWRtaW5NYW5hZ2U6YWRkXCIsXCJvcmRlck1hbmdlOmRvd25sb2FkXCIsXCJwcm9kdWN0Q2VudGVyXCIsXCJkZXZpY2VNYW5hZ2U6dW5iaW5kXCIsXCJvcmRlck1hbmdlOnZpZXdcIixcImFkbWluTWFuYWdlOmVkaXRcIixcImRldmljZU1hbmFnZVwiLFwidmlwTWFuYWdlOmFkZFwiLFwidmlwTWFuYWdlOnZpZXdcIixcInByb2R1Y3RDZW50ZXI6dmlld1wiLFwidmlwTWFuYWdlOmVkaXRcIixcInZpcE1hbmFnZVwiLFwicHJvZHVjdE1hbmdlOmVkaXRcIixcImNvZGVNYW5nZVwiLFwicHJvZHVjdE1hbmdlXCJdLFwidXNlcm5hbWVcIjpcImJhc2ljXCJ9In0.vwjAFkWuEyadRLvIOGK8LFE3MjpY3SQ7j6AlTXnQDG8" ) var lstSync *vo.SyncDevInfo /* 设备信息同步到商城云端 */ func syncDevToCloud() { var sysconf models.LocalConfig err := sysconf.Select() if err != nil { // 查询是否存在 return } i := vo.SyncDevInfo{} ipv4, mask, _ := sys.GetLocalIP(config.Server.NetworkAdapter) gateway, _ := sys.GetDefaultRoute(config.Server.NetworkAdapter) dns, _ := sys.GetDnsServer() machineCode := licence.GetMachineCode() //1.收集设备基本信息 i.Detail = vo.DevDetail{ ServerId: config.Server.AnalyServerId, MachineCode: machineCode, ServerName: sysconf.ServerName, ServerPort: sys.GetNginxListenPort(), Ip: ipv4, SubMask: mask, Gateway: gateway, Dns: dns, DeviceNum: config.Server.DeviceNum, DeviceType: config.Server.DeviceType, DeviceModel: config.Server.DeviceModel, DeviceSerialNum: config.Server.DeviceSerialNum, MasterVersion: config.Server.MasterVersion, WebVersion: "1.0.0", DeviceDesc: config.Server.DeviceDesc, ChannelCount: int(sysconf.RealMax), NeedAuthPwd: sysconf.NeedAuthPwd, AuthPwd: sysconf.AuthPwd, } if strings.HasPrefix(util.GetPlatform(), "X86") { vg, _ := util.NvidiaVGpu() i.Detail.VGpu = vg } cmd := exec.Command("/bin/sh", "-c", "lsblk -d | grep -v part | grep -v SWAP | grep -v M | grep disk | awk '{printf $4\" \"}'") disks, _ := cmd.Output() cpu, _ := cpu.Info() mem, _ := mem.VirtualMemory() hi, _ := host.Info() i.Detail.Disk = string(disks) i.Detail.Runtime = util.TimeSpan(time.Unix(int64(hi.BootTime), 0)) if cpu != nil && len(cpu) > 0 { i.Detail.Cpu = cpu[0].ModelName } if mem != nil { i.Detail.Mem = mem.Total } var initE models.SysInit if i2, _ := initE.Select(); i2 > 0 { i.Detail.FirstUseTime = initE.InitTime i.Detail.ProvinceId = initE.ProvinceId i.Detail.CityId = initE.CityId i.Detail.CountyId = initE.CountyId } bSn, e := HttpRCT("POST", "http://127.0.0.1:8888/data/api-v/version/snBus", nil, 3*time.Second) if e == nil { var dRet bhomedbapi.Result if e := json.Unmarshal(bSn, &dRet); e == nil && dRet.Success { type tis struct { InstallTime string `json:"installTime"` } var is tis if bts, e := json.Marshal(dRet.Data); e == nil { if e = json.Unmarshal(bts, &is); e == nil { i.Detail.InstallTime = is.InstallTime } } } } //2.收集已安装算法 var sdkApi bhomedbapi.SdkApi sdks := sdkApi.FindAll("") //3.收集已安装应用 var appApi bhomedbapi.AppApi aps := appApi.FindAll("") i.Sdks = sdks i.Apps = aps diff := true if lstSync != nil { if reflect.DeepEqual(i, *lstSync) { diff = false } } // 同步设备数据到saas 已迁移至saas-service //if config.SaasConf.Url != "" { // body := util.Struct2Map(i) // url := "http://" + config.SaasConf.Url + "/data/api-d/device/syncDevToCloud" // // header := map[string]string{ // "Authorization": tokenForSaas, // } // data, err := util.DoPostRequest(url, util.CONTENT_TYPE_JSON, body, nil, header, 10*time.Second) // if err != nil { // logger.Error("send devInfo to saas cloud err:", err, string(data)) // } else { // logger.Debug("syncDevToCloud to saas result:", string(data)) // var result bhomedbapi.Result // err = json.Unmarshal(data, &result) // if err != nil { // logger.Error("unmarshal err:", err) // } // } //} if diff { // 同步设备信息到商城 if util.GetShopUrl() != "" { body := util.Struct2Map(i) url := "http://" + util.GetShopUrl() + "/data/api-d/device/syncDevToCloud" header := map[string]string{ "Authorization": token, } data, err := util.DoPostRequest(url, util.CONTENT_TYPE_JSON, body, nil, header, 10*time.Second) if err != nil { logger.Error("send devInfo to cloud err:", err) return } logger.Debug("syncDevToCloud result:", string(data)) var result bhomedbapi.Result err = json.Unmarshal(data, &result) if err != nil { logger.Error("unmarshal err:", err) return } if result.Success { lstSync = &i } else { logger.Error("syncDevToCloud result:", result) } } //查看是否有管理节点管理着此台设备 syncToDevManager(i) //需要主动通知serf1更新数据,设备管理app的数据从serf1中获取的 } } func syncToDevManager(info vo.SyncDevInfo) error { var ad models.AuthDevice managers := ad.FindByStatus(models.AuthStatus_Agreed) //获取已授权的设备列表 if len(managers) > 0 { //写入device,deviceApp及deviceSdk表中通过serf同步到其它节点 tx := models.GetDB().Begin() var err error defer func() { if err != nil && tx != nil { logger.Debug("syncToDevManager err:", err) tx.Rollback() } }() var dE models.Device dc, e := dE.FindByDevId(info.Detail.ServerId) if e == nil && dc > 0 { //已存在则更新 cd := vo.Copy2DeviceModel(info.Detail) cd.Id = dE.Id cd.ActivateCode = dE.ActivateCode cd.ProductId = dE.ProductId cd.UserId = dE.UserId cd.Address = dE.Address cd.DevGpu = dE.DevGpu cd.InstallTime = dE.InstallTime cd.FirstUseTime = dE.FirstUseTime cd.ClusterId = dE.ClusterId cd.ClusterName = dE.ClusterName cd.Status = dE.Status cd.CreateTime = dE.CreateTime cd.UpdateTime = dE.UpdateTime if err = tx.Table(cd.TableName()).Save(&cd).Error; err != nil { return err } } else { //创建 cd := vo.Copy2DeviceModel(info.Detail) cd.Id = uuid.NewV4().String() if err = tx.Table(cd.TableName()).Create(&cd).Error; err != nil { return err } } if len(info.Apps) > 0 { for _, a := range info.Apps { var da models.DeviceApp if row, _ := da.Exist(config.Server.AnalyServerId, a.Id); row > 0 { da.MachineCode = info.Detail.MachineCode da.ExpireTime = "" da.ActivateCode = "" da.InstallTime = "" if err = tx.Table(da.TableName()).Where("id=?", da.Id).Update(&da).Error; err != nil { return err } } else { tmp := models.DeviceApp{ Id: uuid.NewV4().String(), DevId: config.Server.AnalyServerId, MachineCode: info.Detail.MachineCode, ActivateCode: "", AppId: a.Id, ExpireTime: "", InstallTime: "", } if err = tx.Table(tmp.TableName()).Create(&tmp).Error; err != nil { return err } } } } if len(info.Sdks) > 0 { for _, s := range info.Sdks { var ds models.DeviceSdk if row, _ := ds.Exist(config.Server.AnalyServerId, s.Id); row > 0 { ds.MachineCode = info.Detail.MachineCode ds.ExpireTime = "" ds.ActivateCode = "" ds.InstallTime = "" if err = tx.Table(ds.TableName()).Where("id=?", ds.Id).Update(&ds).Error; err != nil { return err } } else { tmp := models.DeviceSdk{ Id: uuid.NewV4().String(), DevId: config.Server.AnalyServerId, MachineCode: info.Detail.MachineCode, ActivateCode: "", SdkId: s.Id, ExpireTime: "", InstallTime: "", } if err = tx.Table(tmp.TableName()).Create(&tmp).Error; err != nil { return err } } } } tx.Commit() return nil } return nil } //计算持续时长 func timeSpan(startTime time.Time) string { sp := time.Since(startTime) day := strconv.Itoa(int(sp.Hours() / 24)) //天数 hour := strconv.Itoa(int(sp.Hours()) % 24) //小时数 minute := strconv.Itoa(int(sp.Minutes()) % 60) //分钟数 sec := strconv.Itoa(int(sp.Seconds()) % 60) //秒数 return day + "天" + hour + "时" + minute + "分" + sec + "秒" }