package service import ( "basic.com/valib/bhomedbapi.git" "basic.com/valib/licence.git" "basic.com/valib/logger.git" "encoding/json" "errors" "github.com/mitchellh/mapstructure" "io/ioutil" "os" "path" "strings" "sync" "time" "vamicro/config" "vamicro/extend/util" ) //安装依赖 func installDepend(insDir string) error { depDir := insDir + "/toolkits" depDef := depDir + "/depend_enc.def" if util.DirExists(depDir) && util.FileExists(depDef) { depB, err := util.CallDecFileContent(depDef) if err != nil { logger.Error("CallDecFileContent depDef err:", err) return err } depArr := strings.Split(string(depB), ":") for _, depName := range depArr { if util.DirExists(depDir+"/"+depName) && util.DirExists("/opt/toolkits") && !util.DirExists("/opt/toolkits/"+depName) { _, err = util.CopyDirByCmd(depDir+"/"+depName, "/opt/toolkits/") if err != nil { logger.Error("copy dep ", depName, " err:", err) continue } } } } return nil } type sdkConfig struct { RunTime string `json:"runtime"` } //动态监测算法依赖文件是否存在,不存在则尝试在线下载 const binPath = "/opt/vasystem/bin" var depInstallingMap sync.Map func downloadDepend(sdks []SdkIns) error { for _, s := range sdks { sdkTyp := s.SdkType jsf := binPath + "/zconf/" + sdkTyp + ".json" if util.FileExists(jsf) { fData, err := ioutil.ReadFile(jsf) if err != nil { logger.Error("open ", sdkTyp, " config err:", err) continue } var sc sdkConfig err = json.Unmarshal(fData, &sc) if err != nil { logger.Error("unmarshal sdkConfig err:", err) continue } depArr := strings.Split(sc.RunTime, ":") for _, dep := range depArr { if dep == "/opt/vasystem/libs/"+sdkTyp { continue } if strings.HasPrefix(dep, "/opt/toolkits/") { tmp := strings.Replace(dep, "/opt/toolkits", "", -1) idx := strings.Index(tmp, "/") if idx > 0 { depName := tmp[:idx] if util.DirExists("/opt/toolkits") && !util.DirExists("/opt/toolkits/"+depName) { _, ok := depInstallingMap.Load(depName) if !ok { go depOnline(depName) } } } } } } } return nil } //在线下载依赖 func depOnline(depName string) error { depInstallingMap.Store(depName, depName) defer depInstallingMap.Delete(depName) url := "http://" + util.GetShopUrl() + "/data/api-s/sdk/depend" machineCode := licence.GetMachineCode() if machineCode == "" { logger.Debug("depOnline 获取机器码失败") return errors.New("获取机器码失败") } paramBody := map[string]interface{}{ "depName": depName, "machineCode": machineCode, "serverId": config.Server.AnalyServerId, } header := map[string]string{ "Authorization": token, } respBody, err := util.DoPostRequest(url, util.CONTENT_TYPE_JSON, paramBody, nil, header, time.Second*60) if err != nil { logger.Debug("DoPostRequest err:", err) return err } var res bhomedbapi.Result if err = json.Unmarshal(respBody, &res); err != nil { logger.Debug("unmarshal err:", err) return err } if !res.Success { logger.Debug("res.Data:", res.Data) return errors.New("请求商城失败") } logger.Debug("res.Data:", res.Data) var resp downOrUpResp if err := mapstructure.Decode(res.Data.(map[string]interface{}), &resp); err != nil { logger.Debug("mapstructure.Decode err:", err) return err } logger.Debug("resp:", resp) if resp.Url == "" || resp.Md5 == "" { return errors.New("获取依赖包下载地址失败") } logger.Info("依赖项:", depName, " 在线安装包大小:", resp.Size) configPatchPath := "" if config.Server.PatchPath != "" { configPatchPath = config.Server.PatchPath } else { configPatchPath = "/opt/vasystem/patch" } if !util.DirExists(configPatchPath) { os.Mkdir(configPatchPath, 0777) } filenameWithSuffix := path.Base(resp.Url) ext := path.Ext(filenameWithSuffix) gzFilePath := configPatchPath + "/" + resp.Md5 + ext ip := &InsProgress{ Status: InsStatus_Downloading, Progress: 0, Size: resp.Size, } defer func() { if util.FileExists(gzFilePath) { os.Remove(gzFilePath) } }() if !util.FileExists(gzFilePath) { err := DownloadFile(gzFilePath, resp.Url, ip) if err != nil { logger.Debug("DownloadFile err:", err) return err } rmd5, err := util.FileMd5(gzFilePath) if err != nil { logger.Error("FileMd5 err:", err) return err } if rmd5 != resp.Md5 { err = errors.New("下载的依赖文件校验md5失败,请重新下载") logger.Error(err) return err } } //解压安装依赖 depPath := "/opt/toolkits/" + depName if !util.DirExists(depPath) { os.Mkdir(configPatchPath, os.ModePerm) } out, err := util.UnTarGzByCmd(gzFilePath, depPath) logger.Info("UnTarGzByCmd depName:", depName, " err:", err, " out:", out) if err != nil { os.RemoveAll(depPath) return err } return nil }