diff --git a/frontend/components.d.ts b/frontend/components.d.ts
index de4b86c2..c592fc84 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -8,6 +8,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
+ ABadge: typeof import('ant-design-vue/es')['Badge']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
AButton: typeof import('ant-design-vue/es')['Button']
@@ -37,6 +38,7 @@ declare module '@vue/runtime-core' {
AModal: typeof import('ant-design-vue/es')['Modal']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
+ APopover: typeof import('ant-design-vue/es')['Popover']
AProgress: typeof import('ant-design-vue/es')['Progress']
AResult: typeof import('ant-design-vue/es')['Result']
ARow: typeof import('ant-design-vue/es')['Row']
@@ -59,6 +61,7 @@ declare module '@vue/runtime-core' {
CodeEditorCodeEditor: typeof import('./src/components/CodeEditor/CodeEditor.vue')['default']
FooterToolbarFooterToolBar: typeof import('./src/components/FooterToolbar/FooterToolBar.vue')['default']
LogoLogo: typeof import('./src/components/Logo/Logo.vue')['default']
+ NginxControlNginxControl: typeof import('./src/components/NginxControl/NginxControl.vue')['default']
PageHeaderPageHeader: typeof import('./src/components/PageHeader/PageHeader.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
diff --git a/frontend/package.json b/frontend/package.json
index 61deabf1..f1b04bdc 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -32,9 +32,9 @@
"vue3-apexcharts": "^1.4.1",
"vue3-gettext": "^2.3.4",
"vuedraggable": "^4.1.0",
- "xterm": "^5.0.0",
- "xterm-addon-attach": "^0.7.0",
- "xterm-addon-fit": "^0.6.0"
+ "xterm": "^5.1.0",
+ "xterm-addon-attach": "^0.8.0",
+ "xterm-addon-fit": "^0.7.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.0.0",
diff --git a/frontend/src/api/ngx.ts b/frontend/src/api/ngx.ts
index 5a2e32e2..62e3db1b 100644
--- a/frontend/src/api/ngx.ts
+++ b/frontend/src/api/ngx.ts
@@ -13,10 +13,18 @@ const ngx = {
return http.post('/ngx/format_code', {content})
},
+ status() {
+ return http.get('/nginx/status')
+ },
+
reload() {
return http.post('/nginx/reload')
},
+ restart() {
+ return http.post('/nginx/restart')
+ },
+
test() {
return http.post('/nginx/test')
}
diff --git a/frontend/src/components/NginxControl/NginxControl.vue b/frontend/src/components/NginxControl/NginxControl.vue
new file mode 100644
index 00000000..a544dc45
--- /dev/null
+++ b/frontend/src/components/NginxControl/NginxControl.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
{{ $gettext('Nginx Control') }}
+
+
+
+
+
+
+ {{ $gettext('Restart') }}
+ {{ $gettext('Reload') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/layouts/HeaderLayout.vue b/frontend/src/layouts/HeaderLayout.vue
index 943657af..8b94e18c 100644
--- a/frontend/src/layouts/HeaderLayout.vue
+++ b/frontend/src/layouts/HeaderLayout.vue
@@ -3,10 +3,9 @@ import SetLanguage from '@/components/SetLanguage/SetLanguage.vue'
import gettext from '@/gettext'
import {message} from 'ant-design-vue'
import auth from '@/api/auth'
-import {HomeOutlined, LogoutOutlined, MenuUnfoldOutlined, ReloadOutlined} from '@ant-design/icons-vue'
+import {HomeOutlined, LogoutOutlined, MenuUnfoldOutlined} from '@ant-design/icons-vue'
import {useRouter} from 'vue-router'
-import ngx from '@/api/ngx'
-import logLevel from '@/views/config/constants'
+import NginxControl from '@/components/NginxControl/NginxControl.vue'
const {$gettext} = gettext
@@ -19,20 +18,6 @@ function logout() {
router.push('/login')
})
}
-
-function reload_nginx() {
- ngx.reload().then(r => {
- if (r.level < logLevel.Warn) {
- message.success($gettext('Nginx reloaded successfully'))
- } else if (r.level === logLevel.Warn) {
- message.warn(r.message)
- } else {
- message.error(r.message)
- }
- }).catch(e => {
- message.error($gettext('Server error') + ' ' + e?.message)
- })
-}
@@ -48,17 +33,7 @@ function reload_nginx() {
-
-
-
-
-
+
diff --git a/frontend/src/lib/http/index.ts b/frontend/src/lib/http/index.ts
index 1527f171..a5a2721d 100644
--- a/frontend/src/lib/http/index.ts
+++ b/frontend/src/lib/http/index.ts
@@ -1,6 +1,8 @@
import axios, {AxiosRequestConfig} from 'axios'
import {useUserStore} from '@/pinia'
import {storeToRefs} from 'pinia'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
import router from '@/routes'
@@ -25,6 +27,7 @@ let instance = axios.create({
instance.interceptors.request.use(
config => {
+ NProgress.start()
if (token) {
(config.headers as any).Authorization = token.value
}
@@ -37,9 +40,11 @@ instance.interceptors.request.use(
instance.interceptors.response.use(
response => {
+ NProgress.done()
return Promise.resolve(response.data)
},
async error => {
+ NProgress.done()
switch (error.response.status) {
case 401:
case 403:
diff --git a/frontend/src/version.json b/frontend/src/version.json
index e82ef0c9..fc8c8d79 100644
--- a/frontend/src/version.json
+++ b/frontend/src/version.json
@@ -1 +1 @@
-{"version":"1.7.5","build_id":77,"total_build":147}
\ No newline at end of file
+{"version":"1.7.5","build_id":81,"total_build":151}
\ No newline at end of file
diff --git a/frontend/src/views/pty/Terminal.vue b/frontend/src/views/pty/Terminal.vue
index 62143072..c6742a39 100644
--- a/frontend/src/views/pty/Terminal.vue
+++ b/frontend/src/views/pty/Terminal.vue
@@ -35,14 +35,13 @@ const fit = _.throttle(function () {
function initTerm() {
term = new Terminal({
- rendererType: 'canvas',
convertEol: true,
fontSize: 14,
cursorStyle: 'block',
scrollback: 1000,
theme: {
- background: '#000',
- },
+ background: '#000'
+ }
})
term.loadAddon(fitAddon)
diff --git a/frontend/version.json b/frontend/version.json
index e82ef0c9..fc8c8d79 100644
--- a/frontend/version.json
+++ b/frontend/version.json
@@ -1 +1 @@
-{"version":"1.7.5","build_id":77,"total_build":147}
\ No newline at end of file
+{"version":"1.7.5","build_id":81,"total_build":151}
\ No newline at end of file
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 3174b87a..ab338993 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -3019,20 +3019,20 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-xterm-addon-attach@^0.7.0:
+xterm-addon-attach@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/xterm-addon-attach/-/xterm-addon-attach-0.8.0.tgz#86e0ed08460efffb7d4bad74a57b600226594def"
+ integrity sha512-k8N5boSYn6rMJTTNCgFpiSTZ26qnYJf3v/nJJYexNO2sdAHDN3m1ivVQWVZ8CHJKKnZQw1rc44YP2NtgalWHfQ==
+
+xterm-addon-fit@^0.7.0:
version "0.7.0"
- resolved "https://registry.yarnpkg.com/xterm-addon-attach/-/xterm-addon-attach-0.7.0.tgz#6775b3c5f1e9f91ae4cd9089f5ecb49fda8d2946"
- integrity sha512-Yh3Kvq2e28onjnmGizQKZwlRMp9gmuZEHVX0BVZbo463YSjkqfhQS3T2wMLuO+j8AokccXsMa1z0bH1/+MMYuQ==
+ resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.7.0.tgz#b8ade6d96e63b47443862088f6670b49fb752c6a"
+ integrity sha512-tQgHGoHqRTgeROPnvmtEJywLKoC/V9eNs4bLLz7iyJr1aW/QFzRwfd3MGiJ6odJd9xEfxcW36/xRU47JkD5NKQ==
-xterm-addon-fit@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.6.0.tgz#142e1ce181da48763668332593fc440349c88c34"
- integrity sha512-9/7A+1KEjkFam0yxTaHfuk9LEvvTSBi0PZmEkzJqgafXPEXL9pCMAVV7rB09sX6ATRDXAdBpQhZkhKj7CGvYeg==
-
-xterm@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0.tgz#0af50509b33d0dc62fde7a4ec17750b8e453cc5c"
- integrity sha512-tmVsKzZovAYNDIaUinfz+VDclraQpPUnAME+JawosgWRMphInDded/PuY0xmU5dOhyeYZsI0nz5yd8dPYsdLTA==
+xterm@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.1.0.tgz#3e160d60e6801c864b55adf19171c49d2ff2b4fc"
+ integrity sha512-LovENH4WDzpwynj+OTkLyZgJPeDom9Gra4DMlGAgz6pZhIDCQ+YuO7yfwanY+gVbn/mmZIStNOnVRU/ikQuAEQ==
yallist@^3.0.2:
version "3.1.1"
diff --git a/server/api/ngx.go b/server/api/ngx.go
index da43f80f..f39eca8d 100644
--- a/server/api/ngx.go
+++ b/server/api/ngx.go
@@ -4,6 +4,7 @@ import (
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/gin-gonic/gin"
"net/http"
+ "os"
)
func BuildNginxConfig(c *gin.Context) {
@@ -48,6 +49,19 @@ func FormatNginxConfig(c *gin.Context) {
})
}
+func NginxStatus(c *gin.Context) {
+ pidPath := nginx.GetNginxPIDPath()
+
+ running := true
+ if _, err := os.Stat(pidPath); err != nil {
+ running = false
+ }
+
+ c.JSON(http.StatusOK, gin.H{
+ "running": running,
+ })
+}
+
func ReloadNginx(c *gin.Context) {
output := nginx.Reload()
@@ -65,3 +79,12 @@ func TestNginx(c *gin.Context) {
"level": nginx.GetLogLevel(output),
})
}
+
+func RestartNginx(c *gin.Context) {
+ output := nginx.Restart()
+
+ c.JSON(http.StatusOK, gin.H{
+ "message": output,
+ "level": nginx.GetLogLevel(output),
+ })
+}
diff --git a/server/pkg/nginx/nginx.go b/server/pkg/nginx/nginx.go
index daac985f..b40fc8f0 100644
--- a/server/pkg/nginx/nginx.go
+++ b/server/pkg/nginx/nginx.go
@@ -27,8 +27,17 @@ func Reload() string {
return string(out)
}
-func GetConfPath(dir ...string) string {
+func Restart() string {
+ out, err := exec.Command("nginx", "-s", "reopen").CombinedOutput()
+ if err != nil {
+ log.Println("[error] nginx.Restart", err)
+ }
+
+ return string(out)
+}
+
+func GetConfPath(dir ...string) string {
var confPath string
if settings.ServerSettings.NginxConfigDir == "" {
@@ -50,3 +59,26 @@ func GetConfPath(dir ...string) string {
return filepath.Join(confPath, filepath.Join(dir...))
}
+
+func GetNginxPIDPath() string {
+ var confPath string
+
+ if settings.ServerSettings.NginxPIDPath == "" {
+ out, err := exec.Command("nginx", "-V").CombinedOutput()
+ if err != nil {
+ log.Println("nginx.GetNginxPIDPath exec.Command error", err)
+ return ""
+ }
+ r, _ := regexp.Compile("--pid-path=(.*.pid)")
+ match := r.FindStringSubmatch(string(out))
+ if len(match) < 1 {
+ log.Println("nginx.GetNginxPIDPath len(match) < 1")
+ return ""
+ }
+ confPath = r.FindStringSubmatch(string(out))[1]
+ } else {
+ confPath = settings.ServerSettings.NginxPIDPath
+ }
+
+ return confPath
+}
diff --git a/server/router/routers.go b/server/router/routers.go
index 879c27d4..92bf07ff 100644
--- a/server/router/routers.go
+++ b/server/router/routers.go
@@ -64,8 +64,12 @@ func InitRouter() *gin.Engine {
g.POST("ngx/format_code", api.FormatNginxConfig)
// nginx reload
g.POST("nginx/reload", api.ReloadNginx)
+ // nginx restart
+ g.POST("nginx/restart", api.RestartNginx)
// nginx test
g.POST("nginx/test", api.TestNginx)
+ // nginx status
+ g.GET("nginx/status", api.NginxStatus)
g.POST("domain/:name/enable", api.EnableDomain)
g.POST("domain/:name/disable", api.DisableDomain)
diff --git a/server/settings/settings.go b/server/settings/settings.go
index 02657b1f..aaad7dc8 100644
--- a/server/settings/settings.go
+++ b/server/settings/settings.go
@@ -28,6 +28,7 @@ type Server struct {
PageSize int `json:"page_size"`
GithubProxy string `json:"github_proxy"`
NginxConfigDir string `json:"nginx_config_dir"`
+ NginxPIDPath string `json:"nginx_pid_path"`
}
type NginxLog struct {