From f5a0a9ed50e196fb7142eb4314a94f0fcab05ed7 Mon Sep 17 00:00:00 2001 From: Jacky Date: Sun, 21 Jul 2024 23:16:28 +0800 Subject: [PATCH] enhance(upgrader): gracefully replace the old exe with the new exe --- api/system/upgrade.go | 3 +- app/src/components/ChatGPT/ChatGPT.vue | 1 - app/src/version.json | 2 +- app/src/views/environment/Environment.vue | 5 + app/src/views/system/Upgrade.vue | 7 +- app/version.json | 2 +- go.mod | 2 + go.sum | 9 + internal/helper/tar.go | 2 +- internal/upgrader/info.go | 59 +++++++ internal/upgrader/release.go | 109 ++++++++++++ internal/upgrader/upgrade.go | 206 +++++----------------- router/routers.go | 130 +++++++------- 13 files changed, 304 insertions(+), 233 deletions(-) create mode 100644 internal/upgrader/info.go create mode 100644 internal/upgrader/release.go diff --git a/api/system/upgrade.go b/api/system/upgrade.go index 131572d2..cc125588 100644 --- a/api/system/upgrade.go +++ b/api/system/upgrade.go @@ -139,9 +139,8 @@ func PerformCoreUpgrade(c *gin.Context) { return } - _ = os.Remove(u.ExPath) // bye, overseer will restart nginx-ui - err = u.PerformCoreUpgrade(u.ExPath, tarName) + err = u.PerformCoreUpgrade(tarName) if err != nil { _ = ws.WriteJSON(CoreUpgradeResp{ Status: UpgradeStatusError, diff --git a/app/src/components/ChatGPT/ChatGPT.vue b/app/src/components/ChatGPT/ChatGPT.vue index f34d7d5d..1ff0c2be 100644 --- a/app/src/components/ChatGPT/ChatGPT.vue +++ b/app/src/components/ChatGPT/ChatGPT.vue @@ -143,7 +143,6 @@ async function send() { messages.value = [] if (messages.value.length === 0) { - console.log(current.value) messages.value.push({ role: 'user', content: `${props.content}\n\nCurrent Language Code: ${current.value}`, diff --git a/app/src/version.json b/app/src/version.json index 77eb052d..167f8a6a 100644 --- a/app/src/version.json +++ b/app/src/version.json @@ -1 +1 @@ -{"version":"2.0.0-beta.26","build_id":142,"total_build":346} \ No newline at end of file +{"version":"2.0.0-beta.26","build_id":144,"total_build":348} \ No newline at end of file diff --git a/app/src/views/environment/Environment.vue b/app/src/views/environment/Environment.vue index 6c06f580..9cdad234 100644 --- a/app/src/views/environment/Environment.vue +++ b/app/src/views/environment/Environment.vue @@ -30,6 +30,11 @@ const columns: Column[] = [{ }, }, }, +{ + title: () => $gettext('Version'), + dataIndex: 'version', + pithy: true, +}, { title: () => 'NodeSecret', dataIndex: 'token', diff --git a/app/src/views/system/Upgrade.vue b/app/src/views/system/Upgrade.vue index b8f5f264..92f0541a 100644 --- a/app/src/views/system/Upgrade.vue +++ b/app/src/views/system/Upgrade.vue @@ -95,7 +95,6 @@ async function perform_upgrade() { const r = JSON.parse(m.data) if (r.message) log(r.message) - console.log(r.status) switch (r.status) { case 'info': progressPercent.value += 10 @@ -115,6 +114,12 @@ async function perform_upgrade() { } } + ws.onerror = () => { + is_fail = true + progressStatus.value = 'exception' + modalClosable.value = true + } + ws.onclose = async () => { if (is_fail) return diff --git a/app/version.json b/app/version.json index 77eb052d..167f8a6a 100644 --- a/app/version.json +++ b/app/version.json @@ -1 +1 @@ -{"version":"2.0.0-beta.26","build_id":142,"total_build":346} \ No newline at end of file +{"version":"2.0.0-beta.26","build_id":144,"total_build":348} \ No newline at end of file diff --git a/go.mod b/go.mod index e5482bbc..94b3c1ee 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( ) require ( + aead.dev/minisign v0.3.0 // indirect cloud.google.com/go/auth v0.7.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect @@ -183,6 +184,7 @@ require ( github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/miekg/dns v1.1.61 // indirect github.com/mimuret/golang-iij-dpf v0.9.1 // indirect + github.com/minio/selfupdate v0.6.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index a1706158..bd6f3c3f 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ= +aead.dev/minisign v0.3.0 h1:8Xafzy5PEVZqYDNP60yJHARlW1eOQtsKNp/Ph2c0vRA= +aead.dev/minisign v0.3.0/go.mod h1:NLvG3Uoq3skkRMDuc3YHpWUTMTrSExqm+Ij73W13F6Y= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -1338,6 +1341,8 @@ github.com/mimuret/golang-iij-dpf v0.9.1 h1:Gj6EhHJkOhr+q2RnvRPJsPMcjuVnWPSccEHy github.com/mimuret/golang-iij-dpf v0.9.1/go.mod h1:sl9KyOkESib9+KRD3HaGpgi1xk7eoN2+d96LCLsME2M= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= +github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU= +github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -1731,9 +1736,11 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1993,6 +2000,7 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2050,6 +2058,7 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/internal/helper/tar.go b/internal/helper/tar.go index f1c15eed..2b07da1d 100644 --- a/internal/helper/tar.go +++ b/internal/helper/tar.go @@ -54,7 +54,7 @@ func UnTar(dst, src string) (err error) { return errors.Wrap(err, "unTar os.OpenFile error") } defer file.Close() - _, err = file.Seek(0, os.SEEK_END) + _, err = file.Seek(0, io.SeekEnd) if err != nil { return errors.Wrap(err, "unTar file.Truncate(0) error") } diff --git a/internal/upgrader/info.go b/internal/upgrader/info.go new file mode 100644 index 00000000..6d536b1a --- /dev/null +++ b/internal/upgrader/info.go @@ -0,0 +1,59 @@ +package upgrader + +import ( + "encoding/json" + "github.com/0xJacky/Nginx-UI/app" + "github.com/pkg/errors" + "os" + "path/filepath" + "runtime" +) + +type RuntimeInfo struct { + OS string `json:"os"` + Arch string `json:"arch"` + ExPath string `json:"ex_path"` +} + +type CurVersion struct { + Version string `json:"version"` + BuildID int `json:"build_id"` + TotalBuild int `json:"total_build"` +} + +func GetRuntimeInfo() (r RuntimeInfo, err error) { + ex, err := os.Executable() + if err != nil { + err = errors.Wrap(err, "service.GetRuntimeInfo os.Executable() err") + return + } + realPath, err := filepath.EvalSymlinks(ex) + if err != nil { + err = errors.Wrap(err, "service.GetRuntimeInfo filepath.EvalSymlinks() err") + return + } + + r = RuntimeInfo{ + OS: runtime.GOOS, + Arch: runtime.GOARCH, + ExPath: realPath, + } + + return +} + +func GetCurrentVersion() (c CurVersion, err error) { + verJson, err := app.DistFS.ReadFile("dist/version.json") + if err != nil { + err = errors.Wrap(err, "service.GetCurrentVersion ReadFile err") + return + } + + err = json.Unmarshal(verJson, &c) + if err != nil { + err = errors.Wrap(err, "service.GetCurrentVersion json.Unmarshal err") + return + } + + return +} diff --git a/internal/upgrader/release.go b/internal/upgrader/release.go new file mode 100644 index 00000000..94b74769 --- /dev/null +++ b/internal/upgrader/release.go @@ -0,0 +1,109 @@ +package upgrader + +import ( + "encoding/json" + "github.com/pkg/errors" + "io" + "net/http" + "time" +) + +const ( + GithubLatestReleaseAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases/latest" + GithubReleasesListAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases" +) + +type TReleaseAsset struct { + Name string `json:"name"` + BrowserDownloadUrl string `json:"browser_download_url"` + Size uint `json:"size"` +} + +type TRelease struct { + TagName string `json:"tag_name"` + Name string `json:"name"` + PublishedAt time.Time `json:"published_at"` + Body string `json:"body"` + Prerelease bool `json:"prerelease"` + Assets []TReleaseAsset `json:"assets"` +} + +func (t *TRelease) GetAssetsMap() (m map[string]TReleaseAsset) { + m = make(map[string]TReleaseAsset) + for _, v := range t.Assets { + m[v.Name] = v + } + return +} + +func getLatestRelease() (data TRelease, err error) { + resp, err := http.Get(GithubLatestReleaseAPI) + if err != nil { + err = errors.Wrap(err, "service.getLatestRelease http.Get err") + return + } + body, err := io.ReadAll(resp.Body) + if err != nil { + err = errors.Wrap(err, "service.getLatestRelease io.ReadAll err") + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + err = errors.New(string(body)) + return + } + err = json.Unmarshal(body, &data) + if err != nil { + err = errors.Wrap(err, "service.getLatestRelease json.Unmarshal err") + return + } + return +} + +func getLatestPrerelease() (data TRelease, err error) { + resp, err := http.Get(GithubReleasesListAPI) + if err != nil { + err = errors.Wrap(err, "service.getLatestPrerelease http.Get err") + return + } + body, err := io.ReadAll(resp.Body) + if err != nil { + err = errors.Wrap(err, "service.getLatestPrerelease io.ReadAll err") + return + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + err = errors.New(string(body)) + return + } + + var releaseList []TRelease + + err = json.Unmarshal(body, &releaseList) + if err != nil { + err = errors.Wrap(err, "service.getLatestPrerelease json.Unmarshal err") + return + } + + latestDate := time.Time{} + + for _, release := range releaseList { + if release.Prerelease && release.PublishedAt.After(latestDate) { + data = release + latestDate = release.PublishedAt + } + } + + return +} + +func GetRelease(channel string) (data TRelease, err error) { + switch channel { + default: + fallthrough + case "stable": + return getLatestRelease() + case "prerelease": + return getLatestPrerelease() + } +} diff --git a/internal/upgrader/upgrade.go b/internal/upgrader/upgrade.go index d75d4938..4631c48d 100644 --- a/internal/upgrader/upgrade.go +++ b/internal/upgrader/upgrade.go @@ -4,171 +4,21 @@ import ( "encoding/json" "fmt" _github "github.com/0xJacky/Nginx-UI/.github" - "github.com/0xJacky/Nginx-UI/app" "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/settings" + "github.com/minio/selfupdate" "github.com/pkg/errors" "io" "net/http" "net/url" "os" "path/filepath" - "runtime" "strconv" "strings" - "time" + "sync/atomic" ) -const ( - GithubLatestReleaseAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases/latest" - GithubReleasesListAPI = "https://api.github.com/repos/0xJacky/nginx-ui/releases" -) - -type RuntimeInfo struct { - OS string `json:"os"` - Arch string `json:"arch"` - ExPath string `json:"ex_path"` -} - -func GetRuntimeInfo() (r RuntimeInfo, err error) { - ex, err := os.Executable() - if err != nil { - err = errors.Wrap(err, "service.GetRuntimeInfo os.Executable() err") - return - } - realPath, err := filepath.EvalSymlinks(ex) - if err != nil { - err = errors.Wrap(err, "service.GetRuntimeInfo filepath.EvalSymlinks() err") - return - } - - r = RuntimeInfo{ - OS: runtime.GOOS, - Arch: runtime.GOARCH, - ExPath: realPath, - } - - return -} - -type TReleaseAsset struct { - Name string `json:"name"` - BrowserDownloadUrl string `json:"browser_download_url"` - Size uint `json:"size"` -} - -type TRelease struct { - TagName string `json:"tag_name"` - Name string `json:"name"` - PublishedAt time.Time `json:"published_at"` - Body string `json:"body"` - Prerelease bool `json:"prerelease"` - Assets []TReleaseAsset `json:"assets"` -} - -func (t *TRelease) GetAssetsMap() (m map[string]TReleaseAsset) { - m = make(map[string]TReleaseAsset) - for _, v := range t.Assets { - m[v.Name] = v - } - return -} - -func getLatestRelease() (data TRelease, err error) { - resp, err := http.Get(GithubLatestReleaseAPI) - if err != nil { - err = errors.Wrap(err, "service.getLatestRelease http.Get err") - return - } - body, err := io.ReadAll(resp.Body) - if err != nil { - err = errors.Wrap(err, "service.getLatestRelease io.ReadAll err") - return - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - err = errors.New(string(body)) - return - } - err = json.Unmarshal(body, &data) - if err != nil { - err = errors.Wrap(err, "service.getLatestRelease json.Unmarshal err") - return - } - return -} - -func getLatestPrerelease() (data TRelease, err error) { - resp, err := http.Get(GithubReleasesListAPI) - if err != nil { - err = errors.Wrap(err, "service.getLatestPrerelease http.Get err") - return - } - body, err := io.ReadAll(resp.Body) - if err != nil { - err = errors.Wrap(err, "service.getLatestPrerelease io.ReadAll err") - return - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - err = errors.New(string(body)) - return - } - - var releaseList []TRelease - - err = json.Unmarshal(body, &releaseList) - if err != nil { - err = errors.Wrap(err, "service.getLatestPrerelease json.Unmarshal err") - return - } - - latestDate := time.Time{} - - for _, release := range releaseList { - if release.Prerelease && release.PublishedAt.After(latestDate) { - data = release - latestDate = release.PublishedAt - } - } - - return -} - -func GetRelease(channel string) (data TRelease, err error) { - switch channel { - default: - fallthrough - case "stable": - return getLatestRelease() - case "prerelease": - return getLatestPrerelease() - } -} - -type CurVersion struct { - Version string `json:"version"` - BuildID int `json:"build_id"` - TotalBuild int `json:"total_build"` -} - -func GetCurrentVersion() (c CurVersion, err error) { - verJson, err := app.DistFS.ReadFile("dist/version.json") - if err != nil { - err = errors.Wrap(err, "service.GetCurrentVersion ReadFile err") - return - } - - err = json.Unmarshal(verJson, &c) - if err != nil { - err = errors.Wrap(err, "service.GetCurrentVersion json.Unmarshal err") - return - } - - return -} - type Upgrader struct { Release TRelease RuntimeInfo @@ -350,23 +200,57 @@ func (u *Upgrader) DownloadLatestRelease(progressChan chan float64) (tarName str return } -func (u *Upgrader) PerformCoreUpgrade(exPath string, tarPath string) (err error) { - dir := filepath.Dir(exPath) - err = helper.UnTar(dir, tarPath) +var updateInProgress atomic.Bool + +func (u *Upgrader) PerformCoreUpgrade(tarPath string) (err error) { + if !updateInProgress.CompareAndSwap(false, true) { + return errors.New("update already in progress") + } + defer updateInProgress.Store(false) + + opts := selfupdate.Options{} + + if err = opts.CheckPermissions(); err != nil { + return err + } + + tempDir, err := os.MkdirTemp("", "nginx-ui-upgrade-*") + if err != nil { + return err + } + defer os.RemoveAll(tempDir) + + err = helper.UnTar(tempDir, tarPath) if err != nil { err = errors.Wrap(err, "PerformCoreUpgrade unTar error") return } - err = os.Rename(filepath.Join(dir, "nginx-ui"), exPath) + + f, err := os.Open(filepath.Join(tempDir, "nginx-ui")) if err != nil { - err = errors.Wrap(err, "PerformCoreUpgrade rename error") + err = errors.Wrap(err, "PerformCoreUpgrade open error") return } + defer f.Close() + + if err = selfupdate.PrepareAndCheckBinary(f, opts); err != nil { + var pathErr *os.PathError + if errors.As(err, &pathErr) { + return pathErr.Err + } + return err + } - err = os.Remove(tarPath) - if err != nil { - err = errors.Wrap(err, "PerformCoreUpgrade remove tar error") - return + if err = selfupdate.CommitBinary(opts); err != nil { + if rerr := selfupdate.RollbackError(err); rerr != nil { + return rerr + } + var pathErr *os.PathError + if errors.As(err, &pathErr) { + return pathErr.Err + } + return err } + return } diff --git a/router/routers.go b/router/routers.go index 599a497b..eb15a257 100644 --- a/router/routers.go +++ b/router/routers.go @@ -1,79 +1,79 @@ package router import ( - "github.com/0xJacky/Nginx-UI/api/analytic" - "github.com/0xJacky/Nginx-UI/api/certificate" - "github.com/0xJacky/Nginx-UI/api/cluster" - "github.com/0xJacky/Nginx-UI/api/config" - "github.com/0xJacky/Nginx-UI/api/nginx" - "github.com/0xJacky/Nginx-UI/api/notification" - "github.com/0xJacky/Nginx-UI/api/openai" - "github.com/0xJacky/Nginx-UI/api/settings" - "github.com/0xJacky/Nginx-UI/api/sites" - "github.com/0xJacky/Nginx-UI/api/streams" - "github.com/0xJacky/Nginx-UI/api/system" - "github.com/0xJacky/Nginx-UI/api/template" - "github.com/0xJacky/Nginx-UI/api/terminal" - "github.com/0xJacky/Nginx-UI/api/upstream" - "github.com/0xJacky/Nginx-UI/api/user" - "github.com/gin-contrib/static" - "github.com/gin-gonic/gin" - "net/http" + "github.com/0xJacky/Nginx-UI/api/analytic" + "github.com/0xJacky/Nginx-UI/api/certificate" + "github.com/0xJacky/Nginx-UI/api/cluster" + "github.com/0xJacky/Nginx-UI/api/config" + "github.com/0xJacky/Nginx-UI/api/nginx" + "github.com/0xJacky/Nginx-UI/api/notification" + "github.com/0xJacky/Nginx-UI/api/openai" + "github.com/0xJacky/Nginx-UI/api/settings" + "github.com/0xJacky/Nginx-UI/api/sites" + "github.com/0xJacky/Nginx-UI/api/streams" + "github.com/0xJacky/Nginx-UI/api/system" + "github.com/0xJacky/Nginx-UI/api/template" + "github.com/0xJacky/Nginx-UI/api/terminal" + "github.com/0xJacky/Nginx-UI/api/upstream" + "github.com/0xJacky/Nginx-UI/api/user" + "github.com/gin-contrib/static" + "github.com/gin-gonic/gin" + "net/http" ) func InitRouter() *gin.Engine { - r := gin.New() - r.Use(gin.Logger()) - r.Use(recovery()) - r.Use(cacheJs()) - r.Use(ipWhiteList()) + r := gin.New() + r.Use(gin.Logger()) + r.Use(recovery()) + r.Use(cacheJs()) + r.Use(ipWhiteList()) - //r.Use(OperationSync()) + //r.Use(OperationSync()) - r.Use(static.Serve("/", mustFS(""))) + r.Use(static.Serve("/", mustFS(""))) - r.NoRoute(func(c *gin.Context) { - c.JSON(http.StatusNotFound, gin.H{ - "message": "not found", - }) - }) + r.NoRoute(func(c *gin.Context) { + c.JSON(http.StatusNotFound, gin.H{ + "message": "not found", + }) + }) - root := r.Group("/api") - { - system.InitPublicRouter(root) - user.InitAuthRouter(root) + root := r.Group("/api") + { + system.InitPublicRouter(root) + user.InitAuthRouter(root) - // Authorization required not websocket request - g := root.Group("/", authRequired(), proxy()) - { - analytic.InitRouter(g) - user.InitManageUserRouter(g) - nginx.InitRouter(g) - sites.InitRouter(g) - streams.InitRouter(g) - config.InitRouter(g) - template.InitRouter(g) - certificate.InitCertificateRouter(g) - certificate.InitDNSCredentialRouter(g) - certificate.InitAcmeUserRouter(g) - system.InitPrivateRouter(g) - settings.InitRouter(g) - openai.InitRouter(g) - cluster.InitRouter(g) - notification.InitRouter(g) - } + // Authorization required not websocket request + g := root.Group("/", authRequired(), proxy()) + { + analytic.InitRouter(g) + user.InitManageUserRouter(g) + nginx.InitRouter(g) + sites.InitRouter(g) + streams.InitRouter(g) + config.InitRouter(g) + template.InitRouter(g) + certificate.InitCertificateRouter(g) + certificate.InitDNSCredentialRouter(g) + certificate.InitAcmeUserRouter(g) + system.InitPrivateRouter(g) + settings.InitRouter(g) + openai.InitRouter(g) + cluster.InitRouter(g) + notification.InitRouter(g) + } - // Authorization required and websocket request - w := root.Group("/", authRequired(), proxyWs()) - { - analytic.InitWebSocketRouter(w) - certificate.InitCertificateWebSocketRouter(w) - terminal.InitRouter(w) - nginx.InitNginxLogRouter(w) - upstream.InitRouter(w) - system.InitWebSocketRouter(w) - } - } + // Authorization required and websocket request + w := root.Group("/", authRequired(), proxyWs()) + { + analytic.InitWebSocketRouter(w) + certificate.InitCertificateWebSocketRouter(w) + terminal.InitRouter(w) + nginx.InitNginxLogRouter(w) + upstream.InitRouter(w) + system.InitWebSocketRouter(w) + } + } - return r + return r }