This commit is contained in:
wh_zcy 2022-08-12 18:47:23 +08:00
parent 24fb25692f
commit 98aa5b7de7
7 changed files with 420 additions and 0 deletions

0
cmd/upgrade/build.sh Normal file
View File

View File

@ -0,0 +1,5 @@
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build -o update main.go

167
cmd/upgrade/main.go Normal file
View File

@ -0,0 +1,167 @@
package main
import (
"embed"
"flag"
"fmt"
"go_dreamfactory/cmd/upgrade/tools"
"html/template"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
)
// func main() {
// http.HandleFunc("/download", FileDownload)
// http.HandleFunc("/upload", FileUpload)
// log.Print("http server start")
// if err := http.ListenAndServe(":8910", nil); err != nil {
// log.Fatal(err)
// }
// }
func FileUpload(w http.ResponseWriter, r *http.Request) {
//获取文件流,第三个返回值是错误对象
file, header, _ := r.FormFile("file")
//读取文件流为[]byte
b, _ := ioutil.ReadAll(file)
//把文件保存到指定位置
ioutil.WriteFile("/opt/upgrade", b, 0777)
//输出上传时文件名
fmt.Println("上传文件名:", header.Filename)
}
func FileDownload(w http.ResponseWriter, r *http.Request) {
filename := "E:\\projects\\workspace\\go_dreamfactory\\cmd\\v2\\RobotGUI.exe"
file, _ := os.Open(filename)
defer file.Close()
fileHeader := make([]byte, 512)
file.Read(fileHeader)
fileStat, _ := file.Stat()
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
w.Header().Set("Content-Type", http.DetectContentType(fileHeader))
w.Header().Set("Content-Length", strconv.FormatInt(fileStat.Size(), 10))
file.Seek(0, 0)
io.Copy(w, file)
return
}
//go:embed views/*
var f embed.FS
var version = "0.0.1"
func main() {
host := flag.String("host", "10.0.0.9", "Host")
port := flag.String("port", "8080", "Port")
uploadsDir := flag.String("uploadsDir", "./uploads", "上传文件存储地址")
wwwDir := flag.String("wwwDir", "./www", "www服务地址即解压地址")
flag.Parse()
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
r.Static("/prd", "./www")
tmpl := template.Must(template.New("").ParseFS(f, "views/*"))
r.SetHTMLTemplate(tmpl)
r.GET("/version", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"version": version,
})
})
r.GET("/", func(c *gin.Context) {
fmt.Println(tmpl.DefinedTemplates())
c.HTML(http.StatusOK, "index.html", nil)
})
r.POST("/upload", func(c *gin.Context) {
f, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
//从上传的文件名获取到版本号
s := strings.SplitN(f.Filename, "-", 2)
if len(s) != 2 {
c.JSON(http.StatusBadRequest, gin.H{
"error": "上传的文件名中没有包含版本号 eg. update.zip-0.0.1",
})
return
}
version = s[1] //设置版本号
dst := path.Join(*uploadsDir, f.Filename)
err = c.SaveUploadedFile(f, dst)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
}
_, err = tools.Unzip(dst, *wwwDir)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
}
c.JSON(http.StatusOK, gin.H{
"msg": "upload success",
"url": strings.Join([]string{"http://" + *host + ":" + *port, "/prd/", strings.Split(f.Filename, ".")[0], "/index.html"}, ""),
})
})
r.GET("/dirs", func(c *gin.Context) {
dir, err := ioutil.ReadDir(*wwwDir)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
}
type Item struct {
Name string `json:"name"`
Url string `json:"url"`
DateTime string `json:"dateTime"`
}
var dirs []Item
for _, f := range dir {
// if f.IsDir() && len(f.Name()) > 0 && f.Name() != "__MACOSX" {
dirs = append(dirs, Item{
Name: f.Name(),
Url: strings.Join([]string{"http://" + *host + ":" + *port, "/prd/", f.Name()}, ""),
DateTime: f.ModTime().Format(time.RFC3339),
})
// }
}
c.JSON(http.StatusOK, gin.H{
"dirs": dirs,
})
})
err := r.Run("0.0.0.0:" + *port)
if err != nil {
log.Fatal(err)
}
}

0
cmd/upgrade/readme.md Normal file
View File

125
cmd/upgrade/tools/gz.go Normal file
View File

