Compare commits

...
10 Commits
Author SHA1 Message Date
nap0o 96c3fd433f feat: status-server主题增加套餐信息展示 (#464)
* feat: status-server主题增加套餐信息展示
1. 首页通过在后台配置PublicNote字段,实现agent套餐信息展示
2. 一些其他小优化

* 1.未获取agent国家时,默认彩虹旗修改为联合国旗
2024-11-01 21:28:14 +08:00
github-actions[bot] 45b0f1edfc update contributors[no ci] 2024-10-30 16:15:58 +00:00
Moraxyc 61fdcd2a9e fix(cli): display version before init app (#463) 2024-10-31 00:15:41 +08:00
UUBulb a474b8484b ddns: replace tencentcloud implemention (#462) 2024-10-29 21:39:45 +08:00
UUBulb 67b003a27d installer: fix download service scripts (#449) 2024-10-22 13:02:54 +08:00
UUBulb 99aeda7939 installer: fix format (#448) 2024-10-22 10:25:31 +08:00
UUBulb d5744d0c73 fix installer (#442)
* fix installer

* version
2024-10-20 00:33:28 +08:00
UUBulb e7837d8eaf installer: fix some style issues (#441)
* installer: fix some style issues

* translate

* translate

* replace cf-ns
2024-10-19 22:03:00 +08:00
UUBulb aa81fc02ab fix: add custom theme key (#440) 2024-10-19 11:59:31 +08:00
UUBulb f6531a52bd ddns: remove ipv6 nameservers, support custom nameservers (#439) 2024-10-18 22:06:01 +08:00
26 changed files with 481 additions and 265 deletions
+2 -1
View File
@@ -4,7 +4,7 @@
<br> <br>
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small> <small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
<br><br> <br><br>
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard">&nbsp;<img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github">&nbsp;<img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge">&nbsp;<img src="https://img.shields.io/badge/Installer-v0.19.2-brightgreen?style=for-the-badge&logo=linux"> <img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard">&nbsp;<img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github">&nbsp;<img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge">&nbsp;<img src="https://img.shields.io/badge/Installer-v0.20.2-brightgreen?style=for-the-badge&logo=linux">
<br> <br>
<br> <br>
<p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p> <p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p>
@@ -84,6 +84,7 @@ You can change the dashboard language in the settings page (`/setting`) after th
<a href="https://github.com/IamTaoChen" title="Tao Chen"><img src="https://avatars.githubusercontent.com/u/42793494?v=4" width="50;" alt="Tao Chen"/></a> <a href="https://github.com/IamTaoChen" title="Tao Chen"><img src="https://avatars.githubusercontent.com/u/42793494?v=4" width="50;" alt="Tao Chen"/></a>
<a href="https://github.com/Septrum101" title="Spetrum"><img src="https://avatars.githubusercontent.com/u/11692994?v=4" width="50;" alt="Spetrum"/></a> <a href="https://github.com/Septrum101" title="Spetrum"><img src="https://avatars.githubusercontent.com/u/11692994?v=4" width="50;" alt="Spetrum"/></a>
<a href="https://github.com/dreamingsleeping" title="Nanjing Hopefun Network Technology Co. Ltd."><img src="https://avatars.githubusercontent.com/u/13828658?v=4" width="50;" alt="Nanjing Hopefun Network Technology Co. Ltd."/></a> <a href="https://github.com/dreamingsleeping" title="Nanjing Hopefun Network Technology Co. Ltd."><img src="https://avatars.githubusercontent.com/u/13828658?v=4" width="50;" alt="Nanjing Hopefun Network Technology Co. Ltd."/></a>
<a href="https://github.com/Moraxyc" title="Moraxyc"><img src="https://avatars.githubusercontent.com/u/69713071?v=4" width="50;" alt="Moraxyc"/></a>
<a href="https://github.com/silver-ymz" title="Mingzhuo Yin"><img src="https://avatars.githubusercontent.com/u/78400701?v=4" width="50;" alt="Mingzhuo Yin"/></a> <a href="https://github.com/silver-ymz" title="Mingzhuo Yin"><img src="https://avatars.githubusercontent.com/u/78400701?v=4" width="50;" alt="Mingzhuo Yin"/></a>
<a href="https://github.com/MartijnLindeman" title="Martijn Lindeman"><img src="https://avatars.githubusercontent.com/u/78365708?v=4" width="50;" alt="Martijn Lindeman"/></a> <a href="https://github.com/MartijnLindeman" title="Martijn Lindeman"><img src="https://avatars.githubusercontent.com/u/78365708?v=4" width="50;" alt="Martijn Lindeman"/></a>
<a href="https://github.com/xrgzs" title="MadDogOwner"><img src="https://avatars.githubusercontent.com/u/26499123?v=4" width="50;" alt="MadDogOwner"/></a> <a href="https://github.com/xrgzs" title="MadDogOwner"><img src="https://avatars.githubusercontent.com/u/26499123?v=4" width="50;" alt="MadDogOwner"/></a>
+4
View File
@@ -1012,6 +1012,7 @@ type settingForm struct {
DashboardTheme string DashboardTheme string
CustomCode string CustomCode string
CustomCodeDashboard string CustomCodeDashboard string
CustomNameservers string
ViewPassword string ViewPassword string
IgnoredIPNotification string IgnoredIPNotification string
IPChangeNotificationTag string // IP变更提醒的通知组 IPChangeNotificationTag string // IP变更提醒的通知组
@@ -1078,6 +1079,7 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
singleton.Conf.Site.DashboardTheme = sf.DashboardTheme singleton.Conf.Site.DashboardTheme = sf.DashboardTheme
singleton.Conf.Site.CustomCode = sf.CustomCode singleton.Conf.Site.CustomCode = sf.CustomCode
singleton.Conf.Site.CustomCodeDashboard = sf.CustomCodeDashboard singleton.Conf.Site.CustomCodeDashboard = sf.CustomCodeDashboard
singleton.Conf.DNSServers = sf.CustomNameservers
singleton.Conf.Site.ViewPassword = sf.ViewPassword singleton.Conf.Site.ViewPassword = sf.ViewPassword
singleton.Conf.Oauth2.Admin = sf.Admin singleton.Conf.Oauth2.Admin = sf.Admin
// 保证NotificationTag不为空 // 保证NotificationTag不为空
@@ -1093,6 +1095,8 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
} }
// 更新系统语言 // 更新系统语言
singleton.InitLocalizer() singleton.InitLocalizer()
// 更新DNS服务器
singleton.OnNameserverUpdate()
c.JSON(http.StatusOK, model.Response{ c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK, Code: http.StatusOK,
}) })
+9 -8
View File
@@ -1,6 +1,7 @@
package main package main
import ( import (
"os"
"context" "context"
"fmt" "fmt"
"log" "log"
@@ -32,13 +33,6 @@ func init() {
flag.StringVarP(&dashboardCliParam.ConfigFile, "config", "c", "data/config.yaml", "配置文件路径") flag.StringVarP(&dashboardCliParam.ConfigFile, "config", "c", "data/config.yaml", "配置文件路径")
flag.StringVar(&dashboardCliParam.DatebaseLocation, "db", "data/sqlite.db", "Sqlite3数据库文件路径") flag.StringVar(&dashboardCliParam.DatebaseLocation, "db", "data/sqlite.db", "Sqlite3数据库文件路径")
flag.Parse() flag.Parse()
// 初始化 dao 包
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
singleton.InitTimezoneAndCache()
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)
singleton.InitLocalizer()
initSystem()
} }
func initSystem() { func initSystem() {
@@ -59,9 +53,16 @@ func initSystem() {
func main() { func main() {
if dashboardCliParam.Version { if dashboardCliParam.Version {
fmt.Println(singleton.Version) fmt.Println(singleton.Version)
return os.Exit(0)
} }
// 初始化 dao 包
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
singleton.InitTimezoneAndCache()
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)
singleton.InitLocalizer()
initSystem()
// TODO 使用 cmux 在同一端口服务 HTTP 和 gRPC // TODO 使用 cmux 在同一端口服务 HTTP 和 gRPC
singleton.CleanMonitorHistory() singleton.CleanMonitorHistory()
go rpc.ServeRPC(singleton.Conf.GRPCPort) go rpc.ServeRPC(singleton.Conf.GRPCPort)
+2 -2
View File
@@ -16,8 +16,8 @@ require (
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/libdns/cloudflare v0.1.1 github.com/libdns/cloudflare v0.1.1
github.com/libdns/libdns v0.2.2 github.com/libdns/libdns v0.2.2
github.com/libdns/tencentcloud v1.0.0
github.com/miekg/dns v1.1.62 github.com/miekg/dns v1.1.62
github.com/nezhahq/libdns-tencentcloud v0.0.0-20241029120103-889957240fff
github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/ory/graceful v0.1.3 github.com/ory/graceful v0.1.3
github.com/oschwald/maxminddb-golang v1.13.1 github.com/oschwald/maxminddb-golang v1.13.1
@@ -75,9 +75,9 @@ require (
github.com/spf13/afero v1.11.0 // indirect github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cast v1.6.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.597 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect github.com/ugorji/go/codec v1.2.11 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
+5 -4
View File
@@ -111,8 +111,6 @@ github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn0
github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU= github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU=
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/libdns/tencentcloud v1.0.0 h1:u4LXnYu/lu/9P5W+MCVPeSDnwI+6w+DxYhQ1wSnQOuU=
github.com/libdns/tencentcloud v1.0.0/go.mod h1:NlCgPumzUsZWSOo1+Q/Hfh8G6TNRAaTUeWQdg6LbtUI=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -131,6 +129,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nezhahq/libdns-tencentcloud v0.0.0-20241029120103-889957240fff h1:3WDsbsg3dmsRENYLUPGPTkEcWWmTvk41i+rM91AIIbY=
github.com/nezhahq/libdns-tencentcloud v0.0.0-20241029120103-889957240fff/go.mod h1:k+cDtTbUY+UV56Aqv4Ahmc9bWmhpga9JJXZlAIPKBEc=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
@@ -188,14 +188,15 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.597 h1:C0GHdLTfikLVoEzfhgPfrZ7LwlG0xiCmk6iwNKE+xs0= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.597/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
+3
View File
@@ -23,6 +23,7 @@ var Themes = map[string]string{
"hotaru": "Hotaru", "hotaru": "Hotaru",
"angel-kanade": "AngelKanade", "angel-kanade": "AngelKanade",
"server-status": "ServerStatus", "server-status": "ServerStatus",
"custom": "Custom(local)",
} }
var DashboardThemes = map[string]string{ var DashboardThemes = map[string]string{
@@ -125,6 +126,8 @@ type Config struct {
IgnoredIPNotificationServerIDs map[uint64]bool // [ServerID] -> bool(值为true代表当前ServerID在特定服务器列表内) IgnoredIPNotificationServerIDs map[uint64]bool // [ServerID] -> bool(值为true代表当前ServerID在特定服务器列表内)
MaxTCPPingValue int32 MaxTCPPingValue int32
AvgPingCount int AvgPingCount int
DNSServers string
} }
// Read 读取配置文件并应用 // Read 读取配置文件并应用
+17 -2
View File
@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"log" "log"
"strings"
"time" "time"
"github.com/libdns/libdns" "github.com/libdns/libdns"
@@ -13,7 +14,10 @@ import (
"github.com/naiba/nezha/pkg/utils" "github.com/naiba/nezha/pkg/utils"
) )
var dnsTimeOut = 10 * time.Second var (
dnsTimeOut = 10 * time.Second
customDNSServers []string
)
type IP struct { type IP struct {
Ipv4Addr string Ipv4Addr string
@@ -33,6 +37,12 @@ type Provider struct {
Setter libdns.RecordSetter Setter libdns.RecordSetter
} }
func InitDNSServers(s string) {
if s != "" {
customDNSServers = strings.Split(s, ",")
}
}
func (provider *Provider) UpdateDomain(ctx context.Context) { func (provider *Provider) UpdateDomain(ctx context.Context) {
provider.ctx = ctx provider.ctx = ctx
for _, domain := range provider.DDNSProfile.Domains { for _, domain := range provider.DDNSProfile.Domains {
@@ -95,12 +105,17 @@ func splitDomainSOA(domain string) (prefix string, zone string, err error) {
domain += "." domain += "."
indexes := dns.Split(domain) indexes := dns.Split(domain)
servers := utils.DNSServers
if len(customDNSServers) > 0 {
servers = customDNSServers
}
var r *dns.Msg var r *dns.Msg
for _, idx := range indexes { for _, idx := range indexes {
m := new(dns.Msg) m := new(dns.Msg)
m.SetQuestion(domain[idx:], dns.TypeSOA) m.SetQuestion(domain[idx:], dns.TypeSOA)
for _, server := range utils.DNSServers { for _, server := range servers {
r, _, err = c.Exchange(m, server) r, _, err = c.Exchange(m, server)
if err != nil { if err != nil {
return return
+1 -1
View File
@@ -13,7 +13,7 @@ import (
var ( var (
Json = jsoniter.ConfigCompatibleWithStandardLibrary Json = jsoniter.ConfigCompatibleWithStandardLibrary
DNSServers = []string{"1.1.1.1:53", "223.5.5.5:53", "[2606:4700:4700::1111]:53", "[2400:3200::1]:53"} DNSServers = []string{"1.1.1.1:53", "223.5.5.5:53"}
) )
func IsWindows() bool { func IsWindows() bool {
+6
View File
@@ -747,3 +747,9 @@ other = "Expired"
[Days] [Days]
other = "d" other = "d"
[CustomNameservers]
other = "Custom Public DNS Nameservers for DDNS (separate with comma)"
[Plan]
other = "Plan"
+6
View File
@@ -747,3 +747,9 @@ other = "Expired"
[Days] [Days]
other = "d" other = "d"
[CustomNameservers]
other = "Servidores DNS públicos personalizados para DDNS (separar con coma)"
[Plan]
other = "Plan"
+6
View File
@@ -747,3 +747,9 @@ other = "已到期"
[Days] [Days]
other = "天" other = "天"
[CustomNameservers]
other = "自定义DDNS使用的公共DNS服务器(逗号分隔)"
[Plan]
other = "套餐"
+6
View File
@@ -747,3 +747,9 @@ other = "已到期"
[Days] [Days]
other = "天" other = "天"
[CustomNameservers]
other = "自訂DDNS使用的公共DNS伺服器(逗號分隔)"
[Plan]
other = "套餐"
+5
View File
@@ -90,6 +90,11 @@ body[theme="dark"] .table > tbody > tr.expandRow.odd > td:before {
body[theme="dark"] .table > tbody > tr.expandRow.even > td:before { body[theme="dark"] .table > tbody > tr.expandRow.even > td:before {
background-color: rgba(28, 29, 38, 1); background-color: rgba(28, 29, 38, 1);
} }
body[theme="dark"] .plan {
background-image: none;
background-color: rgba(255, 255, 255, 0.075);
}
/* expandRow展开部分样式结束 */ /* expandRow展开部分样式结束 */
body[theme="dark"] .progress { body[theme="dark"] .progress {
+7
View File
@@ -116,6 +116,13 @@ body[theme="light"] tr.odd.expandRow > :hover {
background: #ffffff !important; background: #ffffff !important;
} }
body[theme="light"] .plan {
color: #000000;
background-color: #f5f5f5;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
}
body[theme="light"] .progress-bar { body[theme="light"] .progress-bar {
color: #000000; color: #000000;
} }
@@ -104,6 +104,11 @@ body[theme="light"] .table > tbody > tr.expandRow.odd > td:before {
body[theme="light"] .table > tbody > tr.expandRow.even > td:before { body[theme="light"] .table > tbody > tr.expandRow.even > td:before {
background-color: unset; background-color: unset;
} }
body[theme="light"] .plan {
background-image: none;
background-color: rgba(0, 0, 0, 0.015);
}
/* expandRow展开部分样式结束 */ /* expandRow展开部分样式结束 */
body[theme="light"] .progress { body[theme="light"] .progress {
+19
View File
@@ -268,6 +268,22 @@ tr.accordion-toggle{
font-size: 80%; font-size: 80%;
} }
.plan {
display: inline-block;
font-size: 85%;
margin-right: 2px;
padding: 2px 5px;
border-radius: 2px;
}
.network-route, .extra {
margin-right: 6px;
}
.last {
margin-right: 2px;
}
.temp-detail { .temp-detail {
cursor: pointer; cursor: pointer;
} }
@@ -557,6 +573,9 @@ footer p {
min-width: 75px; min-width: 75px;
max-width: 75px; max-width: 75px;
} }
.plan {
display: inline;
}
.accordian-body { .accordian-body {
margin: 5px 0px 5px 10px; margin: 5px 0px 5px 10px;
} }
+4
View File
@@ -53,6 +53,10 @@
<label>{{tr "PanelServerDomainAndIP"}}</label> <label>{{tr "PanelServerDomainAndIP"}}</label>
<input type="text" name="GRPCHost" placeholder="" value="{{.Conf.GRPCHost}}"> <input type="text" name="GRPCHost" placeholder="" value="{{.Conf.GRPCHost}}">
</div> </div>
<div class="field">
<label>{{tr "CustomNameservers"}}</label>
<input type="text" name="CustomNameservers" placeholder="" value="{{.Conf.DNSServers}}">
</div>
<div class="field"> <div class="field">
<label>{{tr "IPChangeAlert"}}</label> <label>{{tr "IPChangeAlert"}}</label>
</div> </div>
+3 -3
View File
@@ -26,9 +26,9 @@
<script src="https://unpkg.com/[email protected]/dist/js/bootstrap.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/echarts.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/echarts.min.js"></script>
<link rel="stylesheet" href="/static/theme-server-status/css/main.css?v20241008"> <link rel="stylesheet" href="/static/theme-server-status/css/main.css?v20241029">
<link rel="stylesheet" href="/static/theme-server-status/css/dark.css?v20241008"> <link rel="stylesheet" href="/static/theme-server-status/css/dark.css?v20241029">
<link rel="stylesheet" href="/static/theme-server-status/css/light.css?v20241008"> <link rel="stylesheet" href="/static/theme-server-status/css/light.css?v20241029">
<script src="/static/theme-server-status/js/mixin.js?v20240915"></script> <script src="/static/theme-server-status/js/mixin.js?v20240915"></script>
</head> </head>
<body> <body>
+41 -2
View File
@@ -35,8 +35,8 @@
<span class="node-cell-os-text">@#getPlatformName(node.os) === '' && node.stateuptime > 0 ? 'linux' : getPlatformName(node.os)#@</span> <span class="node-cell-os-text">@#getPlatformName(node.os) === '' && node.stateuptime > 0 ? 'linux' : getPlatformName(node.os)#@</span>
</td> </td>
<td class="node-cell location center"> <td class="node-cell location center">
<i :class="'fi fi-' + (node.stateuptime > 0 ? (node.location || 'rb') : '')"></i> <i :class="'fi fi-' + (node.stateuptime > 0 ? (node.location || 'un') : '')"></i>
<span class="node-cell-location-text text-uppercase">@#node.stateuptime > 0 ? (node.location || 'RB') : ''#@</span> <span class="node-cell-location-text text-uppercase">@#node.stateuptime > 0 ? (node.location || 'UN') : ''#@</span>
</td> </td>
<td v-if="nodesNoTag.some(item => item.additional && item.additional.price && Object.keys(item.additional.price).length > 0)" class="node-cell price center"> <td v-if="nodesNoTag.some(item => item.additional && item.additional.price && Object.keys(item.additional.price).length > 0)" class="node-cell price center">
<template v-if="node.additional && node.additional.price"> <template v-if="node.additional && node.additional.price">
@@ -88,6 +88,45 @@
<td colspan="16"> <td colspan="16">
<div class="accordian-body collapse" :id="'rt'+node.ID"> <div class="accordian-body collapse" :id="'rt'+node.ID">
<div style="display: flex;left-items: center;justify-content: center;flex-direction: column; max-width: 89vw"> <div style="display: flex;left-items: center;justify-content: center;flex-direction: column; max-width: 89vw">
<span v-if="node.additional && Object.keys(node.additional.plan).length > 0" class="node-cell-expand">
<span class="node-cell-expand-label">{{tr "Plan"}}:</span>
<span v-if="node.additional && Object.keys(node.additional.price).length > 0" class="plan price">
<span v-if="node.additional.price.amount == 0">FREE</span>
<span v-else-if="node.additional.price.amount == -1">PAYG</span>
<span v-else><i class="bi bi-cash-stack"></i> @#node.additional.price.amount#@@#(node.additional.price.cycle ? '/' + node.additional.price.cycle : '')#@</span>
</span>
<span v-if="node.additional && node.additional.remaining.endDate" class="plan enddate">
<i class="bi bi-clock-history"></i>
<span v-if="node.additional.remaining.days == 'lifetime'">{{tr "Lifetime"}}</span>
<span v-else-if="node.additional.remaining.days < 0">{{tr "Expired"}}</span>
<span v-else>@#node.additional.remaining.endDate.toISOString().split('T')[0]#@</span>
</span>
<span v-if="node.additional && node.additional.plan.bandwidth" class="plan bandwidth">
<i class="bi bi-speedometer2"></i>
<span>@#node.additional.plan.bandwidth#@</span>
</span>
<span v-if="node.additional && node.additional.plan.trafficVol" class="plan traffic">
<i v-if="node.additional && node.additional.plan.trafficType == 1" class="bi bi-arrow-up"></i>
<i v-else class="bi bi-arrow-down-up"></i>
<span>@#node.additional.plan.trafficVol#@</span>
</span>
<span v-if="node.additional && node.additional.plan.ipv4" class="plan ipv4">
<span>IPv4</span>
</span>
<span v-if="node.additional && node.additional.plan.ipv6" class="plan ipv6">
<span>IPv6</span>
</span>
<template v-if="node.additional && node.additional.plan.networkRoute.length>0" v-for="(item, index) in node.additional.plan.networkRoute" :key="index">
<span class="plan network-route" :class="{ last: index === node.additional.plan.networkRoute.length - 1 }">
<span>@#item#@</span>
</span>
</template>
<template v-if="node.additional && node.additional.plan.extra.length>0" v-for="(item, index) in node.additional.plan.extra" :key="index">
<span class="plan extra" :class="{ last: index === node.additional.plan.extra.length - 1 }">
<span>@#item#@</span>
</span>
</template>
</span>
<span class="node-cell-expand"> <span class="node-cell-expand">
<span class="node-cell-expand-label">{{tr "Platform"}}:</span> <span class="node-cell-expand-label">{{tr "Platform"}}:</span>
<span v-if="node.host.Platform">@#node.host.Platform#@@#node.host.PlatformVersion ? '-' + node.host.PlatformVersion : ''#@</span> <span v-if="node.host.Platform">@#node.host.Platform#@@#node.host.PlatformVersion ? '-' + node.host.PlatformVersion : ''#@</span>
+41 -2
View File
@@ -38,8 +38,8 @@
<span class="node-cell-os-text">@#getPlatformName(node.os) === '' && node.stateuptime > 0 ? 'linux' : getPlatformName(node.os)#@</span> <span class="node-cell-os-text">@#getPlatformName(node.os) === '' && node.stateuptime > 0 ? 'linux' : getPlatformName(node.os)#@</span>
</td> </td>
<td class="node-cell location center"> <td class="node-cell location center">
<i :class="'fi fi-' + (node.stateuptime > 0 ? (node.location || 'rb') : '')"></i> <i :class="'fi fi-' + (node.stateuptime > 0 ? (node.location || 'un') : '')"></i>
<span class="node-cell-location-text text-uppercase">@#node.stateuptime > 0 ? (node.location || 'RB') : ''#@</span> <span class="node-cell-location-text text-uppercase">@#node.stateuptime > 0 ? (node.location || 'UN') : ''#@</span>
</td> </td>
<td v-if="group.data.some(item => item.additional && item.additional.price && Object.keys(item.additional.price).length > 0)" class="node-cell price center"> <td v-if="group.data.some(item => item.additional && item.additional.price && Object.keys(item.additional.price).length > 0)" class="node-cell price center">
<template v-if="node.additional && node.additional.price"> <template v-if="node.additional && node.additional.price">
@@ -91,6 +91,45 @@
<td colspan="16"> <td colspan="16">
<div class="accordian-body collapse" :id="'rt'+node.ID"> <div class="accordian-body collapse" :id="'rt'+node.ID">
<div style="display: flex;left-items: center;justify-content: center;flex-direction: column; max-width: 89vw"> <div style="display: flex;left-items: center;justify-content: center;flex-direction: column; max-width: 89vw">
<span v-if="node.additional && Object.keys(node.additional.plan).length > 0" class="node-cell-expand">
<span class="node-cell-expand-label">{{tr "Plan"}}:</span>
<span v-if="node.additional && Object.keys(node.additional.price).length > 0" class="plan price">
<span v-if="node.additional.price.amount == 0">FREE</span>
<span v-else-if="node.additional.price.amount == -1">PAYG</span>
<span v-else><i class="bi bi-cash-stack"></i> @#node.additional.price.amount#@@#(node.additional.price.cycle ? '/' + node.additional.price.cycle : '')#@</span>
</span>
<span v-if="node.additional && node.additional.remaining.endDate" class="plan enddate">
<i class="bi bi-clock-history"></i>
<span v-if="node.additional.remaining.days == 'lifetime'">{{tr "Lifetime"}}</span>
<span v-else-if="node.additional.remaining.days < 0">{{tr "Expired"}}</span>
<span v-else>@#node.additional.remaining.endDate.toISOString().split('T')[0]#@</span>
</span>
<span v-if="node.additional && node.additional.plan.bandwidth" class="plan bandwidth">
<i class="bi bi-speedometer2"></i>
<span>@#node.additional.plan.bandwidth#@</span>
</span>
<span v-if="node.additional && node.additional.plan.trafficVol" class="plan traffic">
<i v-if="node.additional && node.additional.plan.trafficType == 1" class="bi bi-arrow-up"></i>
<i v-else class="bi bi-arrow-down-up"></i>
<span>@#node.additional.plan.trafficVol#@</span>
</span>
<span v-if="node.additional && node.additional.plan.ipv4" class="plan ipv4">
<span>IPv4</span>
</span>
<span v-if="node.additional && node.additional.plan.ipv6" class="plan ipv6">
<span>IPv6</span>
</span>
<template v-if="node.additional && node.additional.plan.networkRoute.length>0" v-for="(item, index) in node.additional.plan.networkRoute" :key="index">
<span class="plan network-route" :class="{ last: index === node.additional.plan.networkRoute.length - 1 }">
<span>@#item#@</span>
</span>
</template>
<template v-if="node.additional && node.additional.plan.extra.length>0" v-for="(item, index) in node.additional.plan.extra" :key="index">
<span class="plan extra" :class="{ last: index === node.additional.plan.extra.length - 1 }">
<span>@#item#@</span>
</span>
</template>
</span>
<span class="node-cell-expand"> <span class="node-cell-expand">
<span class="node-cell-expand-label">{{tr "Platform"}}:</span> <span class="node-cell-expand-label">{{tr "Platform"}}:</span>
<span v-if="node.host.Platform">@#node.host.Platform#@@#node.host.PlatformVersion ? '-' + node.host.PlatformVersion : ''#@</span> <span v-if="node.host.Platform">@#node.host.Platform#@@#node.host.PlatformVersion ? '-' + node.host.PlatformVersion : ''#@</span>
+52 -38
View File
@@ -117,43 +117,54 @@
initAdditional(servers) { initAdditional(servers) {
let nodes = {}; let nodes = {};
servers?.forEach(server => { servers?.forEach(server => {
if (server.PublicNote) { //处理异常
const remainingFormat = this.getRemainingFormat(server.live, server.PublicNote); if (!server.PublicNote) return;
const remainingDays = this.getRemainingDays(this.getNoteElementValue(server.PublicNote, "billingDataMod", "endDate"), server.PublicNote);
const remainingPercent = this.getRemainingPercent(
this.getNoteElementValue(server.PublicNote, "billingDataMod", "startDate"),
this.getNoteElementValue(server.PublicNote, "billingDataMod", "endDate"),
server.PublicNote
);
const priceAmount = this.getNoteElementValue(server.PublicNote, "billingDataMod", "amount");
const priceCycle = this.getNoteElementValue(server.PublicNote, "billingDataMod", "cycle");
// 初始化节点 // 初始化节点
nodes[server.ID] = { nodes[server.ID] = {
"remaining": {}, "remaining": {},
"price": {} "price": {},
}; "plan": {}
};
if (remainingFormat) { // 处理 billingDataMod 的 remaining 配置
nodes[server.ID].remaining.format = remainingFormat; const remainingEndDate = this.getRemainingDays(this.getNoteElementValue(server.PublicNote, "billingDataMod", "endDate"), server.PublicNote, 1);
} const remainingFormat = this.getRemainingFormat(server.live, server.PublicNote);
const remainingDays = this.getRemainingDays(this.getNoteElementValue(server.PublicNote, "billingDataMod", "endDate"), server.PublicNote);
const remainingPercent = this.getRemainingPercent(
this.getNoteElementValue(server.PublicNote, "billingDataMod", "startDate"),
this.getNoteElementValue(server.PublicNote, "billingDataMod", "endDate"),
server.PublicNote
);
// 设置 remaining 属性
if (remainingEndDate) nodes[server.ID].remaining.endDate = remainingEndDate;
if (remainingFormat) nodes[server.ID].remaining.format = remainingFormat;
if (remainingDays) nodes[server.ID].remaining.days = remainingDays;
if (remainingPercent) nodes[server.ID].remaining.percent = this.toFixed2(100 - remainingPercent);
if (remainingDays) { // 处理 billingDataMod 的 price 配置
nodes[server.ID].remaining.days = remainingDays; const priceAmount = this.getNoteElementValue(server.PublicNote, "billingDataMod", "amount");
} const priceCycle = this.getNoteElementValue(server.PublicNote, "billingDataMod", "cycle");
// 设置 price 属性
if (remainingPercent) { if (priceAmount) nodes[server.ID].price.amount = priceAmount;
nodes[server.ID].remaining.percent = this.toFixed2(100 - remainingPercent); if (priceCycle && priceAmount) nodes[server.ID].price.cycle = priceCycle;
}
// 处理 planDataMod 配置
if (priceAmount) { const planBandwidth = this.getNoteElementValue(server.PublicNote, "planDataMod", "bandwidth");
nodes[server.ID].price.amount = priceAmount; const planTrafficVol = this.getNoteElementValue(server.PublicNote, "planDataMod", "trafficVol");
} const planTrafficType = this.getNoteElementValue(server.PublicNote, "planDataMod", "trafficType");
const planIPv4 = this.getNoteElementValue(server.PublicNote, "planDataMod", "IPv4");
if (priceCycle && priceAmount) { const planIPv6 = this.getNoteElementValue(server.PublicNote, "planDataMod", "IPv6");
nodes[server.ID].price.cycle = priceCycle; const planNetworkRoute = this.getNoteElementValue(server.PublicNote, "planDataMod", "networkRoute");
} const planExtra = this.getNoteElementValue(server.PublicNote, "planDataMod", "extra");
} // 设置 plan 属性
if (planBandwidth) nodes[server.ID].plan.bandwidth = planBandwidth;
if (planTrafficVol) nodes[server.ID].plan.trafficVol = planTrafficVol;
if (planTrafficType) nodes[server.ID].plan.trafficType = planTrafficType;
if (planIPv4) nodes[server.ID].plan.ipv4 = planIPv4 >= 1;
if (planIPv6) nodes[server.ID].plan.ipv6 = planIPv6 >= 1;
if (planNetworkRoute) nodes[server.ID].plan.networkRoute = planNetworkRoute.split(',');
if (planExtra) nodes[server.ID].plan.extra = planExtra.split(',');
}); });
return nodes; return nodes;
}, },
@@ -859,7 +870,7 @@
const expiration = new Date(endDate); const expiration = new Date(endDate);
const current = this.getAdjustTimezone(new Date(endDate), new Date()); const current = this.getAdjustTimezone(new Date(endDate), new Date());
// 如果 expiration 无效,返回 null 并记录日志 // 如果 expiration 无效,记录日志
if (isNaN(expiration.getTime())) { if (isNaN(expiration.getTime())) {
console.log("getAutoRenewalEndDate: Invalid expiration format"); console.log("getAutoRenewalEndDate: Invalid expiration format");
} }
@@ -1055,7 +1066,7 @@
return this.formatPercents(online, this.toFixed2(percent)); return this.formatPercents(online, this.toFixed2(percent));
}, },
getRemainingDays(endDate, note) { getRemainingDays(endDate, note, type) {
// 检查 endDate 是否有效 // 检查 endDate 是否有效
if (!endDate || typeof endDate !== 'string') { if (!endDate || typeof endDate !== 'string') {
return null; return null;
@@ -1066,9 +1077,9 @@
return "lifetime"; return "lifetime";
} }
// 检查 startDate 和 endDate 是否为合法的Date // 检查 endDate 是否为合法的Date
if (isNaN(new Date(endDate).getTime())) { if (isNaN(new Date(endDate).getTime())) {
return "NaN"; return type === 1 ? null : "NaN";
} }
// 获取当前时间,并调整时区 // 获取当前时间,并调整时区
@@ -1087,6 +1098,9 @@
// 确定到期时间 // 确定到期时间
const end = autoRenewal ? autoEndDate.date : new Date(endDate); const end = autoRenewal ? autoEndDate.date : new Date(endDate);
// 直接返回处理后的到期时间
if (type === 1) return end;
// 计算剩余天数 // 计算剩余天数
const timeDiff = end - currentTime; const timeDiff = end - currentTime;
const daysDiff = Math.ceil(timeDiff / (1000 * 60 * 60 * 24)); const daysDiff = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
+2 -2
View File
@@ -11,7 +11,7 @@
<input type="text" id="dropdown-search" class="form-control" placeholder="Search..."> <input type="text" id="dropdown-search" class="form-control" placeholder="Search...">
</li> </li>
<li class="dropdown-item" v-for="server in servers" @click="showCharts(server.ID)"> <li class="dropdown-item" v-for="server in servers" @click="showCharts(server.ID)">
<a><i :class="'fi fi-' + (server.Host.CountryCode || 'rb')"></i> @#server.Name#@ <i v-if="server.ID == currentServerId" class="check icon"></i></a> <a><i :class="'fi fi-' + (server.Host.CountryCode || 'un')"></i> @#server.Name#@ <i v-if="server.ID == currentServerId" class="check icon"></i></a>
</li> </li>
</ul> </ul>
</div> </div>
@@ -332,7 +332,7 @@
}, },
getServerCountryCode(id){ getServerCountryCode(id){
const result = this.servers.find(item => item.ID == id); const result = this.servers.find(item => item.ID == id);
return result.Host.CountryCode ? result.Host.CountryCode : 'rb'; return result.Host.CountryCode ? result.Host.CountryCode : 'un';
}, },
getNextServerId(id) { getNextServerId(id) {
const currentIndex = this.servers.findIndex(item => item.ID === id); const currentIndex = this.servers.findIndex(item => item.ID === id);
+1 -1
View File
@@ -51,7 +51,7 @@ if ([string]::IsNullOrWhiteSpace($agenttag)) {
#Region判断 #Region判断
$ipapi = "" $ipapi = ""
$region = "Unknown" $region = "Unknown"
foreach ($url in ("https://dash.cloudflare.com/cdn-cgi/trace","https://cf-ns.com/cdn-cgi/trace","https://1.0.0.1/cdn-cgi/trace")) { foreach ($url in ("https://dash.cloudflare.com/cdn-cgi/trace","https://developers.cloudflare.com/cdn-cgi/trace","https://1.0.0.1/cdn-cgi/trace")) {
try { try {
$ipapi = Invoke-RestMethod -Uri $url -TimeoutSec 5 -UseBasicParsing $ipapi = Invoke-RestMethod -Uri $url -TimeoutSec 5 -UseBasicParsing
if ($ipapi -match "loc=(\w+)" ) { if ($ipapi -match "loc=(\w+)" ) {
+103 -91
View File
@@ -12,13 +12,13 @@ NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent" NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service" NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service"
NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard" NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard"
NZ_VERSION="v0.19.2" NZ_VERSION="v0.20.2"
red='\033[0;31m' red='\033[0;31m'
green='\033[0;32m' green='\033[0;32m'
yellow='\033[0;33m' yellow='\033[0;33m'
plain='\033[0m' plain='\033[0m'
export PATH=$PATH:/usr/local/bin export PATH="$PATH:/usr/local/bin"
os_arch="" os_arch=""
[ -e /etc/os-release ] && grep -i "PRETTY_NAME" /etc/os-release | grep -qi "alpine" && os_alpine='1' [ -e /etc/os-release ] && grep -i "PRETTY_NAME" /etc/os-release | grep -qi "alpine" && os_alpine='1'
@@ -45,20 +45,28 @@ check_systemd() {
} }
err() { err() {
printf "${red}$*${plain}\n" >&2 printf "${red}%s${plain}\n" "$*" >&2
}
success() {
printf "${green}%s${plain}\n" "$*"
}
info() {
printf "${yellow}%s${plain}\n" "$*"
} }
geo_check() { geo_check() {
api_list="https://blog.cloudflare.com/cdn-cgi/trace https://dash.cloudflare.com/cdn-cgi/trace https://cf-ns.com/cdn-cgi/trace" api_list="https://blog.cloudflare.com/cdn-cgi/trace https://dash.cloudflare.com/cdn-cgi/trace https://developers.cloudflare.com/cdn-cgi/trace"
ua="Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0" ua="Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0"
set -- $api_list set -- "$api_list"
for url in $api_list; do for url in $api_list; do
text="$(curl -A "$ua" -m 10 -s $url)" text="$(curl -A "$ua" -m 10 -s "$url")"
endpoint="$(echo $text | sed -n 's/.*h=\([^ ]*\).*/\1/p')" endpoint="$(echo "$text" | sed -n 's/.*h=\([^ ]*\).*/\1/p')"
if echo $text | grep -qw 'CN'; then if echo "$text" | grep -qw 'CN'; then
isCN=true isCN=true
break break
elif echo $url | grep -q $endpoint; then elif echo "$url" | grep -q "$endpoint"; then
break break
fi fi
done done
@@ -85,9 +93,9 @@ pre_check() {
## China_IP ## China_IP
if [ -z "$CN" ]; then if [ -z "$CN" ]; then
geo_check geo_check
if [ ! -z "$isCN" ]; then if [ -n "$isCN" ]; then
echo "根据geoip api提供的信息,当前IP可能在中国" echo "根据geoip api提供的信息,当前IP可能在中国"
printf "是否选用中国镜像完成安装? [Y/n] (自定义镜像输入 3):" printf "是否选用中国镜像完成安装? [Y/n] (自定义镜像输入 3)"
read -r input read -r input
case $input in case $input in
[yY][eE][sS] | [yY]) [yY][eE][sS] | [yY])
@@ -180,7 +188,9 @@ installation_check() {
select_version() { select_version() {
if [ -z "$IS_DOCKER_NEZHA" ]; then if [ -z "$IS_DOCKER_NEZHA" ]; then
printf "${yellow}请自行选择您的安装方式(如果你是安装Agent,输入哪个都是一样的):\n1. Docker\n2. 独立安装${plain}\n" info "请自行选择您的安装方式(如果你是安装Agent,输入哪个都是一样的):"
info "1. Docker"
info "2. 独立安装"
while true; do while true; do
printf "请输入选择 [1-2]" printf "请输入选择 [1-2]"
read -r option read -r option
@@ -206,7 +216,7 @@ update_script() {
curl -sL https://${GITHUB_RAW_URL}/script/install.sh -o /tmp/nezha.sh curl -sL https://${GITHUB_RAW_URL}/script/install.sh -o /tmp/nezha.sh
new_version=$(grep "NZ_VERSION" /tmp/nezha.sh | head -n 1 | awk -F "=" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g') new_version=$(grep "NZ_VERSION" /tmp/nezha.sh | head -n 1 | awk -F "=" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$new_version" ]; then if [ -z "$new_version" ]; then
echo "脚本获取失败,请检查本机能否链接 https://${GITHUB_RAW_URL}/script/install.sh" echo "脚本获取失败,请检查本机能否链接 https://${GITHUB_RAW_URL}/script/install.sh"
return 1 return 1
fi fi
@@ -221,7 +231,7 @@ update_script() {
} }
before_show_menu() { before_show_menu() {
echo && printf "${yellow}* 按回车返回主菜单 *${plain}" && read temp echo && info "* 按回车返回主菜单 *" && read temp
show_menu show_menu
} }
@@ -231,7 +241,7 @@ install_base() {
} }
install_arch() { install_arch() {
printf "${green}提示: ${plain} Arch安装libselinux需添加nezha-agent用户,安装完会自动删除,建议手动检查一次\n" info "提示:Arch安装libselinux需添加nezha-agent用户,安装完会自动删除,建议手动检查一次"
read -r -p "是否安装libselinux? [Y/n] " input read -r -p "是否安装libselinux? [Y/n] " input
case $input in case $input in
[yY][eE][sS] | [yY]) [yY][eE][sS] | [yY])
@@ -255,11 +265,11 @@ install_arch() {
} }
install_soft() { install_soft() {
(command -v yum >/dev/null 2>&1 && sudo yum makecache && sudo yum install $* selinux-policy -y) || (command -v yum >/dev/null 2>&1 && sudo yum makecache && sudo yum install "$@" selinux-policy -y) ||
(command -v apt >/dev/null 2>&1 && sudo apt update && sudo apt install $* selinux-utils -y) || (command -v apt >/dev/null 2>&1 && sudo apt update && sudo apt install "$@" selinux-utils -y) ||
(command -v pacman >/dev/null 2>&1 && sudo pacman -Syu $* base-devel --noconfirm && install_arch) || (command -v pacman >/dev/null 2>&1 && sudo pacman -Syu "$@" base-devel --noconfirm && install_arch) ||
(command -v apt-get >/dev/null 2>&1 && sudo apt-get update && sudo apt-get install $* selinux-utils -y) || (command -v apt-get >/dev/null 2>&1 && sudo apt-get update && sudo apt-get install "$@" selinux-utils -y) ||
(command -v apk >/dev/null 2>&1 && sudo apk update && sudo apk add $* -f) (command -v apk >/dev/null 2>&1 && sudo apk update && sudo apk add "$@" -f)
} }
install_dashboard() { install_dashboard() {
@@ -305,12 +315,10 @@ install_dashboard() {
install_dashboard_docker() { install_dashboard_docker() {
if [ ! "$FRESH_INSTALL" = 0 ]; then if [ ! "$FRESH_INSTALL" = 0 ]; then
command -v docker >/dev/null 2>&1 if ! command -v docker >/dev/null 2>&1; then
if [ $? != 0 ]; then
echo "正在安装 Docker" echo "正在安装 Docker"
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
curl -sL https://${Get_Docker_URL} | sudo bash -s ${Get_Docker_Argu} if ! curl -sL https://${Get_Docker_URL} | sudo bash -s "${Get_Docker_Argu}"; then
if [ $? != 0 ]; then
err "下载脚本失败,请检查本机能否连接 ${Get_Docker_URL}" err "下载脚本失败,请检查本机能否连接 ${Get_Docker_URL}"
return 0 return 0
fi fi
@@ -321,7 +329,7 @@ install_dashboard_docker() {
sudo rc-update add docker sudo rc-update add docker
sudo rc-service docker start sudo rc-service docker start
fi fi
printf "${green}Docker${plain} 安装成功\n" success "Docker 安装成功"
installation_check installation_check
fi fi
fi fi
@@ -334,13 +342,11 @@ install_dashboard_standalone() {
} }
selinux() { selinux() {
#判断当前的状态 #Check SELinux
command -v getenforce >/dev/null 2>&1 if command -v getenforce >/dev/null 2>&1; then
if [ $? -eq 0 ]; then if getenforce | grep '[Ee]nfor'; then
getenforce | grep '[Ee]nfor'
if [ $? -eq 0 ]; then
echo "SELinux是开启状态,正在关闭!" echo "SELinux是开启状态,正在关闭!"
sudo setenforce 0 &>/dev/null sudo setenforce 0 >/dev/null 2>&1
find_key="SELINUX=" find_key="SELINUX="
sudo sed -ri "/^$find_key/c${find_key}disabled" /etc/selinux/config sudo sed -ri "/^$find_key/c${find_key}disabled" /etc/selinux/config
fi fi
@@ -355,22 +361,23 @@ install_agent() {
echo "正在获取监控Agent版本号" echo "正在获取监控Agent版本号"
local version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$version" ]; then _version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/agent/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}') if [ -z "$_version" ]; then
_version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/agent/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g') _version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g') _version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
err "获取版本号失败,请检查本机能否链接 https://api.github.com/repos/nezhahq/agent/releases/latest" err "获取版本号失败,请检查本机能否链接 https://api.github.com/repos/nezhahq/agent/releases/latest"
return 1 return 1
else else
echo "当前最新版本为: ${version}" echo "当前最新版本为: ${_version}"
fi fi
# 哪吒监控文件夹 # 哪吒监控文件夹
@@ -378,12 +385,13 @@ install_agent() {
echo "正在下载监控端" echo "正在下载监控端"
if [ -z "$CN" ]; then if [ -z "$CN" ]; then
NZ_AGENT_URL="https://${GITHUB_URL}/nezhahq/agent/releases/download/${version}/nezha-agent_linux_${os_arch}.zip" NZ_AGENT_URL="https://${GITHUB_URL}/nezhahq/agent/releases/download/${_version}/nezha-agent_linux_${os_arch}.zip"
else else
NZ_AGENT_URL="https://${GITHUB_URL}/naibahq/agent/releases/download/${version}/nezha-agent_linux_${os_arch}.zip" NZ_AGENT_URL="https://${GITHUB_URL}/naibahq/agent/releases/download/${_version}/nezha-agent_linux_${os_arch}.zip"
fi fi
wget -t 2 -T 60 -O nezha-agent_linux_${os_arch}.zip $NZ_AGENT_URL >/dev/null 2>&1
if [ $? != 0 ]; then _cmd="wget -t 2 -T 60 -O nezha-agent_linux_${os_arch}.zip $NZ_AGENT_URL >/dev/null 2>&1"
if ! eval "$_cmd"; then
err "Release 下载失败,请检查本机能否连接 ${GITHUB_URL}" err "Release 下载失败,请检查本机能否连接 ${GITHUB_URL}"
return 1 return 1
fi fi
@@ -435,14 +443,14 @@ modify_agent_config() {
fi fi
fi fi
sudo ${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1 _cmd="sudo ${NZ_AGENT_PATH}/nezha-agent service install -s $nz_grpc_host:$nz_grpc_port -p $nz_client_secret $args >/dev/null 2>&1"
if [ $? -ne 0 ]; then if ! eval "$_cmd"; then
sudo ${NZ_AGENT_PATH}/nezha-agent service uninstall >/dev/null 2>&1 sudo "${NZ_AGENT_PATH}"/nezha-agent service uninstall >/dev/null 2>&1
sudo ${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1 sudo "${NZ_AGENT_PATH}"/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p "$nz_client_secret" "$args" >/dev/null 2>&1
fi fi
printf "Agent配置 ${green}修改成功,请稍等重启生效${plain}\n" success "Agent配置 修改成功,请稍等重启生效"
#if [[ $# == 0 ]]; then #if [[ $# == 0 ]]; then
# before_show_menu # before_show_menu
@@ -453,10 +461,10 @@ modify_dashboard_config() {
echo "> 修改面板配置" echo "> 修改面板配置"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
if [ ! -z "$DOCKER_COMPOSE_COMMAND" ]; then if [ -n "$DOCKER_COMPOSE_COMMAND" ]; then
echo "正在下载 Docker 脚本" echo "正在下载 Docker 脚本"
wget -t 2 -T 60 -O /tmp/nezha-docker-compose.yaml https://${GITHUB_RAW_URL}/script/docker-compose.yaml >/dev/null 2>&1 _cmd="wget -t 2 -T 60 -O /tmp/nezha-docker-compose.yaml https://${GITHUB_RAW_URL}/script/docker-compose.yaml >/dev/null 2>&1"
if [ $? != 0 ]; then if ! eval "$_cmd"; then
err "下载脚本失败,请检查本机能否连接 ${GITHUB_RAW_URL}" err "下载脚本失败,请检查本机能否连接 ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
@@ -466,8 +474,8 @@ modify_dashboard_config() {
fi fi
fi fi
wget -t 2 -T 60 -O /tmp/nezha-config.yaml https://${GITHUB_RAW_URL}/script/config.yaml >/dev/null 2>&1 _cmd="wget -t 2 -T 60 -O /tmp/nezha-config.yaml https://${GITHUB_RAW_URL}/script/config.yaml >/dev/null 2>&1"
if [ $? != 0 ]; then if ! eval "$_cmd"; then
err "下载脚本失败,请检查本机能否连接 ${GITHUB_RAW_URL}" err "下载脚本失败,请检查本机能否连接 ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
@@ -529,18 +537,22 @@ modify_dashboard_config() {
if [ "$IS_DOCKER_NEZHA" = 0 ]; then if [ "$IS_DOCKER_NEZHA" = 0 ]; then
echo "正在下载服务文件" echo "正在下载服务文件"
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICE https://${GITHUB_RAW_URL}/script/nezha-dashboard.service >/dev/null 2>&1 _download="sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICE https://${GITHUB_RAW_URL}/script/nezha-dashboard.service >/dev/null 2>&1"
else if ! eval "$_download"; then
sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICERC https://${GITHUB_RAW_URL}/script/nezha-dashboard >/dev/null 2>&1
sudo chmod +x $NZ_DASHBOARD_SERVICERC
if [ $? != 0 ]; then
err "文件下载失败,请检查本机能否连接 ${GITHUB_RAW_URL}" err "文件下载失败,请检查本机能否连接 ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
else
_download="sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICERC https://${GITHUB_RAW_URL}/script/nezha-dashboard >/dev/null 2>&1"
if ! eval "$_download"; then
err "文件下载失败,请检查本机能否连接 ${GITHUB_RAW_URL}"
return 0
fi
sudo chmod +x $NZ_DASHBOARD_SERVICERC
fi fi
fi fi
printf "面板配置 ${green}修改成功,请稍等重启生效${plain}\n" success "面板配置 修改成功,请稍等重启生效"
restart_and_update restart_and_update
@@ -553,14 +565,14 @@ restart_and_update() {
echo "> 重启并更新面板" echo "> 重启并更新面板"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
restart_and_update_docker _cmd="restart_and_update_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
restart_and_update_standalone _cmd="restart_and_update_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}哪吒监控 重启成功${plain}\n" success "哪吒监控 重启成功"
printf "默认管理面板地址:${yellow}域名:站点访问端口${plain}\n" info "默认管理面板地址:域名:站点访问端口"
else else
err "重启失败,可能是因为启动时间超过了两秒,请稍后查看日志信息" err "重启失败,可能是因为启动时间超过了两秒,请稍后查看日志信息"
fi fi
@@ -577,15 +589,22 @@ restart_and_update_docker() {
} }
restart_and_update_standalone() { restart_and_update_standalone() {
local version=$(curl -m 10 -sL "https://api.github.com/repos/naiba/nezha/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g') _version=$(curl -m 10 -sL "https://api.github.com/repos/naiba/nezha/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/nezha/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}') _version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/nezha/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g') _version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g') _version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g')
fi
if [ -z "$_version" ]; then
err "获取版本号失败,请检查本机能否链接 https://api.github.com/repos/naiba/nezha/releases/latest"
return 1
else
echo "当前最新版本为: ${_version}"
fi fi
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
@@ -595,20 +614,13 @@ restart_and_update_standalone() {
sudo rc-service nezha-dashboard stop sudo rc-service nezha-dashboard stop
fi fi
if [ ! -n "$version" ]; then
err "获取版本号失败,请检查本机能否链接 https://api.github.com/repos/naiba/nezha/releases/latest"
return 1
else
echo "当前最新版本为: ${version}"
fi
if [ -z "$CN" ]; then if [ -z "$CN" ]; then
NZ_DASHBOARD_URL="https://${GITHUB_URL}/naiba/nezha/releases/download/$version/dashboard-linux-$os_arch.zip" NZ_DASHBOARD_URL="https://${GITHUB_URL}/naiba/nezha/releases/download/${_version}/dashboard-linux-${os_arch}.zip"
else else
NZ_DASHBOARD_URL="https://${GITHUB_URL}/naibahq/nezha/releases/download/$version/dashboard-linux-$os_arch.zip" NZ_DASHBOARD_URL="https://${GITHUB_URL}/naibahq/nezha/releases/download/${_version}/dashboard-linux-${os_arch}.zip"
fi fi
sudo wget -qO $NZ_DASHBOARD_PATH/app.zip $NZ_DASHBOARD_URL >/dev/null 2>&1 && sudo unzip -qq -o $NZ_DASHBOARD_PATH/app.zip -d $NZ_DASHBOARD_PATH && sudo mv $NZ_DASHBOARD_PATH/dashboard-linux-$os_arch $NZ_DASHBOARD_PATH/app && sudo rm $NZ_DASHBOARD_PATH/app.zip sudo wget -qO $NZ_DASHBOARD_PATH/app.zip "$NZ_DASHBOARD_URL" >/dev/null 2>&1 && sudo unzip -qq -o $NZ_DASHBOARD_PATH/app.zip -d $NZ_DASHBOARD_PATH && sudo mv $NZ_DASHBOARD_PATH/dashboard-linux-$os_arch $NZ_DASHBOARD_PATH/app && sudo rm $NZ_DASHBOARD_PATH/app.zip
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
sudo systemctl enable nezha-dashboard sudo systemctl enable nezha-dashboard
@@ -623,13 +635,13 @@ start_dashboard() {
echo "> 启动面板" echo "> 启动面板"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
start_dashboard_docker _cmd="start_dashboard_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
start_dashboard_standalone _cmd="start_dashboard_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}哪吒监控 启动成功${plain}\n" success "哪吒监控 启动成功"
else else
err "启动失败,请稍后查看日志信息" err "启动失败,请稍后查看日志信息"
fi fi
@@ -655,13 +667,13 @@ stop_dashboard() {
echo "> 停止面板" echo "> 停止面板"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
stop_dashboard_docker _cmd="stop_dashboard_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
stop_dashboard_standalone _cmd="stop_dashboard_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}哪吒监控 停止成功${plain}\n" success "哪吒监控 停止成功"
else else
err "停止失败,请稍后查看日志信息" err "停止失败,请稍后查看日志信息"
fi fi
@@ -940,4 +952,4 @@ if [ $# -gt 0 ]; then
else else
select_version select_version
show_menu show_menu
fi fi
+124 -107
View File
@@ -12,13 +12,13 @@ NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard"
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent" NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service" NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service"
NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard" NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard"
NZ_VERSION="v0.19.2" NZ_VERSION="v0.20.2"
red='\033[0;31m' red='\033[0;31m'
green='\033[0;32m' green='\033[0;32m'
yellow='\033[0;33m' yellow='\033[0;33m'
plain='\033[0m' plain='\033[0m'
export PATH=$PATH:/usr/local/bin export PATH="$PATH:/usr/local/bin"
os_arch="" os_arch=""
[ -e /etc/os-release ] && grep -i "PRETTY_NAME" /etc/os-release | grep -qi "alpine" && os_alpine='1' [ -e /etc/os-release ] && grep -i "PRETTY_NAME" /etc/os-release | grep -qi "alpine" && os_alpine='1'
@@ -45,20 +45,28 @@ check_systemd() {
} }
err() { err() {
printf "${red}$*${plain}\n" >&2 printf "${red}%s${plain}\n" "$*" >&2
}
success() {
printf "${green}%s${plain}\n" "$*"
}
info() {
printf "${yellow}%s${plain}\n" "$*"
} }
geo_check() { geo_check() {
api_list="https://blog.cloudflare.com/cdn-cgi/trace https://dash.cloudflare.com/cdn-cgi/trace https://cf-ns.com/cdn-cgi/trace" api_list="https://blog.cloudflare.com/cdn-cgi/trace https://dash.cloudflare.com/cdn-cgi/trace https://developers.cloudflare.com/cdn-cgi/trace"
ua="Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0" ua="Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0"
set -- $api_list set -- "$api_list"
for url in $api_list; do for url in $api_list; do
text="$(curl -A "$ua" -m 10 -s $url)" text="$(curl -A "$ua" -m 10 -s "$url")"
endpoint="$(echo $text | sed -n 's/.*h=\([^ ]*\).*/\1/p')" endpoint="$(echo "$text" | sed -n 's/.*h=\([^ ]*\).*/\1/p')"
if echo $text | grep -qw 'CN'; then if echo "$text" | grep -qw 'CN'; then
isCN=true isCN=true
break break
elif echo $url | grep -q $endpoint; then elif echo "$url" | grep -q "$endpoint"; then
break break
fi fi
done done
@@ -85,7 +93,7 @@ pre_check() {
## China_IP ## China_IP
if [ -z "$CN" ]; then if [ -z "$CN" ]; then
geo_check geo_check
if [ ! -z "$isCN" ]; then if [ -n "$isCN" ]; then
echo "According to the information provided by various geoip api, the current IP may be in China" echo "According to the information provided by various geoip api, the current IP may be in China"
printf "Will the installation be done with a Chinese Mirror? [Y/n] (Custom Mirror Input 3): " printf "Will the installation be done with a Chinese Mirror? [Y/n] (Custom Mirror Input 3): "
read -r input read -r input
@@ -179,7 +187,9 @@ installation_check() {
select_version() { select_version() {
if [ -z "$IS_DOCKER_NEZHA" ]; then if [ -z "$IS_DOCKER_NEZHA" ]; then
printf "${yellow}Select your installation method(Input anything is ok if you are installing agent):\n1. Docker\n2. Standalone${plain}\n" info "Select your installation method(Input anything is ok if you are installing agent):"
info "1. Docker"
info "2. Standalone"
while true; do while true; do
printf "Please enter [1-2]: " printf "Please enter [1-2]: "
read -r option read -r option
@@ -205,7 +215,7 @@ update_script() {
curl -sL https://${GITHUB_RAW_URL}/script/install_en.sh -o /tmp/nezha.sh curl -sL https://${GITHUB_RAW_URL}/script/install_en.sh -o /tmp/nezha.sh
new_version=$(grep "NZ_VERSION" /tmp/nezha.sh | head -n 1 | awk -F "=" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g') new_version=$(grep "NZ_VERSION" /tmp/nezha.sh | head -n 1 | awk -F "=" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$new_version" ]; then if [ -z "$new_version" ]; then
echo "Script failed to get, please check if the network can link https://${GITHUB_RAW_URL}/script/install.sh" echo "Script failed to get, please check if the network can link https://${GITHUB_RAW_URL}/script/install.sh"
return 1 return 1
fi fi
@@ -220,7 +230,7 @@ update_script() {
} }
before_show_menu() { before_show_menu() {
echo && printf "${yellow}* Press Enter to return to the main menu *${plain}" && read temp echo && info "* Press Enter to return to the main menu *" && read temp
show_menu show_menu
} }
@@ -230,7 +240,7 @@ install_base() {
} }
install_arch() { install_arch() {
printf "${green}Info: ${plain} Archlinux needs to add nezha-agent user to install libselinux. It will be deleted automatically after installation. It is recommended to check manually\n" info "Archlinux needs to add nezha-agent user to install libselinux. It will be deleted automatically after installation. It is recommended to check manually"
read -r -p "Do you need to install libselinux? [Y/n] " input read -r -p "Do you need to install libselinux? [Y/n] " input
case $input in case $input in
[yY][eE][sS] | [yY]) [yY][eE][sS] | [yY])
@@ -254,11 +264,11 @@ install_arch() {
} }
install_soft() { install_soft() {
(command -v yum >/dev/null 2>&1 && sudo yum makecache && sudo yum install $* selinux-policy -y) || (command -v yum >/dev/null 2>&1 && sudo yum makecache && sudo yum install "$@" selinux-policy -y) ||
(command -v apt >/dev/null 2>&1 && sudo apt update && sudo apt install $* selinux-utils -y) || (command -v apt >/dev/null 2>&1 && sudo apt update && sudo apt install "$@" selinux-utils -y) ||
(command -v pacman >/dev/null 2>&1 && sudo pacman -Syu $* base-devel --noconfirm && install_arch) || (command -v pacman >/dev/null 2>&1 && sudo pacman -Syu "$@" base-devel --noconfirm && install_arch) ||
(command -v apt-get >/dev/null 2>&1 && sudo apt-get update && sudo apt-get install $* selinux-utils -y) || (command -v apt-get >/dev/null 2>&1 && sudo apt-get update && sudo apt-get install "$@" selinux-utils -y) ||
(command -v apk >/dev/null 2>&1 && sudo apk update && sudo apk add $* -f) (command -v apk >/dev/null 2>&1 && sudo apk update && sudo apk add "$@" -f)
} }
install_dashboard() { install_dashboard() {
@@ -304,12 +314,10 @@ install_dashboard() {
install_dashboard_docker() { install_dashboard_docker() {
if [ ! "$FRESH_INSTALL" = 0 ]; then if [ ! "$FRESH_INSTALL" = 0 ]; then
command -v docker >/dev/null 2>&1 if ! command -v docker >/dev/null 2>&1; then
if [ $? != 0 ]; then
echo "Installing Docker" echo "Installing Docker"
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
curl -sL https://${Get_Docker_URL} | sudo bash -s ${Get_Docker_Argu} if ! curl -sL https://${Get_Docker_URL} | sudo bash -s "${Get_Docker_Argu}"; then
if [ $? != 0 ]; then
err "Script failed to get, please check if the network can link ${Get_Docker_URL}" err "Script failed to get, please check if the network can link ${Get_Docker_URL}"
return 0 return 0
fi fi
@@ -320,7 +328,7 @@ install_dashboard_docker() {
sudo rc-update add docker sudo rc-update add docker
sudo rc-service docker start sudo rc-service docker start
fi fi
printf "${green}Docker${plain} installed successfully\n" success "Docker installed successfully"
installation_check installation_check
fi fi
fi fi
@@ -334,12 +342,10 @@ install_dashboard_standalone() {
selinux() { selinux() {
#Check SELinux #Check SELinux
command -v getenforce >/dev/null 2>&1 if command -v getenforce >/dev/null 2>&1; then
if [ $? -eq 0 ]; then if getenforce | grep '[Ee]nfor'; then
getenforce | grep '[Ee]nfor'
if [ $? -eq 0 ]; then
echo "SELinux running, closing now!" echo "SELinux running, closing now!"
sudo setenforce 0 &>/dev/null sudo setenforce 0 >/dev/null 2>&1
find_key="SELINUX=" find_key="SELINUX="
sudo sed -ri "/^$find_key/c${find_key}disabled" /etc/selinux/config sudo sed -ri "/^$find_key/c${find_key}disabled" /etc/selinux/config
fi fi
@@ -354,30 +360,37 @@ install_agent() {
echo "Obtaining Agent version number" echo "Obtaining Agent version number"
local version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$version" ]; then _version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/agent/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}') if [ -z "$_version" ]; then
_version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/agent/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g') _version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g') _version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
err "Fail to obtaine agent version, please check if the network can link https://api.github.com/repos/nezhahq/agent/releases/latest" err "Fail to obtain agent version, please check if the network can link https://api.github.com/repos/nezhahq/agent/releases/latest"
return 1 return 1
else else
echo "The current latest version is: ${version}" echo "The current latest version is: ${_version}"
fi fi
# Nezha Monitoring Folder # Nezha Monitoring Folder
sudo mkdir -p $NZ_AGENT_PATH sudo mkdir -p $NZ_AGENT_PATH
echo "Downloading Agent" echo "Downloading Agent"
wget -t 2 -T 60 -O nezha-agent_linux_${os_arch}.zip https://${GITHUB_URL}/nezhahq/agent/releases/download/${version}/nezha-agent_linux_${os_arch}.zip >/dev/null 2>&1 if [ -z "$CN" ]; then
if [ $? != 0 ]; then NZ_AGENT_URL="https://${GITHUB_URL}/nezhahq/agent/releases/download/${_version}/nezha-agent_linux_${os_arch}.zip"
else
NZ_AGENT_URL="https://${GITHUB_URL}/naibahq/agent/releases/download/${_version}/nezha-agent_linux_${os_arch}.zip"
fi
_cmd="wget -t 2 -T 60 -O nezha-agent_linux_${os_arch}.zip $NZ_AGENT_URL >/dev/null 2>&1"
if ! eval "$_cmd"; then
err "Fail to download agent, please check if the network can link ${GITHUB_URL}" err "Fail to download agent, please check if the network can link ${GITHUB_URL}"
return 1 return 1
fi fi
@@ -401,10 +414,10 @@ modify_agent_config() {
echo "> Modify Agent Configuration" echo "> Modify Agent Configuration"
if [ $# -lt 3 ]; then if [ $# -lt 3 ]; then
echo "Please add Agent in the admin panel first, record the secret" echo "Please add Agent in the Dashboard first, record the secret"
printf "Please enter a domain that resolves to the IP where the panel is located (no CDN): " printf "Please enter a domain that resolves to the IP where Dashboard is located (no CDN): "
read -r nz_grpc_host read -r nz_grpc_host
printf "Please enter the panel RPC port (default 5555): " printf "Please enter Dashboard RPC port (default 5555): "
read -r nz_grpc_port read -r nz_grpc_port
printf "Please enter the Agent secret: " printf "Please enter the Agent secret: "
read -r nz_client_secret read -r nz_client_secret
@@ -429,14 +442,14 @@ modify_agent_config() {
fi fi
fi fi
sudo ${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1 _cmd="sudo ${NZ_AGENT_PATH}/nezha-agent service install -s $nz_grpc_host:$nz_grpc_port -p $nz_client_secret $args >/dev/null 2>&1"
if [ $? -ne 0 ]; then if ! eval "$_cmd"; then
sudo ${NZ_AGENT_PATH}/nezha-agent service uninstall >/dev/null 2>&1 sudo "${NZ_AGENT_PATH}"/nezha-agent service uninstall >/dev/null 2>&1
sudo ${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1 sudo "${NZ_AGENT_PATH}"/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p "$nz_client_secret" "$args" >/dev/null 2>&1
fi fi
printf "Agent configuration ${green} modified successfully, please wait for agent self-restart to take effect${plain}\n" success "Agent configuration modified successfully, please wait for agent self-restart to take effect"
#if [[ $# == 0 ]]; then #if [[ $# == 0 ]]; then
# before_show_menu # before_show_menu
@@ -447,21 +460,21 @@ modify_dashboard_config() {
echo "> Modify Dashboard Configuration" echo "> Modify Dashboard Configuration"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
if [ ! -z "$DOCKER_COMPOSE_COMMAND" ]; then if [ -n "$DOCKER_COMPOSE_COMMAND" ]; then
echo "Download Docker Script" echo "Download Docker Script"
wget -t 2 -T 60 -O /tmp/nezha-docker-compose.yaml https://${GITHUB_RAW_URL}/script/docker-compose.yaml >/dev/null 2>&1 _cmd="wget -t 2 -T 60 -O /tmp/nezha-docker-compose.yaml https://${GITHUB_RAW_URL}/script/docker-compose.yaml >/dev/null 2>&1"
if [ $? != 0 ]; then if ! eval "$_cmd"; then
err "Script failed to get, please check if the network can link ${GITHUB_RAW_URL}" err "Script failed to get, please check if the network can link ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
else else
err "请手动安装 docker-composehttps://docs.docker.com/compose/install/linux/" err "Please install docker-compose manually. https://docs.docker.com/compose/install/linux/"
before_show_menu before_show_menu
fi fi
fi fi
wget -t 2 -T 60 -O /tmp/nezha-config.yaml https://${GITHUB_RAW_URL}/script/config.yaml >/dev/null 2>&1 _cmd="wget -t 2 -T 60 -O /tmp/nezha-config.yaml https://${GITHUB_RAW_URL}/script/config.yaml >/dev/null 2>&1"
if [ $? != 0 ]; then if ! eval "$_cmd"; then
err "Script failed to get, please check if the network can link ${GITHUB_RAW_URL}" err "Script failed to get, please check if the network can link ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
@@ -523,18 +536,22 @@ modify_dashboard_config() {
if [ "$IS_DOCKER_NEZHA" = 0 ]; then if [ "$IS_DOCKER_NEZHA" = 0 ]; then
echo "Downloading service file" echo "Downloading service file"
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICE https://${GITHUB_RAW_URL}/script/nezha-dashboard.service >/dev/null 2>&1 _download="sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICE https://${GITHUB_RAW_URL}/script/nezha-dashboard.service >/dev/null 2>&1"
else if ! eval "$_download"; then
sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICERC https://${GITHUB_RAW_URL}/script/nezha-dashboard >/dev/null 2>&1
sudo chmod +x $NZ_DASHBOARD_SERVICERC
if [ $? != 0 ]; then
err "File failed to get, please check if the network can link ${GITHUB_RAW_URL}" err "File failed to get, please check if the network can link ${GITHUB_RAW_URL}"
return 0 return 0
fi fi
else
_download="sudo wget -t 2 -T 60 -O $NZ_DASHBOARD_SERVICERC https://${GITHUB_RAW_URL}/script/nezha-dashboard >/dev/null 2>&1"
if ! eval "$_download"; then
err "File failed to get, please check if the network can link ${GITHUB_RAW_URL}"
return 0
fi
sudo chmod +x $NZ_DASHBOARD_SERVICERC
fi fi
fi fi
printf "Dashboard configuration ${green} modified successfully, please wait for Dashboard self-restart to take effect${plain}\n" success "Dashboard configuration modified successfully, please wait for Dashboard self-restart to take effect"
restart_and_update restart_and_update
@@ -544,17 +561,17 @@ modify_dashboard_config() {
} }
restart_and_update() { restart_and_update() {
echo "> Restart and Update the Panel" echo "> Restart and Update Dashboard"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
restart_and_update_docker _cmd="restart_and_update_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
restart_and_update_standalone _cmd="restart_and_update_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}Nezha Monitoring Restart Successful${plain}\n" success "Nezha Monitoring Restart Successful"
printf "Default panel address: ${yellow}domain:Site_access_port${plain}\n" info "Default Dashboard address: domain:site_access_port"
else else
err "The restart failed, probably because the boot time exceeded two seconds, please check the log information later" err "The restart failed, probably because the boot time exceeded two seconds, please check the log information later"
fi fi
@@ -571,22 +588,22 @@ restart_and_update_docker() {
} }
restart_and_update_standalone() { restart_and_update_standalone() {
local version=$(curl -m 10 -sL "https://api.github.com/repos/naiba/nezha/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g') _version=$(curl -m 10 -sL "https://api.github.com/repos/naiba/nezha/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/nezha/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}') _version=$(curl -m 10 -sL "https://gitee.com/api/v5/repos/naibahq/nezha/releases/latest" | awk -F '"' '{for(i=1;i<=NF;i++){if($i=="tag_name"){print $(i+2)}}}')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g') _version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g') _version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/naiba/nezha/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/naiba\/nezha@/v/g')
fi fi
if [ ! -n "$version" ]; then if [ -z "$_version" ]; then
err "Fail to obtaine agent version, please check if the network can link https://api.github.com/repos/nezhahq/agent/releases/latest" err "Fail to obtain agent version, please check if the network can link https://api.github.com/repos/nezhahq/agent/releases/latest"
return 1 return 1
else else
echo "The current latest version is: ${version}" echo "The current latest version is: ${_version}"
fi fi
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
@@ -597,12 +614,12 @@ restart_and_update_standalone() {
fi fi
if [ -z "$CN" ]; then if [ -z "$CN" ]; then
NZ_DASHBOARD_URL="https://${GITHUB_URL}/naiba/nezha/releases/download/$version/dashboard-linux-$os_arch.zip" NZ_DASHBOARD_URL="https://${GITHUB_URL}/naiba/nezha/releases/download/${_version}/dashboard-linux-${os_arch}.zip"
else else
NZ_DASHBOARD_URL="https://${GITHUB_URL}/naibahq/nezha/releases/download/$version/dashboard-linux-$os_arch.zip" NZ_DASHBOARD_URL="https://${GITHUB_URL}/naibahq/nezha/releases/download/${_version}/dashboard-linux-${os_arch}.zip"
fi fi
sudo wget -qO $NZ_DASHBOARD_PATH/app.zip $NZ_DASHBOARD_URL >/dev/null 2>&1 && sudo unzip -qq -o $NZ_DASHBOARD_PATH/app.zip -d $NZ_DASHBOARD_PATH && sudo mv $NZ_DASHBOARD_PATH/dashboard-linux-$os_arch $NZ_DASHBOARD_PATH/app && sudo rm $NZ_DASHBOARD_PATH/app.zip sudo wget -qO $NZ_DASHBOARD_PATH/app.zip "$NZ_DASHBOARD_URL" >/dev/null 2>&1 && sudo unzip -qq -o $NZ_DASHBOARD_PATH/app.zip -d $NZ_DASHBOARD_PATH && sudo mv $NZ_DASHBOARD_PATH/dashboard-linux-$os_arch $NZ_DASHBOARD_PATH/app && sudo rm $NZ_DASHBOARD_PATH/app.zip
if [ "$os_alpine" != 1 ]; then if [ "$os_alpine" != 1 ]; then
sudo systemctl enable nezha-dashboard sudo systemctl enable nezha-dashboard
@@ -614,16 +631,16 @@ restart_and_update_standalone() {
} }
start_dashboard() { start_dashboard() {
echo "> Start Panel" echo "> Start Dashboard"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
start_dashboard_docker _cmd="start_dashboard_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
start_dashboard_standalone _cmd="start_dashboard_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}Nezha Monitoring Start Successful${plain}\n" success "Nezha Monitoring Start Successful"
else else
err "Failed to start, please check the log message later" err "Failed to start, please check the log message later"
fi fi
@@ -646,16 +663,16 @@ start_dashboard_standalone() {
} }
stop_dashboard() { stop_dashboard() {
echo "> Stop Panel" echo "> Stop Dashboard"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
stop_dashboard_docker _cmd="stop_dashboard_docker"
elif [ "$IS_DOCKER_NEZHA" = 0 ]; then elif [ "$IS_DOCKER_NEZHA" = 0 ]; then
stop_dashboard_standalone _cmd="stop_dashboard_standalone"
fi fi
if [ $? = 0 ]; then if eval "$_cmd"; then
printf "${green}Nezha Monitoring Stop Successful${plain}\n" success "Nezha Monitoring Stop Successful"
else else
err "Failed to stop, please check the log message later" err "Failed to stop, please check the log message later"
fi fi
@@ -678,7 +695,7 @@ stop_dashboard_standalone() {
} }
show_dashboard_log() { show_dashboard_log() {
echo "> View Panel Log" echo "> View Dashboard Log"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
show_dashboard_log_docker show_dashboard_log_docker
@@ -704,7 +721,7 @@ show_dashboard_log_standalone() {
} }
uninstall_dashboard() { uninstall_dashboard() {
echo "> Uninstall Panel" echo "> Uninstall Dashboard"
if [ "$IS_DOCKER_NEZHA" = 1 ]; then if [ "$IS_DOCKER_NEZHA" = 1 ]; then
uninstall_dashboard_docker uninstall_dashboard_docker
@@ -791,13 +808,13 @@ show_usage() {
echo "Nezha Monitor Management Script Usage: " echo "Nezha Monitor Management Script Usage: "
echo "--------------------------------------------------------" echo "--------------------------------------------------------"
echo "./nezha.sh - Show Menu" echo "./nezha.sh - Show Menu"
echo "./nezha.sh install_dashboard - Install Panel" echo "./nezha.sh install_dashboard - Install Dashboard"
echo "./nezha.sh modify_dashboard_config - Modify Panel Configuration" echo "./nezha.sh modify_dashboard_config - Modify Dashboard Configuration"
echo "./nezha.sh start_dashboard - Start Panel" echo "./nezha.sh start_dashboard - Start Dashboard"
echo "./nezha.sh stop_dashboard - Stop Panel" echo "./nezha.sh stop_dashboard - Stop Dashboard"
echo "./nezha.sh restart_and_update - Restart and Update the Panel" echo "./nezha.sh restart_and_update - Restart and Update the Dashboard"
echo "./nezha.sh show_dashboard_log - View Panel Log" echo "./nezha.sh show_dashboard_log - View Dashboard Log"
echo "./nezha.sh uninstall_dashboard - Uninstall Panel" echo "./nezha.sh uninstall_dashboard - Uninstall Dashboard"
echo "--------------------------------------------------------" echo "--------------------------------------------------------"
echo "./nezha.sh install_agent - Install Agent" echo "./nezha.sh install_agent - Install Agent"
echo "./nezha.sh modify_agent_config - Modify Agent Configuration" echo "./nezha.sh modify_agent_config - Modify Agent Configuration"
@@ -812,13 +829,13 @@ show_menu() {
printf " printf "
${green}Nezha Monitor Management Script${plain} ${red}${NZ_VERSION}${plain} ${green}Nezha Monitor Management Script${plain} ${red}${NZ_VERSION}${plain}
--- https://github.com/naiba/nezha --- --- https://github.com/naiba/nezha ---
${green}1.${plain} Install Panel ${green}1.${plain} Install Dashboard
${green}2.${plain} Modify Panel Configuration ${green}2.${plain} Modify Dashbaord Configuration
${green}3.${plain} Start Panel ${green}3.${plain} Start Dashboard
${green}4.${plain} Stop Panel ${green}4.${plain} Stop Dashboard
${green}5.${plain} Restart and Update the Panel ${green}5.${plain} Restart and Update Dashboard
${green}6.${plain} View Panel Log ${green}6.${plain} View Dashboard Log
${green}7.${plain} Uninstall Panel ${green}7.${plain} Uninstall Dashboard
————————————————- ————————————————-
${green}8.${plain} Install Agent ${green}8.${plain} Install Agent
${green}9.${plain} Modify Agent Configuration ${green}9.${plain} Modify Agent Configuration
@@ -934,4 +951,4 @@ if [ $# -gt 0 ]; then
else else
select_version select_version
show_menu show_menu
fi fi
+7 -1
View File
@@ -5,7 +5,7 @@ import (
"sync" "sync"
"github.com/libdns/cloudflare" "github.com/libdns/cloudflare"
"github.com/libdns/tencentcloud" tencentcloud "github.com/nezhahq/libdns-tencentcloud"
"github.com/naiba/nezha/model" "github.com/naiba/nezha/model"
ddns2 "github.com/naiba/nezha/pkg/ddns" ddns2 "github.com/naiba/nezha/pkg/ddns"
@@ -20,6 +20,7 @@ var (
func initDDNS() { func initDDNS() {
OnDDNSUpdate() OnDDNSUpdate()
OnNameserverUpdate()
} }
func OnDDNSUpdate() { func OnDDNSUpdate() {
@@ -33,6 +34,10 @@ func OnDDNSUpdate() {
} }
} }
func OnNameserverUpdate() {
ddns2.InitDNSServers(Conf.DNSServers)
}
func GetDDNSProvidersFromProfiles(profileId []uint64, ip *ddns2.IP) ([]*ddns2.Provider, error) { func GetDDNSProvidersFromProfiles(profileId []uint64, ip *ddns2.IP) ([]*ddns2.Provider, error) {
profiles := make([]*model.DDNSProfile, 0, len(profileId)) profiles := make([]*model.DDNSProfile, 0, len(profileId))
ddnsCacheLock.RLock() ddnsCacheLock.RLock()
@@ -40,6 +45,7 @@ func GetDDNSProvidersFromProfiles(profileId []uint64, ip *ddns2.IP) ([]*ddns2.Pr
if profile, ok := ddnsCache[id]; ok { if profile, ok := ddnsCache[id]; ok {
profiles = append(profiles, profile) profiles = append(profiles, profile)
} else { } else {
ddnsCacheLock.RUnlock()
return nil, fmt.Errorf("无法找到DDNS配置 ID %d", id) return nil, fmt.Errorf("无法找到DDNS配置 ID %d", id)
} }
} }