| | |
| | | package service |
| | | |
| | | import ( |
| | | "basic.com/dbapi.git" |
| | | "basic.com/valib/logger.git" |
| | | "encoding/json" |
| | | "errors" |
| | | "io/ioutil" |
| | | "os" |
| | | "path" |
| | | "webserver/extend/config" |
| | | "webserver/extend/util" |
| | | ) |
| | | |
| | | //算法安装包安装 |
| | | func (sv SysService) SdkInstall(identifier string,filename string) (bool,error) { |
| | | configPatchPath := "" |
| | | if config.Server.PatchPath != "" { |
| | | configPatchPath = config.Server.PatchPath |
| | | } else { |
| | | configPatchPath = "/opt/vasystem/patch" |
| | | } |
| | | |
| | | filenameWithSuffix := path.Base(filename) |
| | | ext := path.Ext(filenameWithSuffix) |
| | | |
| | | zipFilePath := configPatchPath + "/"+identifier+ext |
| | | if util.Exists(zipFilePath) { |
| | | strMd5, e := util.FileMd5(zipFilePath) |
| | | if e !=nil || strMd5 == "" { |
| | | return false,errors.New("获取安装包md5失败") |
| | | } |
| | | if strMd5 == identifier { |
| | | if !installSdk(identifier, ext) { |
| | | return false,errors.New("执行安装过程异常,请确定上传的安装包是tar.gz格式") |
| | | } |
| | | return true,nil |
| | | |
| | | } else { |
| | | logger.Debug("strMd5 is", strMd5,"identifier is",identifier,"not equal") |
| | | return false,errors.New("校验安装文件失败") |
| | | } |
| | | } else { |
| | | return false,errors.New("安装包已丢失,请重新上传") |
| | | } |
| | | } |
| | | |
| | | //安装sdk |
| | | func installSdk(identifier string, ext string) bool { |
| | | configPatchPath := "" |
| | | if config.Server.PatchPath != "" { |
| | | configPatchPath = config.Server.PatchPath |
| | | } else { |
| | | configPatchPath = "/opt/vasystem/patch" |
| | | } |
| | | //1.解压缩更新包 |
| | | unPackPath := configPatchPath+"/"+identifier+"_basic/" |
| | | if util.Exists(unPackPath) { |
| | | //此版本已经更新过 |
| | | rmErr := os.RemoveAll(unPackPath) |
| | | if rmErr !=nil { |
| | | return false |
| | | } |
| | | } |
| | | if !util.CreateDirectory(unPackPath) { |
| | | return false |
| | | } |
| | | |
| | | unPackFilePath := configPatchPath+"/"+identifier+ext |
| | | err := util.UnTarGz(unPackFilePath, unPackPath) |
| | | if err !=nil { |
| | | logger.Debug("UnPack err:",err,"unPackFile:",unPackFilePath) |
| | | return false |
| | | } |
| | | //解压完成,获取安装包中的文件,开始安装 |
| | | //1.解析安装说明ins.inc |
| | | incPath := unPackPath+"ins.inc" |
| | | ret := false |
| | | if util.Exists(incPath) { |
| | | if incB, err := ioutil.ReadFile(incPath);err == nil { |
| | | var ins InsInc |
| | | if err = json.Unmarshal(incB, &ins); err == nil { |
| | | //处理授权信息 |
| | | |
| | | //2.解析sdk.def,将so和zconf复制到/opt/vasystem/libs/文件夹下 |
| | | defPath := unPackPath + "sdk.def" |
| | | if util.Exists(defPath) { |
| | | if defB, err := ioutil.ReadFile(defPath); err == nil { |
| | | //3.将算法so、依赖文件、zconf、 |
| | | soM := make(map[string]SdkDef) |
| | | var skDefArr []SdkDef |
| | | if err = json.Unmarshal(defB, &skDefArr);err == nil { |
| | | var sdkApi dbapi.SdkApi |
| | | for _,skd := range skDefArr { |
| | | if _,ok := soM[skd.Def.SdkType];!ok { |
| | | soM[skd.Def.SdkType] = skd |
| | | } |
| | | srv := SdkRegisterVo{ |
| | | Id: skd.Def.Id, |
| | | SdkType: skd.Def.SdkType, |
| | | SdkName: skd.Def.SdkName, |
| | | Icon: skd.Def.Icon, |
| | | Url: skd.Def.Url, |
| | | } |
| | | for _,ag := range skd.Args { |
| | | sra := SdkRegisterArgVo{ |
| | | Scope: ag.Scope, |
| | | } |
| | | sra.SdkArg = SdkArg{ |
| | | Alias: ag.Alias, |
| | | Name: ag.Name, |
| | | Type: ag.Type, |
| | | ArgType: ag.ArgType, |
| | | Must: ag.Must, |
| | | Unit: ag.Unit, |
| | | Range: ag.Range, |
| | | DefaultValue: ag.DefaultValue, |
| | | DefaultOperator: ag.DefaultOperator, |
| | | Sort: ag.Sort, |
| | | } |
| | | srv.Args = append(srv.Args, sra) |
| | | } |
| | | paramBody := util.Struct2Map(srv) |
| | | sdkApi.Register(paramBody) //将算法注册到数据库中 |
| | | } |
| | | |
| | | zconfPath := "/opt/vasystem/bin/zconf/" |
| | | libPath := "/opt/vasystem/libs/" |
| | | if !util.DirExists(zconfPath) { |
| | | os.MkdirAll(zconfPath, 0777) |
| | | } |
| | | if !util.DirExists(libPath) { |
| | | os.MkdirAll(libPath, 0777) |
| | | } |
| | | for sdkType,_ := range soM { |
| | | //复制json启动文件 |
| | | util.CopyFile(unPackPath+sdkType+"/"+sdkType+".json", zconfPath) |
| | | util.CopyDir(unPackPath+sdkType+"/"+sdkType, libPath) |
| | | if util.DirExists(unPackPath+sdkType+"models") { |
| | | util.CopyDir(unPackPath+sdkType+"models", "/opt/vasystem/bin/") |
| | | } |
| | | } |
| | | ret = true |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return ret |
| | | } |
| | | |
| | | |
| | | type InsInc struct { |
| | | OrderId string `json:"orderId"` |
| | | ProductId string `json:"productId"` |
| | | ActivateCode string `json:"activateCode"` |
| | | MachineCode string `json:"machineCode"` |
| | | UserId string `json:"userId"` |
| | | SdkIds []string `json:"sdkIds"` |
| | | ModuleIds []string `json:"moduleIds"` |
| | | ChCount int `json:"chCount"` |
| | | AuthCount int `json:"authCount"` |
| | | ServeYear int `json:"serveYear"` |
| | | } |
| | | |
| | | //算法和参数定义 |
| | | type SdkDef struct { |
| | | Def Sdk `json:"def"` |
| | | Args []SdkArgEntity `json:"args"` |
| | | } |
| | | |
| | | type Sdk struct { |
| | | Id string `gorm:"column:id;primary_key;type:varchar(50);unique;not null;" json:"id"` |
| | | IpcId string `gorm:"column:ipc_id" json:"ipc_id"` |
| | | SdkType string `gorm:"column:sdk_type" json:"sdk_type"` |
| | | SdkName string `gorm:"column:sdk_name" json:"sdk_name" example:"人脸检测"` |
| | | Icon string `gorm:"column:icon" json:"icon,omitempty"` |
| | | Url string `gorm:"column:url" json:"url,omitempty" example:"http://ip:port/govideo/sdk/1"` |
| | | CreateTime string `gorm:"column:create_time" json:"create_time"` |
| | | CreateBy string `gorm:"column:create_by" json:"create_by"` |
| | | UpdateTime string `gorm:"column:update_time" json:"update_time"` |
| | | Enable bool `gorm:"column:enable;default:1" json:"enable"` |
| | | DelFlag int `gorm:"column:del_flag;default:0" json:"del_flag"` |
| | | Env string `gorm:"column:env" json:"env"` //运行环境及结果说明,json格式,包含so_file_path,runtime,param,depends(cuda版本,opencv版本,tensorflow版本等) |
| | | } |
| | | |
| | | type SdkArgEntity struct { |
| | | Id string `gorm:"primary_key;column:id" json:"id"` |
| | | SdkId string `gorm:"column:sdk_id" json:"sdk_id"` |
| | | Scope string `gorm:"column:scope" json:"scope"` |
| | | SdkArg |
| | | } |
| | | |
| | | type SdkArg struct { |
| | | Alias string `gorm:"column:alias" json:"alias"` //参数的别名 |
| | | Name string `gorm:"column:name" json:"name"` //参数名称 |
| | | Type string `gorm:"column:type" json:"type"` //参数类型(整数,字符串或数组) |
| | | ArgType string `gorm:"column:arg_type" json:"arg_type"` |
| | | Must bool `gorm:"column:must" json:"must"` //是否必填 |
| | | Unit string `gorm:"column:unit" json:"unit"` //单位 |
| | | Range string `gorm:"column:range" json:"range"` //值的范围,eg:0,100表示从0到100 |
| | | DefaultValue string `gorm:"column:default_value" json:"default_value"` |
| | | DefaultOperator string `gorm:"column:default_operator" json:"default_operator"` |
| | | Sort int `gorm:"column:sort;default:1" json:"sort"` |
| | | } |
| | | |
| | | |
| | | type SdkRegisterVo struct { |
| | | Id string `json:"id"` |
| | | SdkType string `json:"sdk_type"`//人脸检测:FaceDetect,人脸提取:FaceExtract,人脸比对:FaceCompare,行为:Yolo |
| | | SdkName string `json:"sdk_name"` //算法名称 |
| | | Args []SdkRegisterArgVo `json:"args"` //算法参数 |
| | | Icon string `json:"icon"` //算法图标 |
| | | Url string `json:"url"` //算法下载地址 |
| | | } |
| | | |
| | | type SdkRegisterArgVo struct { |
| | | Scope string `json:"scope"` |
| | | SdkArg |
| | | |
| | | Dics []SdkArgDic `json:"dics"` //如果此算法参数是被选项,需要将参数枚举值写入到字典表中 |
| | | } |
| | | |
| | | type SdkArgDic struct { |
| | | Value string `json:"value"` |
| | | Name string `json:"name"` |
| | | Sort int `json:"sort"` |
| | | } |