| | |
| | | package controllers |
| | | |
| | | import ( |
| | | "net/http" |
| | | "strconv" |
| | | "webserver/extend/code" |
| | | "webserver/extend/config" |
| | | "webserver/extend/util" |
| | | "webserver/middlewares/auth" |
| | | "webserver/service" |
| | | |
| | | "basic.com/dbapi.git" |
| | |
| | | } |
| | | } |
| | | |
| | | // @Summary 算法安装包上传(分块检查) |
| | | // @Description 算法安装包上传(分块检查) |
| | | // @Accept multipart/form-data |
| | | // @Produce json |
| | | // @Tags sdk |
| | | // @Param chunkNumber formData int true "当前是第几个分块" |
| | | // @Param chunkSize formData int true "每一块的大小" |
| | | // @Param currentChunkSize formData int true "当前块的大小" |
| | | // @Param identifier formData string true "整个文件的唯一标识,目前是md5" |
| | | // @Param filename formData string true "文件名称" |
| | | // @Param relativePath formData string true "文件在客户端电脑的路径" |
| | | // @Param totalChunks formData int true "文件总块数" |
| | | // @Success 200 {string} json "{"code":200, msg:"", success:true}" |
| | | // @Failure 500 {string} json "{"code":500, msg:"", success:false}" |
| | | // @Router /data/api-v/sdk/upload [get] |
| | | func (sc SdkController) Upload(c *gin.Context) { |
| | | authDriver := auth.GenerateAuthDriver() |
| | | userM := (*authDriver).User(c) |
| | | if userM ==nil { |
| | | util.ResponseFormat(c,code.TokenNotFound,"登录过期,请登录") |
| | | return |
| | | } |
| | | chunkNumber, e1 := strconv.Atoi(c.Request.FormValue("chunkNumber")) |
| | | chunkSize, e2 := strconv.Atoi(c.Request.FormValue("chunkSize")) |
| | | currentChunkSize, e3 := strconv.Atoi(c.Request.FormValue("currentChunkSize")) |
| | | identifier := c.Request.FormValue("identifier") |
| | | filename := c.Request.FormValue("filename") |
| | | relativePath := c.Request.FormValue("relativePath") |
| | | totalChunks, e5 := strconv.Atoi(c.Request.FormValue("totalChunks")) |
| | | if identifier == "" || e1 != nil || e2 != nil || e3 != nil || e5 !=nil { |
| | | util.ResponseFormat(c,code.RequestParamError,"参数有误") |
| | | return |
| | | } |
| | | var arg = service.FileChunkCheckVo { |
| | | UserId: userM["id"].(string), |
| | | FileName: filename, |
| | | Identifier: identifier, |
| | | RelativePath: relativePath, |
| | | TotalChunks: totalChunks, |
| | | ChunkNumber: chunkNumber, |
| | | ChunkSize: chunkSize, |
| | | CurrentChunkSize:currentChunkSize, |
| | | } |
| | | var sv service.SysService |
| | | if b := sv.CheckUpdateFile(&arg);b { |
| | | c.String(http.StatusOK,"found") |
| | | } else { |
| | | c.String(http.StatusNoContent,"") |
| | | } |
| | | } |
| | | |
| | | // @Security ApiKeyAuth |
| | | // @Summary 算法安装包上传 |
| | | // @Description 算法安装包上传 |
| | | // @Accept multipart/form-data |
| | | // @Produce json |
| | | // @Tags sysset |
| | | // @Param chunkNumber formData int true "当前是第几个分块" |
| | | // @Param chunkSize formData int true "每一块的大小" |
| | | // @Param currentChunkSize formData int true "当前块的大小" |
| | | // @Param totalSize formData string true "文件总大小" |
| | | // @Param identifier formData string true "整个文件的唯一标识,目前是md5" |
| | | // @Param filename formData string true "文件名称" |
| | | // @Param relativePath formData string true "文件在客户端电脑的路径" |
| | | // @Param totalChunks formData int true "文件总块数" |
| | | // @Param file formData file true "文件分片内容" |
| | | // @Success 200 {string} json "{"code":200, msg:"", success:true}" |
| | | // @Failure 500 {string} json "{"code":500, msg:"", success:false}" |
| | | // @Router /data/api-v/sdk/upload [post] |
| | | func (sc SdkController) UploadPack(c *gin.Context) { |
| | | authDriver := auth.GenerateAuthDriver() |
| | | userM := (*authDriver).User(c) |
| | | if userM == nil { |
| | | util.ResponseFormat(c, code.TokenNotFound, "登录过期,请登录") |
| | | return |
| | | } |
| | | chunkNumber, e1 := strconv.Atoi(c.Request.FormValue("chunkNumber")) |
| | | chunkSize, e2 := strconv.Atoi(c.Request.FormValue("chunkSize")) |
| | | currentChunkSize, e3 := strconv.Atoi(c.Request.FormValue("currentChunkSize")) |
| | | totalSize, e4 := strconv.ParseInt(c.Request.FormValue("totalSize"), 10, 64) |
| | | identifier := c.Request.FormValue("identifier") |
| | | filename := c.Request.FormValue("filename") |
| | | relativePath := c.Request.FormValue("relativePath") |
| | | totalChunks, e5 := strconv.Atoi(c.Request.FormValue("totalChunks")) |
| | | file, header, e6 := c.Request.FormFile("file") |
| | | if identifier == "" || e1 != nil || e2 != nil || e3 != nil || e4 != nil || e5 != nil || e6 != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "参数有误") |
| | | return |
| | | } |
| | | var arg = service.FileUploadVo{ |
| | | UserId: userM["id"].(string), |
| | | FileName: filename, |
| | | Identifier: identifier, |
| | | RelativePath: relativePath, |
| | | TotalSize: totalSize, |
| | | TotalChunks: totalChunks, |
| | | ChunkNumber: chunkNumber, |
| | | ChunkSize: chunkSize, |
| | | CurrentChunkSize: currentChunkSize, |
| | | File: &file, |
| | | Header: header, |
| | | } |
| | | var sv service.SysService |
| | | if b,isComplete := sv.PatchUpload(&arg); b { |
| | | if isComplete { //上传完毕需要自动触发安装 |
| | | var sv service.SdkInstallService |
| | | if b,err := sv.SdkInstall(identifier, filename);b { |
| | | util.ResponseFormat(c,&code.Code{http.StatusOK, true, "算法安装成功"},"算法安装成功") |
| | | return |
| | | } else { |
| | | util.ResponseFormat(c,&code.Code{http.StatusBadRequest, false, "算法安装失败"},err.Error()) |
| | | return |
| | | } |
| | | } |
| | | util.ResponseFormat(c, code.Success, "") |
| | | } else { |
| | | util.ResponseFormat(c, code.ComError, "") |
| | | } |
| | | } |
| | | |
| | | func (sc SdkController) SdkDownLoad(c *gin.Context) { |
| | | var soApi dbapi.SdkApi |
| | | var sdkConfig map[string]interface{} |
| | |
| | | Header: header, |
| | | } |
| | | var sv service.SysService |
| | | if b := sv.PatchUpload(&arg); b { |
| | | if b,_ := sv.PatchUpload(&arg); b { |
| | | util.ResponseFormat(c, code.Success, "") |
| | | } else { |
| | | util.ResponseFormat(c, code.ComError, "") |
| | |
| | | var sv service.SysService |
| | | if b,err := sv.Upgrade(identifier, filename);b { |
| | | util.ResponseFormat(c,code.UpgradeSuccess,"升级成功") |
| | | } else { |
| | | util.ResponseFormat(c,code.UpgradeFail,err.Error()) |
| | | } |
| | | } |
| | | |
| | | // @Security ApiKeyAuth |
| | | // @Summary 算法安装包开始安装 |
| | | // @Description 算法安装包开始安装 |
| | | // @Accept multipart/form-data |
| | | // @Produce json |
| | | // @Tags sysset |
| | | // @Param identifier formData string true "整个文件的唯一标识,目前是md5" |
| | | // @Param filename formData string true "文件名称" |
| | | // @Success 200 {string} json "{"code":200, msg:"", success:true}" |
| | | // @Failure 500 {string} json "{"code":500, msg:"", success:false}" |
| | | // @Router /data/api-v/sysset/sdkInstall [post] |
| | | func (sset SysSetController) SdkInstall(c *gin.Context) { |
| | | identifier := c.Request.FormValue("identifier") |
| | | filename := c.Request.FormValue("filename") |
| | | if identifier == "" || filename == "" { |
| | | util.ResponseFormat(c,code.RequestParamError,"") |
| | | return |
| | | } |
| | | var sv service.SysService |
| | | if b,err := sv.SdkInstall(identifier, filename);b { |
| | | util.ResponseFormat(c,code.UpgradeSuccess,"算法安装成功") |
| | | } else { |
| | | util.ResponseFormat(c,code.UpgradeFail,err.Error()) |
| | | } |
| | |
| | | vsset.GET("/patchUpdate", ssController.PatchUpdateCheck) |
| | | vsset.POST("/patchUpdate", ssController.PatchUpdate) |
| | | vsset.POST("/upgrade", ssController.Upgrade) |
| | | |
| | | vsset.POST("/sdkInstall", ssController.SdkInstall) |
| | | } |
| | | |
| | | ic := r.Group(urlPrefix + "/info") |
| | |
| | | sdkApi.GET("/findByTaskId", sdkController.FindByTaskId) |
| | | sdkApi.GET("/getById", sdkController.GetById) |
| | | sdkApi.GET("/sdkDownload", sdkController.SdkDownLoad) |
| | | sdkApi.GET("/upload", sdkController.Upload) |
| | | sdkApi.POST("/upload", sdkController.UploadPack) |
| | | } |
| | | |
| | | //算法参数 |
| | |
| | | |
| | | import ( |
| | | "basic.com/dbapi.git" |
| | | //"basic.com/dbapi.git" |
| | | "basic.com/valib/logger.git" |
| | | "encoding/json" |
| | | "errors" |
| | |
| | | "webserver/extend/util" |
| | | ) |
| | | |
| | | type SdkInstallService struct { |
| | | |
| | | } |
| | | |
| | | //算法安装包安装 |
| | | func (sv SysService) SdkInstall(identifier string,filename string) (bool,error) { |
| | | func (sv SdkInstallService) SdkInstall(identifier string,filename string) (bool,error) { |
| | | configPatchPath := "" |
| | | if config.Server.PatchPath != "" { |
| | | configPatchPath = config.Server.PatchPath |
| | |
| | | if util.Exists(zipFilePath) { |
| | | strMd5, e := util.FileMd5(zipFilePath) |
| | | if e !=nil || strMd5 == "" { |
| | | go os.Remove(zipFilePath) |
| | | return false,errors.New("获取安装包md5失败") |
| | | } |
| | | if strMd5 == identifier { |
| | |
| | | return true,nil |
| | | |
| | | } else { |
| | | go os.Remove(zipFilePath) |
| | | logger.Debug("strMd5 is", strMd5,"identifier is",identifier,"not equal") |
| | | return false,errors.New("校验安装文件失败") |
| | | } |
| | |
| | | configPatchPath = "/opt/vasystem/patch" |
| | | } |
| | | //1.解压缩更新包 |
| | | unPackPath := configPatchPath+"/"+identifier+"_basic/" |
| | | if util.Exists(unPackPath) { |
| | | unPackTargetPath := configPatchPath+"/"+identifier+"_basic/" |
| | | unPackFilePath := configPatchPath+"/"+identifier+ext |
| | | defer func() { |
| | | if util.Exists(unPackTargetPath) { |
| | | os.RemoveAll(unPackTargetPath) |
| | | } |
| | | if util.Exists(unPackFilePath) { |
| | | os.RemoveAll(unPackFilePath) |
| | | } |
| | | }() |
| | | |
| | | if util.Exists(unPackTargetPath) { |
| | | //此版本已经更新过 |
| | | rmErr := os.RemoveAll(unPackPath) |
| | | rmErr := os.RemoveAll(unPackTargetPath) |
| | | if rmErr !=nil { |
| | | return false,rmErr |
| | | } |
| | | } |
| | | if !util.CreateDirectory(unPackPath) { |
| | | if !util.CreateDirectory(unPackTargetPath) { |
| | | return false, errors.New("创建压缩文件夹失败") |
| | | } |
| | | |
| | | unPackFilePath := configPatchPath+"/"+identifier+ext |
| | | logger.Debug("unPackFilePath:", unPackFilePath, "unPackPath:", unPackPath) |
| | | _,err := util.UnTarGzByCmd(unPackFilePath, unPackPath) |
| | | logger.Debug("unPackFilePath:", unPackFilePath, "unPackPath:", unPackTargetPath) |
| | | _,err := util.UnTarGzByCmd(unPackFilePath, unPackTargetPath) |
| | | 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 { |
| | | err = filepath.Walk(unPackTargetPath, func(path string, f os.FileInfo, err error) error { |
| | | if f == nil { |
| | | return err |
| | | } |
| | |
| | | if err != nil { |
| | | return false, err |
| | | } |
| | | unPackPath = unPackPath + targetFileName +"/" |
| | | unPackPath := unPackTargetPath + targetFileName +"/" |
| | | //解压完成,获取安装包中的文件,开始安装 |
| | | //1.解析安装说明ins.inc |
| | | incPath := unPackPath+"ins.inc" |
| | |
| | | dirFiles, _ := ioutil.ReadDir(fileTmpPath) |
| | | if dirFiles != nil && len(dirFiles) == arg.TotalChunks { |
| | | //表示所有分块都上传了,需要merge |
| | | if !sv.MergeChunks(fileTmpPath, mergedFilePath) { |
| | | if !MergeChunks(fileTmpPath, mergedFilePath) { |
| | | return false |
| | | } |
| | | } |
| | |
| | | return true |
| | | } |
| | | |
| | | func (sv SysService) PatchUpload(arg *FileUploadVo) bool { |
| | | func (sv SysService) PatchUpload(arg *FileUploadVo) (bool,bool) { |
| | | configPatchPath := "" |
| | | if config.Server.PatchPath != "" { |
| | | configPatchPath = config.Server.PatchPath |
| | |
| | | } |
| | | defer (*arg.File).Close() |
| | | if !util.CreateDirectory(configPatchPath) { |
| | | return false |
| | | return false, false |
| | | } |
| | | |
| | | filenameWithSuffix := path.Base(arg.Header.Filename) |
| | |
| | | fileTmpPath := configPatchPath + "/"+MD5Str |
| | | if !util.Exists(fileTmpPath) { |
| | | if !util.CreateDirectory(fileTmpPath) { |
| | | return false |
| | | return false, false |
| | | } |
| | | } |
| | | chunkAlignNum := util.FormatNum(arg.TotalChunks, arg.ChunkNumber) |
| | |
| | | rmErr := os.Remove(fileSavePath) |
| | | if rmErr != nil { |
| | | logger.Debug("rmErr:",rmErr) |
| | | return false |
| | | return false, false |
| | | } |
| | | } |
| | | file, e := os.Create(fileSavePath) |
| | | if e !=nil { |
| | | logger.Debug("os.Create err:",e,"fileSavePath:",fileSavePath) |
| | | return false |
| | | return false, false |
| | | } |
| | | defer file.Close() |
| | | writer := bufio.NewWriter(file) |
| | |
| | | n, err := (*arg.File).ReadAt(chunkData, 0) |
| | | if n ==0 || err !=nil { |
| | | logger.Debug("read chunkData err:",err,"n:",n) |
| | | return false |
| | | return false, false |
| | | } |
| | | nn, err2 := writer.Write(chunkData) |
| | | if nn ==0 || err2 !=nil { |
| | | logger.Debug("write chunkData err:",err2,"nn:",nn) |
| | | return false |
| | | return false, false |
| | | } |
| | | if err = writer.Flush(); err != nil { |
| | | logger.Debug("write flush err:",err) |
| | |
| | | isComplete = true |
| | | } |
| | | if isComplete { |
| | | if sv.MergeChunks(fileTmpPath,fileTmpPath + subfix) { |
| | | if MergeChunks(fileTmpPath,fileTmpPath + subfix) { |
| | | logger.Debug("merge all chunks success,identifier:",MD5Str,"fileName:",arg.FileName) |
| | | } else { |
| | | return false |
| | | return false, isComplete |
| | | } |
| | | } |
| | | return true |
| | | return true, isComplete |
| | | } |
| | | |
| | | //upgrade |
| | |
| | | return true |
| | | } |
| | | |
| | | func (sv SysService) MergeChunks(chunkPath string, storePath string) bool { |
| | | func MergeChunks(chunkPath string, storePath string) bool { |
| | | var cmd *exec.Cmd |
| | | cmd = exec.Command("/bin/sh", "-c", fmt.Sprintf("./mergeAll.sh %s %s", chunkPath, storePath)) |
| | | if b, err := cmd.Output(); err != nil { |