package service
|
|
import (
|
//"basic.com/dbapi.git"
|
"basic.com/valib/logger.git"
|
"encoding/json"
|
"errors"
|
"io/ioutil"
|
"os"
|
"path"
|
"path/filepath"
|
"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 _,insE := installSdk(identifier, ext); insE != nil {
|
return false, insE
|
}
|
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, error) {
|
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,rmErr
|
}
|
}
|
if !util.CreateDirectory(unPackPath) {
|
return false, errors.New("创建压缩文件夹失败")
|
}
|
|
unPackFilePath := configPatchPath+"/"+identifier+ext
|
logger.Debug("unPackFilePath:", unPackFilePath, "unPackPath:", unPackPath)
|
_,err := util.UnTarGzByCmd(unPackFilePath, unPackPath)
|
if err !=nil {
|
logger.Debug("UnPack err:",err,"unPackFile:",unPackFilePath)
|
return false, err
|
}
|
targetFileName := ""
|
err = filepath.Walk(unPackPath, func(path string, f os.FileInfo, err error) error {
|
if f == nil {
|
return err
|
}
|
if f.IsDir() {
|
targetFileName = f.Name()
|
}
|
return nil
|
})
|
if err != nil {
|
return false, err
|
}
|
unPackPath = unPackPath + targetFileName +"/"
|
//解压完成,获取安装包中的文件,开始安装
|
//1.解析安装说明ins.inc
|
incPath := unPackPath+"ins.inc"
|
if util.Exists(incPath) {
|
if incB, err := ioutil.ReadFile(incPath);err == nil {
|
var ins InsInc
|
if err = json.Unmarshal(incB, &ins); err == nil {
|
//处理授权信息
|
curMc := ""
|
if ins.MachineCode != curMc {
|
|
}
|
//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 {
|
zconfPath := "/opt/vasystem/bin/zconft/"
|
libPath := "/opt/vasystem/libst/"
|
if !util.DirExists(zconfPath) {
|
os.MkdirAll(zconfPath, 0777)
|
}
|
if !util.DirExists(libPath) {
|
os.MkdirAll(libPath, 0777)
|
}
|
for sdkType,_ := range soM {
|
//先解压SdkType.tar.gz文件
|
if unTarGzE := util.UnTarGz(unPackPath+sdkType+".tar.gz", unPackPath);unTarGzE == nil {
|
//复制json启动文件
|
if util.Exists(unPackPath+sdkType+"/zconf/"+sdkType+".json") {
|
util.CopyFile(unPackPath+sdkType+"/zconf/"+sdkType+".json", zconfPath)
|
}
|
if util.DirExists(unPackPath+sdkType+"/"+sdkType) {
|
if _,cE := util.CopyDirByCmd(unPackPath+sdkType+"/"+sdkType, libPath);cE != nil {
|
return false, cE
|
}
|
}
|
if util.DirExists(unPackPath+sdkType+"/models") {
|
if _,cE := util.CopyDirByCmd(unPackPath+sdkType+"/models", "/opt/vasystem/bin/zconft"); cE != nil {
|
return false, cE
|
}
|
}
|
}
|
}
|
//注册算法信息和算法参数到dbserver
|
//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)
|
logger.Debug("sdkApi.Register paramBody:", paramBody)
|
//sdkApi.Register(paramBody) //将算法注册到数据库中
|
}
|
} else {
|
return false, errors.New("反序列化算法定义信息失败")
|
}
|
} else {
|
return false, errors.New("读取算法定义信息失败")
|
}
|
} else {
|
return false, errors.New("算法定义信息丢失")
|
}
|
} else {
|
return false, errors.New("反序列化授权信息失败")
|
}
|
} else {
|
return false, errors.New("读取授权文件失败")
|
}
|
} else {
|
return false, errors.New("授权文件不存在")
|
}
|
|
return true, nil
|
}
|
|
|
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"`
|
}
|