diff --git a/api/nginx/control.go b/api/nginx/control.go index 04fba566..f6b492a7 100644 --- a/api/nginx/control.go +++ b/api/nginx/control.go @@ -4,6 +4,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/gin-gonic/gin" "net/http" + "os" ) func Reload(c *gin.Context) { @@ -23,9 +24,24 @@ func Test(c *gin.Context) { } func Restart(c *gin.Context) { - output := nginx.Restart() c.JSON(http.StatusOK, gin.H{ - "message": output, - "level": nginx.GetLogLevel(output), + "message": "ok", + }) + go nginx.Restart() +} + +func Status(c *gin.Context) { + pidPath := nginx.GetPIDPath() + lastOutput := nginx.GetLastOutput() + + running := true + if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 { // fileInfo.Size() == 0 no process id + running = false + } + + c.JSON(http.StatusOK, gin.H{ + "running": running, + "message": lastOutput, + "level": nginx.GetLogLevel(lastOutput), }) } diff --git a/api/nginx/nginx.go b/api/nginx/nginx.go index 551acf65..732a6dae 100644 --- a/api/nginx/nginx.go +++ b/api/nginx/nginx.go @@ -1,73 +1,59 @@ package nginx import ( - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/nginx" - "github.com/gin-gonic/gin" - "net/http" - "os" + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "net/http" ) func BuildNginxConfig(c *gin.Context) { - var ngxConf nginx.NgxConfig - if !api.BindAndValid(c, &ngxConf) { - return - } - content, err := ngxConf.BuildConfig() - if err != nil { - api.ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, gin.H{ - "content": content, - }) + var ngxConf nginx.NgxConfig + if !api.BindAndValid(c, &ngxConf) { + return + } + content, err := ngxConf.BuildConfig() + if err != nil { + api.ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, gin.H{ + "content": content, + }) } func TokenizeNginxConfig(c *gin.Context) { - var json struct { - Content string `json:"content" binding:"required"` - } + var json struct { + Content string `json:"content" binding:"required"` + } - if !api.BindAndValid(c, &json) { - return - } + if !api.BindAndValid(c, &json) { + return + } - ngxConfig, err := nginx.ParseNgxConfigByContent(json.Content) - if err != nil { - api.ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, ngxConfig) + ngxConfig, err := nginx.ParseNgxConfigByContent(json.Content) + if err != nil { + api.ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, ngxConfig) } func FormatNginxConfig(c *gin.Context) { - var json struct { - Content string `json:"content" binding:"required"` - } + var json struct { + Content string `json:"content" binding:"required"` + } - if !api.BindAndValid(c, &json) { - return - } - content, err := nginx.FmtCode(json.Content) - if err != nil { - api.ErrHandler(c, err) - return - } - c.JSON(http.StatusOK, gin.H{ - "content": content, - }) -} - -func Status(c *gin.Context) { - pidPath := nginx.GetPIDPath() - - running := true - if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 { // fileInfo.Size() == 0 no process id - running = false - } - - c.JSON(http.StatusOK, gin.H{ - "running": running, - }) + if !api.BindAndValid(c, &json) { + return + } + content, err := nginx.FmtCode(json.Content) + if err != nil { + api.ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, gin.H{ + "content": content, + }) } diff --git a/app/src/api/ngx.ts b/app/src/api/ngx.ts index bb76cbb6..dfc52eb7 100644 --- a/app/src/api/ngx.ts +++ b/app/src/api/ngx.ts @@ -46,7 +46,7 @@ const ngx = { return http.post('/ngx/format_code', { content }) }, - status(): Promise<{ running: boolean }> { + status(): Promise<{ running: boolean; message: string; level: number }> { return http.get('/nginx/status') }, diff --git a/app/src/components/NginxControl/NginxControl.vue b/app/src/components/NginxControl/NginxControl.vue index b9c6fcd8..9166ff0f 100644 --- a/app/src/components/NginxControl/NginxControl.vue +++ b/app/src/components/NginxControl/NginxControl.vue @@ -6,13 +6,14 @@ import { logLevel } from '@/views/config/constants' import { NginxStatus } from '@/constants' const status = ref(0) -function get_status() { - ngx.status().then(r => { - if (r?.running === true) - status.value = NginxStatus.Running - else - status.value = NginxStatus.Stopped - }) +async function get_status() { + const r = await ngx.status() + if (r?.running === true) + status.value = NginxStatus.Running + else + status.value = NginxStatus.Stopped + + return r } function reload_nginx() { @@ -29,9 +30,11 @@ function reload_nginx() { }).finally(() => get_status()) } -function restart_nginx() { +async function restart_nginx() { status.value = NginxStatus.Restarting - ngx.restart().then(r => { + await ngx.restart() + + get_status().then(r => { if (r.level < logLevel.Warn) message.success($gettext('Nginx restarted successfully')) else if (r.level === logLevel.Warn) @@ -40,7 +43,7 @@ function restart_nginx() { message.error(r.message) }).catch(e => { message.error(`${$gettext('Server error')} ${e?.message}`) - }).finally(() => get_status()) + }) } const visible = ref(false) diff --git a/internal/nginx/nginx.go b/internal/nginx/nginx.go index 6b06d245..e778b6cf 100644 --- a/internal/nginx/nginx.go +++ b/internal/nginx/nginx.go @@ -4,27 +4,13 @@ import ( "github.com/0xJacky/Nginx-UI/settings" "os/exec" "sync" + "time" ) -var mutex sync.Mutex - -func execShell(cmd string) (out string) { - bytes, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput() - out = string(bytes) - if err != nil { - out += " " + err.Error() - } - return -} - -func execCommand(name string, cmd ...string) (out string) { - bytes, err := exec.Command(name, cmd...).CombinedOutput() - out = string(bytes) - if err != nil { - out += " " + err.Error() - } - return -} +var ( + mutex sync.Mutex + lastOutput string +) func TestConf() (out string) { mutex.Lock() @@ -53,11 +39,15 @@ func Reload() (out string) { return } -func Restart() (out string) { +func Restart() { mutex.Lock() defer mutex.Unlock() + + // fix(docker): nginx restart always output network error + time.Sleep(500 * time.Millisecond) + if settings.NginxSettings.RestartCmd != "" { - out = execShell(settings.NginxSettings.RestartCmd) + lastOutput = execShell(settings.NginxSettings.RestartCmd) return } @@ -65,15 +55,39 @@ func Restart() (out string) { pidPath := GetPIDPath() daemon := GetSbinPath() - out = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath) + lastOutput = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath) if daemon == "" { - out += execCommand("nginx") + lastOutput += execCommand("nginx") return } - out += execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon) + lastOutput += execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon) return } + +func GetLastOutput() string { + mutex.Lock() + defer mutex.Unlock() + return lastOutput +} + +func execShell(cmd string) (out string) { + bytes, err := exec.Command("/bin/sh", "-c", cmd).CombinedOutput() + out = string(bytes) + if err != nil { + out += " " + err.Error() + } + return +} + +func execCommand(name string, cmd ...string) (out string) { + bytes, err := exec.Command(name, cmd...).CombinedOutput() + out = string(bytes) + if err != nil { + out += " " + err.Error() + } + return +}