diff --git a/.goreleaser.yml b/.goreleaser.yml index 81c8f4f..51b9751 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,7 +16,7 @@ checksum: snapshot: name_template: "{{.ProjectName}}" archives: - - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}" + - name_template: "nezha-agent_{{ .Os }}_{{ .Arch }}" changelog: sort: asc filters: diff --git a/cmd/agent/main.go b/cmd/agent/main.go index c936310..fd8bba6 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -8,6 +8,8 @@ import ( "os" "time" + "github.com/blang/semver" + "github.com/rhysd/go-github-selfupdate/selfupdate" "github.com/spf13/cobra" "google.golang.org/grpc" @@ -19,6 +21,12 @@ import ( ) var ( + clientID string + server string + clientSecret string + debug bool + version string + rootCmd = &cobra.Command{ Use: "nezha-agent", Short: "「哪吒面板」监控、备份、站点管理一站式服务", @@ -26,14 +34,31 @@ var ( ================================ 监控、备份、站点管理一站式服务 啦啦啦,啦啦啦,我是 mjj 小行家`, - Run: run, + Run: run, + Version: version, } - clientID string - server string - clientSecret string - debug bool ) +func doSelfUpdate() { + defer func() { + time.Sleep(time.Minute * 20) + updateCh <- struct{}{} + }() + v := semver.MustParse(version) + latest, err := selfupdate.UpdateSelf(v, "naiba/nezha") + if err != nil { + log.Println("Binary update failed:", err) + return + } + if latest.Version.Equals(v) { + // latest version is the same as current version. It means current binary is up to date. + log.Println("Current binary is the latest version", version) + } else { + log.Println("Successfully updated to version", latest.Version) + log.Println("Release note:\n", latest.ReleaseNotes) + } +} + func main() { rootCmd.PersistentFlags().StringVarP(&server, "server", "s", "localhost:5555", "客户端ID") rootCmd.PersistentFlags().StringVarP(&clientID, "id", "i", "", "客户端ID") @@ -50,6 +75,7 @@ var reporting bool var client pb.NezhaServiceClient var ctx = context.Background() var delayWhenError = time.Second * 10 +var updateCh = make(chan struct{}, 0) func run(cmd *cobra.Command, args []string) { dao.Conf = &model.Config{ @@ -63,6 +89,15 @@ func run(cmd *cobra.Command, args []string) { // 上报服务器信息 go reportState() + go func() { + for range updateCh { + log.Println("check update", version) + doSelfUpdate() + } + }() + + updateCh <- struct{}{} + var err error var conn *grpc.ClientConn var hc pb.NezhaService_HeartbeatClient diff --git a/go.mod b/go.mod index 663a149..b006555 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48 + github.com/blang/semver v3.5.1+incompatible github.com/fsnotify/fsnotify v1.4.9 github.com/gin-gonic/gin v1.6.3 github.com/golang/protobuf v1.4.2 @@ -14,6 +15,7 @@ require ( github.com/onsi/ginkgo v1.7.0 // indirect github.com/onsi/gomega v1.4.3 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/rhysd/go-github-selfupdate v1.2.2 github.com/shirou/gopsutil/v3 v3.20.10 github.com/spf13/cobra v0.0.5 github.com/spf13/viper v1.7.1 diff --git a/go.sum b/go.sum index 2a43e19..6ee6ca0 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -158,6 +160,8 @@ github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= +github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= +github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -205,6 +209,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= +github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= @@ -268,6 +274,7 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -290,6 +297,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rhysd/go-github-selfupdate v1.2.2 h1:G+mNzkc1wEtpmM6sFS/Ghkeq+ad4Yp6EZEHyp//wGEo= +github.com/rhysd/go-github-selfupdate v1.2.2/go.mod h1:khesvSyKcXDUxeySCedFh621iawCks0dS/QnHPcpCws= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= @@ -327,12 +336,16 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= +github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= +github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -426,6 +439,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -557,6 +571,7 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/script/install.sh b/script/install.sh index 0d49b85..1f6da2a 100755 --- a/script/install.sh +++ b/script/install.sh @@ -9,6 +9,7 @@ NZ_BASE_PATH="/opt/nezha" NZ_DASHBOARD_PATH="${NZ_BASE_PATH}/dashboard" NZ_AGENT_PATH="${NZ_BASE_PATH}/agent" +NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service" NZ_VERSION="v1.0.0" red='\033[0;31m' @@ -20,6 +21,12 @@ os_version="" os_arch="" pre_check() { + command -v systemctl >/dev/null 2>&1 + if [[ $? != 0 ]]; then + echo "不支持此系统:未找到 systemctl 命令" + exit 1 + fi + # check root [[ $EUID -ne 0 ]] && echo -e "${red}错误: ${plain} 必须使用root用户运行此脚本!\n" && exit 1 @@ -150,6 +157,8 @@ install_dashboard() { modify_dashboard_config 0 + echo "默认管理面板地址:域名:8008" + if [[ $# == 0 ]]; then before_show_menu fi @@ -167,14 +176,52 @@ install_agent() { if [[ $? != 0 ]]; then echo -e "正在下载监控端" cd $NZ_DASHBOARD_PATH - curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/docker-compose.yaml -o docker-compose.yaml >/dev/null 2>&1 + curl -L https://github.com/naiba/nezha/releases/latest/download/nezha-agent_linux_${os_arch}.tar.gz -o nezha-agent_linux_${os_arch}.tar.gz >/dev/null 2>&1 if [[ $? != 0 ]]; then - echo -e "${red}下载脚本失败,请检查本机能否连接 raw.githubusercontent.com${plain}" + echo -e "${red}Release 下载失败,请检查本机能否连接 github.com${plain}" return 0 fi + tar xf nezha-agent_linux_${os_arch}.tar.gz && + mv nezha-agent_linux_${os_arch}/nezha-agent $NZ_AGENT_PATH && + rm -rf nezha-agent_linux_${os_arch}* fi - modify_dashboard_config 0 + modify_agent_config 0 + + if [[ $# == 0 ]]; then + before_show_menu + fi +} + +modify_agent_config() { + echo -e "> 修改Agent配置" + + cd $NZ_DASHBOARD_PATH + curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/nezha-agent.service -o $NZ_AGENT_SERVICE >/dev/null 2>&1 + if [[ $? != 0 ]]; then + echo -e "${red}文件下载失败,请检查本机能否连接 raw.githubusercontent.com${plain}" + return 0 + fi + + echo "请先在管理面板上添加服务器,获取到ID和密钥" && + read -p "请输入一个解析到面板所在IP的域名(不可套CDN): " nezha_server_addr && + read -p "请输入Agent ID: " nezha_client_id && + read -p "请输入Agent 密钥: " nezha_client_secret + if [[ -z "${nezha_server_addr}" || -z "${nezha_client_id}" || -z "${nezha_client_secret}" ]]; then + echo -e "${red}所有选项都不能为空${plain}" + before_show_menu + return 1 + fi + + sed -i "s/^nezha_server_addr/${nezha_server_addr}/" ${NZ_AGENT_SERVICE} + sed -i "s/^nezha_client_id/${nezha_client_id}/" ${NZ_AGENT_SERVICE} + sed -i "s/^nezha_client_secret/${nezha_client_secret}/" ${NZ_AGENT_SERVICE} + + echo -e "Agent配置 ${green}修改成功,请稍等重启生效${plain}" + + systemctl daemon-reload + systemctl enable nezha-agent + systemctl restart nezha-agent if [[ $# == 0 ]]; then before_show_menu @@ -280,7 +327,9 @@ show_usage() { echo "./nbdomain.sh stop_dashboard - 停止面板" echo "./nbdomain.sh restart_dashboard - 重启面板" echo "./nbdomain.sh show_dashboard_log - 查看面板日志" + echo "------------------------------------------" echo "./nbdomain.sh install_agent - 安装监控Agent" + echo "./nbdomain.sh modify_agent_config - 修改Agent配置" echo "------------------------------------------" } @@ -298,6 +347,7 @@ show_menu() { ${green}6.${plain} 查看面板日志 ———————————————— ${green}7.${plain} 安装监控Agent + ${green}8.${plain} 修改Agent配置 " echo && read -p "请输入选择 [0-14]: " num @@ -357,6 +407,9 @@ if [[ $# > 0 ]]; then "install_agent") install_agent 0 ;; + "modify_agent_config") + modify_agent_config 0 + ;; *) show_usage ;; esac else diff --git a/script/nezha-agent.service b/script/nezha-agent.service index 0b3618c..9068af2 100644 --- a/script/nezha-agent.service +++ b/script/nezha-agent.service @@ -15,7 +15,7 @@ Type=simple User=root Group=root WorkingDirectory=/opt/nezha/agent/ -ExecStart=/opt/nezha/agent/nezha-agent-linux-amd64 -d -s nezha_server_addr -i nezha_client_id -p nezha_client_secret +ExecStart=/opt/nezha/agent/nezha-agent-linux-amd64 -d -s nezha_server_addr:5555 -i nezha_client_id -p nezha_client_secret Restart=always #Environment=DEBUG=true