From 2fdef0f732a5d6549d2c42a116dfdd3dc75a0b48 Mon Sep 17 00:00:00 2001 From: liuxiaolong <736321739@qq.com> Date: 星期一, 06 一月 2020 16:25:34 +0800 Subject: [PATCH] merge ynPatch --- service/SysService.go | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 286 insertions(+), 0 deletions(-) diff --git a/service/SysService.go b/service/SysService.go new file mode 100644 index 0000000..1a1f14c --- /dev/null +++ b/service/SysService.go @@ -0,0 +1,286 @@ +package service + +import ( + "basic.com/valib/logger.git" + "bufio" + "errors" + "fmt" + "io/ioutil" + "mime/multipart" + "os" + "os/exec" + "path" + "strings" + "webserver/extend/config" + "webserver/extend/util" +) + +type SysService struct { + +} + +type FileChunkCheckVo struct { + UserId string + ChunkNumber int //褰撳墠鍒嗙墖涓嬫爣,浠�1寮�濮� + ChunkSize int //姣忎竴鍧楃殑澶у皬 + CurrentChunkSize int //褰撳墠鍒嗗潡鐨勫ぇ灏� + FileName string //鏂囦欢鍚嶇О + Identifier string //鏁翠釜鏂囦欢鍞竴鏍囪瘑,md5 + RelativePath string //鏂囦欢瀹㈡埛绔矾寰� + TotalSize int64 //鏂囦欢鎬诲ぇ灏� + TotalChunks int //鎬诲垎鐗囨暟閲� +} + +type FileUploadVo struct { + Id string + UserId string + ChunkNumber int //褰撳墠鍒嗙墖涓嬫爣,浠�1寮�濮� + ChunkSize int //姣忎竴鍧楃殑澶у皬 + CurrentChunkSize int //褰撳墠鍒嗗潡鐨勫ぇ灏� + FileName string //鏂囦欢鍚嶇О + Identifier string //鏁翠釜鏂囦欢鍞竴鏍囪瘑,md5 + RelativePath string //鏂囦欢瀹㈡埛绔矾寰� + TotalSize int64 //鏂囦欢鎬诲ぇ灏� + TotalChunks int //鎬诲垎鐗囨暟閲� + File *multipart.File //褰撳墠鍒嗙墖鐨勬枃浠跺唴瀹� + Header *multipart.FileHeader +} + +func (sv SysService) CheckUpdateFile(arg *FileChunkCheckVo) bool { + configPatchPath := "" + if config.Server.PatchPath != "" { + configPatchPath = config.Server.PatchPath + } else { + configPatchPath = "/opt/vasystem/patch" + } + fileTmpPath := configPatchPath + "/"+arg.Identifier + if !util.Exists(fileTmpPath) { + return false + } + //鍒ゆ柇鍚堟垚鐨勬枃浠舵槸鍚﹀瓨鍦� + index := strings.LastIndex(arg.FileName, ".") + subfix := "" + if index >-1 {//鏈夊悗缂� + subfix = arg.FileName[index:] + } + mergedFilePath := fileTmpPath+subfix + if util.Exists(mergedFilePath) { + return true + } + //鍒ゆ柇鍒嗗潡鏂囦欢鏄惁瀛樺湪 + chunkAlignNum := util.FormatNum(arg.TotalChunks, arg.ChunkNumber) + chunkFilePath := fileTmpPath+"/"+arg.Identifier+"_"+chunkAlignNum + if !util.Exists(chunkFilePath) { + return false + } + if arg.ChunkNumber == arg.TotalChunks { + dirFiles, _ := ioutil.ReadDir(fileTmpPath) + if dirFiles != nil && len(dirFiles) == arg.TotalChunks { + //琛ㄧず鎵�鏈夊垎鍧楅兘涓婁紶浜嗭紝闇�瑕乵erge + if !sv.MergeChunks(fileTmpPath, mergedFilePath) { + return false + } + } + } + return true +} + +func (sv SysService) PatchUpload(arg *FileUploadVo) bool { + configPatchPath := "" + if config.Server.PatchPath != "" { + configPatchPath = config.Server.PatchPath + } else { + configPatchPath = "/opt/vasystem/patch" + } + defer (*arg.File).Close() + if !util.CreateDirectory(configPatchPath) { + return false + } + + filenameWithSuffix := path.Base(arg.Header.Filename) + subfix := path.Ext(filenameWithSuffix) + MD5Str := arg.Identifier + logger.Debug("Identifier:",MD5Str) + fileTmpPath := configPatchPath + "/"+MD5Str + if !util.Exists(fileTmpPath) { + if !util.CreateDirectory(fileTmpPath) { + return false + } + } + chunkAlignNum := util.FormatNum(arg.TotalChunks, arg.ChunkNumber) + fileSavePath := fileTmpPath+"/"+MD5Str+"_"+chunkAlignNum + if util.Exists(fileSavePath) { + rmErr := os.Remove(fileSavePath) + if rmErr != nil { + logger.Debug("rmErr:",rmErr) + return false + } + } + file, e := os.Create(fileSavePath) + if e !=nil { + logger.Debug("os.Create err:",e,"fileSavePath:",fileSavePath) + return false + } + defer file.Close() + writer := bufio.NewWriter(file) + chunkData := make([]byte, arg.Header.Size) + n, err := (*arg.File).ReadAt(chunkData, 0) + if n ==0 || err !=nil { + logger.Debug("read chunkData err:",err,"n:",n) + return false + } + nn, err2 := writer.Write(chunkData) + if nn ==0 || err2 !=nil { + logger.Debug("write chunkData err:",err2,"nn:",nn) + return false + } + if err = writer.Flush(); err != nil { + logger.Debug("write flush err:",err) + } + isComplete := false + dirFiles, _ := ioutil.ReadDir(fileTmpPath) + if dirFiles != nil && len(dirFiles) == arg.TotalChunks { + isComplete = true + } + if isComplete { + if sv.MergeChunks(fileTmpPath,fileTmpPath + subfix) { + logger.Debug("merge all chunks success,identifier:",MD5Str,"fileName:",arg.FileName) + } else { + return false + } + } + return true +} + +//upgrade +func (sv SysService) Upgrade(identifier string,filename string) (bool,error) { + if !bakBeforeUpgrade() { + return false,errors.New("鏇存柊鍓嶅浠藉け璐�") + } + 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) { + //鏍¢獙md5 + strMd5, e := util.FileMd5(zipFilePath) + if e !=nil || strMd5 == "" { + return false,errors.New("鑾峰彇鍗囩骇鍘嬬缉鍖卪d5澶辫触") + } + if strMd5 == identifier { + if !updatePatch(identifier, ext) { + return false,errors.New("鎵ц鍗囩骇杩囩▼寮傚父,璇风‘瀹氫笂浼犵殑琛ヤ竵鏄痶ar.gz鏍煎紡") + } + return true,nil + + } else { + logger.Debug("strMd5 is", strMd5,"identifier is",identifier,"not equal") + return false,errors.New("鏍¢獙鍗囩骇鏂囦欢澶辫触") + } + } else { + return false,errors.New("鍗囩骇鏂囦欢宸蹭涪澶憋紝璇烽噸鏂颁笂浼�") + } +} + +func bakBeforeUpgrade() bool { + configBakPath := "" + if config.Server.BakPath != "" { + configBakPath = config.Server.BakPath + } else { + configBakPath = "/opt/vasystem/bak" + } + if util.Exists(configBakPath) { + //鍙繚鐣欐渶鏂扮殑鐗堟湰 + if err := os.RemoveAll(configBakPath);err != nil { + return false + } + } + if !util.CreateDirectory(configBakPath) { + return false + } + b, err := ExecCmd("cp -r /opt/vasystem/bin /opt/vasystem/bak") + if err != nil { + logger.Debug("bakBeforeUpgrade result:",string(b),"err:",err) + return false + } + return true +} + +//鏇存柊绯荤粺绋嬪簭 +func updatePatch(identifier string, ext string) bool { + configPatchPath := "" + if config.Server.PatchPath != "" { + configPatchPath = config.Server.PatchPath + } else { + configPatchPath = "/opt/vasystem/patch" + } + //1.瑙e帇缂╂洿鏂板寘 + 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 + } + + //濡傛灉閫氱敤鑴氭湰鏈夋洿鏂帮紝鍒欐洿鏂伴�氱敤鑴氭湰 + if util.Exists(unPackPath+"updatePatch.sh") { + cpStr := fmt.Sprintf("cp %s /opt/vasystem/bin",unPackPath+"updatePatch.sh") + b, err := ExecCmd(cpStr) + if err != nil { + logger.Debug("cp updatePatch.sh to bin err:",err,"result:",string(b)) + return false + } + } + + //鍒ゆ柇鏇存柊鍖呴噷鏄惁鏈夎ˉ涓佽剼鏈紝濡傛灉鏈夊垯鎵ц锛屽惁鍒欐墽琛寀pdatePatch.sh + updateCmd := fmt.Sprintf("./updatePatch.sh %s %s %s &",unPackPath,unPackFilePath,configPatchPath+"/"+identifier) + if util.Exists(unPackPath+"upgrade.sh") { + updateCmd = fmt.Sprintf("%supgrade.sh %s %s %s &",unPackPath,unPackPath,unPackFilePath,configPatchPath+"/"+identifier) + } + //2.鏇存柊绯荤粺 + b,err := ExecCmd(updateCmd) + if err != nil { + logger.Debug("upgrade err:",err,"result:",string(b),"cmd:",updateCmd) + return false + } else { + logger.Debug("upgrade result:",string(b),"cmd:",updateCmd) + } + return true +} + +func (sv SysService) 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 { + logger.Debug("mergeChunks err:", err, "result:", string(b)) + return false + } else { + logger.Debug("mergeChunks result:",string(b),"cmd: ./mergeAll.sh ", chunkPath, storePath) + return true + } +} + +func ExecCmd(cmdStr string) ([]byte,error) { + var cmd *exec.Cmd + cmd = exec.Command("/bin/sh", "-c",cmdStr) + return cmd.Output() +} \ No newline at end of file -- Gitblit v1.8.0