upgrade
This commit is contained in:
parent
24fb25692f
commit
98aa5b7de7
0
cmd/upgrade/build.sh
Normal file
0
cmd/upgrade/build.sh
Normal file
5
cmd/upgrade/build_linux.bat
Normal file
5
cmd/upgrade/build_linux.bat
Normal 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
167
cmd/upgrade/main.go
Normal 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
0
cmd/upgrade/readme.md
Normal file
125
cmd/upgrade/tools/gz.go
Normal file
125
cmd/upgrade/tools/gz.go
Normal 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
54
cmd/upgrade/tools/zip.go
Normal 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
|
||||||
|
}
|
69
cmd/upgrade/views/index.html
Normal file
69
cmd/upgrade/views/index.html
Normal 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> <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>
|
Loading…
Reference in New Issue
Block a user