From d0cf93d5e39d82d1d9ad30a73efafe78434ee2fb Mon Sep 17 00:00:00 2001 From: Jacky Date: Mon, 21 Apr 2025 08:06:27 +0000 Subject: [PATCH] refactor: replace upgrader with version package for runtime and release information --- api/cluster/node.go | 13 ++-- api/system/upgrade.go | 95 +++-------------------- internal/analytic/node.go | 25 +++--- internal/docker/ota.go | 4 +- internal/helper/docker.go | 11 +++ internal/upgrader/binary.go | 92 ++++++++++++++++++++++ internal/upgrader/docker.go | 19 +++++ internal/upgrader/upgrade.go | 36 ++++++--- internal/{upgrader => version}/info.go | 2 +- internal/{upgrader => version}/release.go | 2 +- settings/settings.go | 4 +- 11 files changed, 182 insertions(+), 121 deletions(-) create mode 100644 internal/helper/docker.go create mode 100644 internal/upgrader/binary.go create mode 100644 internal/upgrader/docker.go rename internal/{upgrader => version}/info.go (97%) rename internal/{upgrader => version}/release.go (99%) diff --git a/api/cluster/node.go b/api/cluster/node.go index 399bbec1..5fb131be 100644 --- a/api/cluster/node.go +++ b/api/cluster/node.go @@ -3,8 +3,7 @@ package cluster import ( "net/http" - analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic" - "github.com/0xJacky/Nginx-UI/internal/upgrader" + "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/version" "github.com/dustin/go-humanize" "github.com/gin-gonic/gin" @@ -21,17 +20,17 @@ func GetCurrentNode(c *gin.Context) { return } - runtimeInfo, err := upgrader.GetRuntimeInfo() + runtimeInfo, err := version.GetRuntimeInfo() if err != nil { cosy.ErrHandler(c, err) return } cpuInfo, _ := cpu.Info() - memory, _ := analytic2.GetMemoryStat() + memory, _ := analytic.GetMemoryStat() ver := version.GetVersionInfo() diskUsage, _ := disk.Usage(".") - nodeInfo := analytic2.NodeInfo{ + nodeInfo := analytic.NodeInfo{ NodeRuntimeInfo: runtimeInfo, CPUNum: len(cpuInfo), MemoryTotal: memory.Total, @@ -39,9 +38,9 @@ func GetCurrentNode(c *gin.Context) { Version: ver.Version, } - stat := analytic2.GetNodeStat() + stat := analytic.GetNodeStat() - c.JSON(http.StatusOK, analytic2.Node{ + c.JSON(http.StatusOK, analytic.Node{ NodeInfo: nodeInfo, NodeStat: stat, }) diff --git a/api/system/upgrade.go b/api/system/upgrade.go index 16257aa7..0f52cffd 100644 --- a/api/system/upgrade.go +++ b/api/system/upgrade.go @@ -2,11 +2,10 @@ package system import ( "net/http" - "os" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/version" - "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/uozi-tech/cosy" @@ -14,19 +13,19 @@ import ( ) func GetRelease(c *gin.Context) { - data, err := upgrader.GetRelease(c.Query("channel")) + data, err := version.GetRelease(c.Query("channel")) if err != nil { cosy.ErrHandler(c, err) return } - runtimeInfo, err := upgrader.GetRuntimeInfo() + runtimeInfo, err := version.GetRuntimeInfo() if err != nil { cosy.ErrHandler(c, err) return } type resp struct { - upgrader.TRelease - upgrader.RuntimeInfo + version.TRelease + version.RuntimeInfo } c.JSON(http.StatusOK, resp{ data, runtimeInfo, @@ -63,10 +62,7 @@ func PerformCoreUpgrade(c *gin.Context) { } defer ws.Close() - var control struct { - DryRun bool `json:"dry_run"` - Channel string `json:"channel"` - } + var control upgrader.Control err = ws.ReadJSON(&control) @@ -74,80 +70,9 @@ func PerformCoreUpgrade(c *gin.Context) { logger.Error(err) return } - - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Initialing core upgrader", - }) - - u, err := upgrader.NewUpgrader(control.Channel) - - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Initial core upgrader error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return - } - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Downloading latest release", - }) - progressChan := make(chan float64) - defer close(progressChan) - go func() { - for progress := range progressChan { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusProgress, - Progress: progress, - }) - } - }() - - tarName, err := u.DownloadLatestRelease(progressChan) - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Download latest release error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return - } - - defer func() { - _ = os.Remove(tarName) - _ = os.Remove(tarName + ".digest") - }() - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Performing core upgrade", - }) - // dry run - if control.DryRun || settings.NodeSettings.Demo { - return - } - - // bye, will restart nginx-ui in performCoreUpgrade - err = u.PerformCoreUpgrade(tarName) - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Perform core upgrade error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return + if helper.InNginxUIOfficialDocker() { + upgrader.DockerUpgrade(ws, &control) + } else { + upgrader.BinaryUpgrade(ws, &control) } } diff --git a/internal/analytic/node.go b/internal/analytic/node.go index a3ed6091..8839d4de 100644 --- a/internal/analytic/node.go +++ b/internal/analytic/node.go @@ -3,25 +3,26 @@ package analytic import ( "encoding/json" "errors" - "github.com/0xJacky/Nginx-UI/internal/transport" - "github.com/0xJacky/Nginx-UI/internal/upgrader" - "github.com/0xJacky/Nginx-UI/model" - "github.com/shirou/gopsutil/v4/load" - "github.com/shirou/gopsutil/v4/net" - "github.com/uozi-tech/cosy/logger" "io" "net/http" "net/url" "sync" "time" + + "github.com/0xJacky/Nginx-UI/internal/transport" + "github.com/0xJacky/Nginx-UI/internal/version" + "github.com/0xJacky/Nginx-UI/model" + "github.com/shirou/gopsutil/v4/load" + "github.com/shirou/gopsutil/v4/net" + "github.com/uozi-tech/cosy/logger" ) type NodeInfo struct { - NodeRuntimeInfo upgrader.RuntimeInfo `json:"node_runtime_info"` - Version string `json:"version"` - CPUNum int `json:"cpu_num"` - MemoryTotal string `json:"memory_total"` - DiskTotal string `json:"disk_total"` + NodeRuntimeInfo version.RuntimeInfo `json:"node_runtime_info"` + Version string `json:"version"` + CPUNum int `json:"cpu_num"` + MemoryTotal string `json:"memory_total"` + DiskTotal string `json:"disk_total"` } type NodeStat struct { @@ -77,7 +78,7 @@ func InitNode(env *model.Environment) (n *Node, err error) { u, err := url.JoinPath(env.URL, "/api/node") if err != nil { - return + return } t, err := transport.NewTransport() diff --git a/internal/docker/ota.go b/internal/docker/ota.go index c77b703f..632326b7 100644 --- a/internal/docker/ota.go +++ b/internal/docker/ota.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/0xJacky/Nginx-UI/internal/upgrader" + "github.com/0xJacky/Nginx-UI/internal/version" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/image" "github.com/docker/docker/client" @@ -58,7 +58,7 @@ func UpgradeStepOne(channel string) (err error) { ctx := context.Background() // 1. Get the tag of the latest release - release, err := upgrader.GetRelease(channel) + release, err := version.GetRelease(channel) if err != nil { return err } diff --git a/internal/helper/docker.go b/internal/helper/docker.go new file mode 100644 index 00000000..4bdb5556 --- /dev/null +++ b/internal/helper/docker.go @@ -0,0 +1,11 @@ +package helper + +import ( + "os" + + "github.com/spf13/cast" +) + +func InNginxUIOfficialDocker() bool { + return cast.ToBool(os.Getenv("NGINX_UI_OFFICIAL_DOCKER")) +} diff --git a/internal/upgrader/binary.go b/internal/upgrader/binary.go new file mode 100644 index 00000000..9c573b4a --- /dev/null +++ b/internal/upgrader/binary.go @@ -0,0 +1,92 @@ +package upgrader + +import ( + "os" + + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy/logger" +) + +type Control struct { + DryRun bool `json:"dry_run"` + Channel string `json:"channel"` +} + +func BinaryUpgrade(ws *websocket.Conn, control *Control) { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusInfo, + Message: "Initialing core upgrader", + }) + + u, err := NewUpgrader(control.Channel) + + if err != nil { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: "Initial core upgrader error", + }) + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: err.Error(), + }) + logger.Error(err) + return + } + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusInfo, + Message: "Downloading latest release", + }) + progressChan := make(chan float64) + defer close(progressChan) + go func() { + for progress := range progressChan { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusProgress, + Progress: progress, + }) + } + }() + + tarName, err := u.DownloadLatestRelease(progressChan) + if err != nil { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: "Download latest release error", + }) + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: err.Error(), + }) + logger.Error(err) + return + } + + defer func() { + _ = os.Remove(tarName) + _ = os.Remove(tarName + ".digest") + }() + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusInfo, + Message: "Performing core upgrade", + }) + // dry run + if control.DryRun || settings.NodeSettings.Demo { + return + } + + // bye, will restart nginx-ui in performCoreUpgrade + err = u.PerformCoreUpgrade(tarName) + if err != nil { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: "Perform core upgrade error", + }) + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: err.Error(), + }) + logger.Error(err) + return + } +} diff --git a/internal/upgrader/docker.go b/internal/upgrader/docker.go new file mode 100644 index 00000000..5755ff2d --- /dev/null +++ b/internal/upgrader/docker.go @@ -0,0 +1,19 @@ +package upgrader + +import ( + "github.com/0xJacky/Nginx-UI/internal/docker" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy/logger" +) + +func DockerUpgrade(ws *websocket.Conn, control *Control) { + err := docker.UpgradeStepOne(control.Channel) + if err != nil { + _ = ws.WriteJSON(CoreUpgradeResp{ + Status: UpgradeStatusError, + Message: err.Error(), + }) + logger.Error(err) + return + } +} diff --git a/internal/upgrader/upgrade.go b/internal/upgrader/upgrade.go index 6ce42e73..5007d899 100644 --- a/internal/upgrader/upgrade.go +++ b/internal/upgrader/upgrade.go @@ -3,13 +3,6 @@ package upgrader import ( "encoding/json" "fmt" - _github "github.com/0xJacky/Nginx-UI/.github" - "github.com/0xJacky/Nginx-UI/internal/helper" - "github.com/0xJacky/Nginx-UI/settings" - "github.com/jpillora/overseer" - "github.com/minio/selfupdate" - "github.com/pkg/errors" - "github.com/uozi-tech/cosy/logger" "io" "net/http" "net/url" @@ -18,19 +11,40 @@ import ( "strconv" "strings" "sync/atomic" + + _github "github.com/0xJacky/Nginx-UI/.github" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/version" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/jpillora/overseer" + "github.com/minio/selfupdate" + "github.com/pkg/errors" + "github.com/uozi-tech/cosy/logger" ) +const ( + UpgradeStatusInfo = "info" + UpgradeStatusError = "error" + UpgradeStatusProgress = "progress" +) + +type CoreUpgradeResp struct { + Status string `json:"status"` + Progress float64 `json:"progress"` + Message string `json:"message"` +} + type Upgrader struct { - Release TRelease - RuntimeInfo + Release version.TRelease + version.RuntimeInfo } func NewUpgrader(channel string) (u *Upgrader, err error) { - data, err := GetRelease(channel) + data, err := version.GetRelease(channel) if err != nil { return } - runtimeInfo, err := GetRuntimeInfo() + runtimeInfo, err := version.GetRuntimeInfo() if err != nil { return } diff --git a/internal/upgrader/info.go b/internal/version/info.go similarity index 97% rename from internal/upgrader/info.go rename to internal/version/info.go index 96252120..585db3cf 100644 --- a/internal/upgrader/info.go +++ b/internal/version/info.go @@ -1,4 +1,4 @@ -package upgrader +package version import ( "os" diff --git a/internal/upgrader/release.go b/internal/version/release.go similarity index 99% rename from internal/upgrader/release.go rename to internal/version/release.go index c5d711c3..463f80a7 100644 --- a/internal/upgrader/release.go +++ b/internal/version/release.go @@ -1,4 +1,4 @@ -package upgrader +package version import ( "encoding/json" diff --git a/settings/settings.go b/settings/settings.go index b2df2b47..4cefa7bb 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -2,10 +2,10 @@ package settings import ( "log" - "os" "strings" "time" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/caarlos0/env/v11" "github.com/elliotchance/orderedmap/v3" "github.com/spf13/cast" @@ -81,7 +81,7 @@ func Init(confPath string) { // if in official docker, set the restart cmd of nginx to "nginx -s stop", // then the supervisor of s6-overlay will start the nginx again. - if cast.ToBool(os.Getenv("NGINX_UI_OFFICIAL_DOCKER")) { + if helper.InNginxUIOfficialDocker() { NginxSettings.RestartCmd = "nginx -s stop" }