liuxiaolong
2020-05-29 0bb9a4c37862e5098a596e121fb13fd12c2ca44f
service/SdkInstall.go
@@ -1 +1,230 @@
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"`
}