@ -0,0 +1,125 @@
package tools
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func UnGz(tarFile, dest string) error {
srcFile, err := os.Open(tarFile)
if err != nil {
return err
}
defer srcFile.Close()
gr, err := gzip.NewReader(srcFile)
if err != nil {
return err
}
defer gr.Close()
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err != nil {
if err == io.EOF {
break
} else {
return err
}
}
filename := dest + hdr.Name
file, err := createFile(filename)
if err != nil {
return err
}
io.Copy(file, tr)
}
return nil
}
func createFile(name string) (*os.File, error) {
err := os.MkdirAll(string([]rune(name)[0:strings.LastIndex(name, "/")]), 0755)
if err != nil {
return nil, err
}
return os.Create(name)
}
func UnGzip(tarName, xpath string) (err error) {
tarFile, err := os.Open(tarName)
if err != nil {
return err
}
defer func() {
err = tarFile.Close()
}()
os.Mkdir(xpath, 0755)
absPath, err := filepath.Abs(xpath)
if err != nil {
return err
}
tr := tar.NewReader(tarFile)
if strings.HasSuffix(tarName, ".gz") || strings.HasSuffix(tarName, ".gzip") {
gz, err := gzip.NewReader(tarFile)
if err != nil {
return err
}
defer gz.Close()
tr = tar.NewReader(gz)
}
// untar each segment
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
// determine proper file path info
finfo := hdr.FileInfo()
fileName := hdr.Name
if filepath.IsAbs(fileName) {
fmt.Printf("removing / prefix from %s\n", fileName)
fileName, err = filepath.Rel("/", fileName)
if err != nil {
return err
}
}
absFileName := filepath.Join(absPath, fileName)
if finfo.Mode().IsDir() {
if err := os.MkdirAll(absFileName, 0755); err != nil {
return err
}
continue
}
// create new file with original file mode
file, err := os.OpenFile(absFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, finfo.Mode().Perm())
if err != nil {
return err
}
fmt.Printf("x %s\n", absFileName)
n, cpErr := io.Copy(file, tr)
if closeErr := file.Close(); closeErr != nil { // close file immediately
return err
}
if cpErr != nil {
return cpErr
}
if n != finfo.Size() {
return fmt.Errorf("unexpected bytes written: wrote %d, want %d", n, finfo.Size())
}
}
return nil
}

54
cmd/upgrade/tools/zip.go Normal file
View File

@ -0,0 +1,54 @@
package tools
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func Unzip(src string, dest string) ([]string, error) {
var filenames []string
r, err := zip.OpenReader(src)
if err != nil {
return filenames, err
}
defer r.Close()
for _, f := range r.File {
// Store filename/path for returning and using later on
fpath := filepath.Join(dest, f.Name)
// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) {
return filenames, fmt.Errorf("%s: illegal file path", fpath)
}
filenames = append(filenames, fpath)
if f.FileInfo().IsDir() {
// Make Folder
os.MkdirAll(fpath, os.ModePerm)
continue
}
// Make File
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
return filenames, err
}
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return filenames, err
}
rc, err := f.Open()
if err != nil {
return filenames, err
}
_, err = io.Copy(outFile, rc)
// Close the file without defer to close before next iteration of loop
outFile.Close()
rc.Close()
if err != nil {
return filenames, err
}
}
return filenames, nil
}

View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传</title>
<!-- import Vue.js -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.6/vue.min.js"></script>
<!-- import stylesheet -->
<link href="https://cdn.bootcdn.net/ajax/libs/iview/3.5.5-rc.1/styles/iview.min.css" rel="stylesheet">
<!-- import iView -->
<script src="https://cdn.bootcdn.net/ajax/libs/iview/3.5.5-rc.1/iview.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<style>
#app {
margin: 20px 40px;
}
</style>
</head>
<body>
<div id="app">
<h1>上传原型,获取永久在线浏览地址</h1>
<upload type="drag" action="/upload" paste="true" accept=".zip" :on-success="handleSuccess">
<div style="padding: 20px 0">
<icon type="ios-cloud-upload" size="52" style="color: #3399ff"></icon>
<p>点击或者拖拽上传</p>
</div>
</upload>
<alert type="success" v-for="url in zips">
浏览地址:${ url }
</alert>
<strong>历史prd:</strong>
<br><br>
<list border>
<list-item v-for="dir in dirs">
<a :href="dir.url" target="_blank">${ dir.name }</a> &nbsp;&nbsp; <span>${ dir.dateTime}</span>
</list-item>
</list>
</div>
<script>
new Vue({
el: "#app",
delimiters: ['${', '}'],
data: {
zips: [],
dirs: [],
},
methods: {
handleSuccess(response, file, fileList) {
this.zips.push(response.url)
}
},
created() {
axios.get("/dirs").then((res) => {
this.dirs = res.data.dirs
})
},
})
</script>
</body>
</html>