From 4593090d47c0c49b45a7e27040f95f4ad88fcae8 Mon Sep 17 00:00:00 2001 From: blylei Date: Sun, 24 Mar 2024 21:48:46 +0800 Subject: [PATCH] init --- admin/cmd/version/version.go | 2 + agent/cmd/version.go | 1 + cmd/frabit-server/cmd/version.go | 1 + go.mod | 6 +++ go.sum | 14 +++++++ pkg/common/version/version.go | 28 ++++++++++++++ pkg/server/router/router.go | 53 ++++++++++++++++++++++++++- pkg/server/server.go | 27 ++++++++++++-- pkg/services/notifications/webhook.go | 16 ++++++++ 9 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 pkg/services/notifications/webhook.go diff --git a/admin/cmd/version/version.go b/admin/cmd/version/version.go index 1830509..1cd6deb 100644 --- a/admin/cmd/version/version.go +++ b/admin/cmd/version/version.go @@ -17,6 +17,7 @@ package version import ( "fmt" + "github.com/frabits/frabit/pkg/common/cmdutil" "github.com/frabits/frabit/pkg/common/version" @@ -38,6 +39,7 @@ func NewVersionCmd() *cobra.Command { func runVersion(cmd *cobra.Command, args []string) { fmt.Printf("%s\n", version.InfoStr.String()) + version.CheckLatestVersion() } func init() { diff --git a/agent/cmd/version.go b/agent/cmd/version.go index d0aebcc..17c92e5 100644 --- a/agent/cmd/version.go +++ b/agent/cmd/version.go @@ -31,6 +31,7 @@ var newVersionCmd = &cobra.Command{ func runVersion(cmd *cobra.Command, args []string) { fmt.Printf("%s\n", version.InfoStr.String()) + version.CheckLatestVersion() } func init() { diff --git a/cmd/frabit-server/cmd/version.go b/cmd/frabit-server/cmd/version.go index 34981d8..e6a9574 100644 --- a/cmd/frabit-server/cmd/version.go +++ b/cmd/frabit-server/cmd/version.go @@ -32,6 +32,7 @@ var versionCmd = &cobra.Command{ func runVersion(cmd *cobra.Command, args []string) { fmt.Printf("%s\n", version.InfoStr.String()) + version.CheckLatestVersion() } func init() { diff --git a/go.mod b/go.mod index 3861358..5247762 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/ClickHouse/clickhouse-go/v2 v2.8.3 github.com/gin-gonic/gin v1.9.0 github.com/go-sql-driver/mysql v1.7.0 + github.com/google/go-github/v50 v50.2.0 github.com/pkg/errors v0.9.1 github.com/redis/go-redis/v9 v9.0.3 github.com/spf13/cobra v1.7.0 @@ -23,11 +24,13 @@ require ( require ( github.com/ClickHouse/ch-go v0.52.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/andybalholm/brotli v1.0.5 // indirect github.com/bytedance/sonic v1.8.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cloudflare/circl v1.1.0 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -41,6 +44,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -77,8 +81,10 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/net v0.10.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.10.0 // indirect + google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 5d795fb..fe3aebf 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,8 @@ github.com/ClickHouse/ch-go v0.52.1 h1:nucdgfD1BDSHjbNaG3VNebonxJzD8fX8jbuBpfo5V github.com/ClickHouse/ch-go v0.52.1/go.mod h1:B9htMJ0hii/zrC2hljUKdnagRBuLqtRG/GrU3jqCwRk= github.com/ClickHouse/clickhouse-go/v2 v2.8.3 h1:R6na3RNq/4vEEwfwkxQYrWOf21T9HMhGmE8mhkhq7TI= github.com/ClickHouse/clickhouse-go/v2 v2.8.3/go.mod h1:teXfZNM90iQ99Jnuht+dxQXCuhDZ8nvvMoTJOFrcmcg= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= @@ -49,6 +51,7 @@ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -62,6 +65,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -151,6 +156,10 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= +github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -316,6 +325,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= @@ -396,6 +406,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -445,6 +457,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= @@ -541,6 +554,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/pkg/common/version/version.go b/pkg/common/version/version.go index 34c7e32..935fe7f 100644 --- a/pkg/common/version/version.go +++ b/pkg/common/version/version.go @@ -16,9 +16,12 @@ package version import ( + "context" "fmt" "runtime" "strings" + + "github.com/google/go-github/v50/github" ) // initial version @@ -112,3 +115,28 @@ func (info Info) String() string { str := fmt.Sprintf("%s\n%s\n", info.versionString(), info.buildString()) return str } + +func getLatestVersion() string { + ghClient := github.NewClient(nil) + repo, _, err := ghClient.Repositories.GetLatestRelease(context.Background(), "frabits", "frabit") + if err != nil { + fmt.Errorf("cannot get latest version:%s", err) + return "" + } + return *repo.TagName +} + +func needToUpgrade(version, latest string) bool { + return latest != "" && (strings.TrimPrefix(latest, "v") != strings.TrimPrefix(version, "v")) +} + +func CheckLatestVersion() { + if version != "source" { + latest := getLatestVersion() + + if ok := needToUpgrade(version, latest); ok { + fmt.Printf("A newer version of the frabit is available,please upgrade to: %s\n", latest) + } + } + +} diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go index ff873a3..4071719 100644 --- a/pkg/server/router/router.go +++ b/pkg/server/router/router.go @@ -16,16 +16,65 @@ package router import ( + "context" "fmt" + "log" + "net/http" + "os/signal" + "syscall" "time" "github.com/gin-gonic/gin" ) -type Router struct { +type HttpServer struct { gin.Engine } -func (r *Router) Setup(g gin.RouterGroup) { +func init() { + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + + HttpServer := gin.Default() + + srv := &http.Server{ + Addr: ":8080", + Handler: HttpServer, + } + + // Initializing the server in a goroutine so that + // it won't block the graceful shutdown handling below + go func() { + if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Fatalf("listen: %s\n", err) + } + }() + + // Listen for the interrupt signal. + <-ctx.Done() + + // Restore default behavior on the interrupt signal and notify user of shutdown. + stop() + log.Println("shutting down gracefully, press Ctrl+C again to force") + + // The context is used to inform the server it has 5 seconds to finish + // the request it is currently handling + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := srv.Shutdown(ctx); err != nil { + log.Fatal("Server forced to shutdown: ", err) + } + + log.Println("Server exiting") +} +func (hs *HttpServer) Setup(g gin.RouterGroup) { + fmt.Println(time.Now().Format(time.RFC3339)) +} + +func (hs *HttpServer) Run(addr string) { + fmt.Println(time.Now().Format(time.RFC3339)) +} + +func (hs *HttpServer) Shutdown(ctx context.Context) { fmt.Println(time.Now().Format(time.RFC3339)) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 426db43..934a21e 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -51,9 +51,9 @@ type Server struct { backgroundServices []registry.BackgroundService - config config.Config - g router.Router - db *sql.DB + config config.Config + httpServer router.HttpServer + db *sql.DB } func (s *Server) init() error { @@ -115,6 +115,23 @@ func (s *Server) Run() error { return nil }) } + // finally, start http server + s.childRoutines.Go(func() error { + select { + case <-s.context.Done(): + return s.context.Err() + default: + } + s.log.Debug("Starting background service", zap.String("service", "httpserver")) + err := s.g.Run(":9180") + // Do not return context.Canceled error + if err != nil && errors.Is(err, context.Canceled) { + s.log.Error("Stopped background service", zap.Error(err)) + return fmt.Errorf("%s run error:%w", "httpserver", err) + } + s.log.Debug("Stopped background service", zap.String("service", "httpserver")) + return nil + }) s.notifySystemd("READY=1") s.log.Debug("Waiting on services...") return s.childRoutines.Wait() @@ -124,6 +141,10 @@ func (s *Server) Run() error { // Since Run blocks supposed to be run from a separate goroutine func (s *Server) Shutdown(ctx context.Context, reason string) error { var err error + // firstly, shutdown httpServer to avoid new http request + if err = s.g.Run(); err != nil { + return err + } s.shutdownOnce.Do(func() { s.log.Info("Shutdown started", zap.String("reason", reason)) // revoke cancel function to stop services diff --git a/pkg/services/notifications/webhook.go b/pkg/services/notifications/webhook.go new file mode 100644 index 0000000..b7a5346 --- /dev/null +++ b/pkg/services/notifications/webhook.go @@ -0,0 +1,16 @@ +// Frabit - The next-generation database automatic operation platform +// Copyright © 2022-2023 Blylei Frabit Labs +// +// Licensed under the GNU General Public License, Version 3.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.gnu.org/licenses/gpl-3.0.txt +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package notifications