From 9e748a50df580ed450a7f38e2f0cb25fef0b7769 Mon Sep 17 00:00:00 2001 From: w-mj Date: Tue, 14 Mar 2023 21:31:12 +0800 Subject: [PATCH] first step on fork app --- go.mod | 1 + go.sum | 6 +++ src/controller/app_controller.go | 71 +++++++++++++++++++++++++------- src/model/app_model.go | 14 ++++++- src/utils.go | 17 ++++++++ 5 files changed, 92 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index f7f3825..9f47745 100644 --- a/go.mod +++ b/go.mod @@ -45,6 +45,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/otiai10/copy v1.9.0 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ugorji/go/codec v1.2.9 // indirect diff --git a/go.sum b/go.sum index e660d9c..6c38357 100644 --- a/go.sum +++ b/go.sum @@ -193,6 +193,12 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= +github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4= +github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.4.0/go.mod h1:gifjb2MYOoULtKLqUAEILUG/9KONW6f7YsJ6vQLTlFI= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= diff --git a/src/controller/app_controller.go b/src/controller/app_controller.go index 01b8732..81d2237 100644 --- a/src/controller/app_controller.go +++ b/src/controller/app_controller.go @@ -3,10 +3,13 @@ package controller import ( "encoding/json" "github.com/gin-gonic/gin" + cp "github.com/otiai10/copy" log "github.com/sirupsen/logrus" "github.com/thoas/go-funk" + k8s_manager "k8s-manager/src" "k8s-manager/src/model" "net/http" + "os" "strings" ) @@ -49,22 +52,22 @@ func statusString(a *AppViewModel) string { } } -func AppPage(c *gin.Context) { - c.File("template/app_view.html") -} - -func AppMiddleware(c *gin.Context) { - app := &model.AppModel{} - err := c.ShouldBindJSON(&app) - if err == nil { - username := c.MustGet("username") - if app.UserName != username { - c.JSON(http.StatusUnauthorized, gin.H{"msg": "user error."}) - c.Abort() - } - c.Set("app", app) - } -} +//func AppPage(c *gin.Context) { +// c.File("template/app_view.html") +//} +// +//func AppMiddleware(c *gin.Context) { +// app := &model.AppModel{} +// err := c.ShouldBindJSON(&app) +// if err == nil { +// username := c.MustGet("username") +// if app.UserName != username { +// c.JSON(http.StatusUnauthorized, gin.H{"msg": "user error."}) +// c.Abort() +// } +// c.Set("app", app) +// } +//} func CreateUpdateDeleteApp(c *gin.Context) { app := &model.AppModel{} @@ -114,3 +117,39 @@ func GetUsername(c *gin.Context) { username := c.MustGet("username").(string) c.JSON(http.StatusOK, gin.H{"username": username}) } + +func ForkApp(c *gin.Context) { + newApp := &model.AppModel{} + err := c.BindJSON(newApp) + if err != nil { + log.WithError(err).Error("ForkApp BindJson") + k8s_manager.GinError(c, http.StatusBadRequest, err.Error()) + return + } + originApp := &model.AppModel{Id: newApp.OriginId} + err = originApp.Fill() + if err != nil { + log.WithError(err).Error("ForkApp Fill") + k8s_manager.GinError(c, http.StatusBadRequest, err.Error()) + return + } + err = os.RemoveAll(newApp.NFSPath()) + if err != nil { + log.WithError(err).Error("ForkApp RemoveAll") + k8s_manager.GinError(c, http.StatusBadRequest, err.Error()) + return + } + err = cp.Copy(originApp.NFSPath(), newApp.NFSPath()) + if err != nil { + log.WithError(err).Error("ForkApp Copy") + k8s_manager.GinError(c, http.StatusBadRequest, err.Error()) + return + } + err = newApp.Create() + if err != nil { + log.WithError(err).Error("ForkApp Create") + k8s_manager.GinError(c, http.StatusBadRequest, err.Error()) + return + } + k8s_manager.GinOk(c, "ok") +} diff --git a/src/model/app_model.go b/src/model/app_model.go index ea068a4..9e9038f 100644 --- a/src/model/app_model.go +++ b/src/model/app_model.go @@ -5,6 +5,7 @@ import ( "k8s-manager/src" v1 "k8s.io/api/core/v1" "strings" + "time" "unicode" ) @@ -20,6 +21,10 @@ type AppModel struct { SvcRemovePrefix bool Ports string PersistentPath string + OriginId int + CreateTime time.Time + UpdateTime time.Time + IsPublished bool } func (*AppModel) TableName() string { @@ -51,6 +56,7 @@ func (a *AppModel) fillDefaults() { func (a *AppModel) Update() error { a.fillDefaults() + a.UpdateTime = time.Now() db := k8s_manager.DB() db.Save(a) return nil @@ -58,6 +64,8 @@ func (a *AppModel) Update() error { func (a *AppModel) Create() error { a.fillDefaults() + a.CreateTime = time.Now() + a.UpdateTime = time.Now() db := k8s_manager.DB() db.Create(a) return nil @@ -70,7 +78,11 @@ func (a *AppModel) Delete() error { } func (a *AppModel) NamePrefix() string { - prefix := fmt.Sprintf("%s-%s", a.UserName, a.AppName) + t := "app" + if a.OriginId > 0 { + t = "fork" + } + prefix := fmt.Sprintf("%s-%s-%s-%d", t, a.UserName, a.AppName, a.Id) ans := strings.Builder{} for _, c := range prefix { if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' { diff --git a/src/utils.go b/src/utils.go index d76b8cc..2bc8f72 100644 --- a/src/utils.go +++ b/src/utils.go @@ -1,5 +1,22 @@ package k8s_manager +import ( + "github.com/gin-gonic/gin" + "net/http" +) + func UnnamedPointer[T any](v T) *T { return &v } + +func GinError(c *gin.Context, code int, msg string) { + c.JSON(code, gin.H{"ok": false, "msg": msg}) +} + +func GinOk(c *gin.Context, msg string) { + c.JSON(http.StatusOK, gin.H{"ok": true, "msg": msg}) +} + +func GinOkData(c *gin.Context, data interface{}) { + c.JSON(http.StatusOK, gin.H{"ok": true, "data": data}) +}