From 977436d334787fa500e64307eb26974844f4cfe6 Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Fri, 17 Dec 2021 15:52:32 +0800 Subject: [PATCH] update --- Makefile | 2 +- control/service.go | 44 ++++++++++++++++++++++++++++++++ email/base.go | 21 --------------- email/email.go | 20 +++++++++++++++ email/{ => ref}/base.gohtml.bak | 0 email/{ => ref}/text.tmpl | 0 history/helper.go | 4 +++ history/history.go | 29 +++++++++++++++------ history/service.go | 5 ++-- cmd/test/main.go => main_test.go | 14 +++++++--- run.sh | 2 +- server/service.go | 7 +++++ system/system.go | 7 +++-- task/profile.go | 2 +- 14 files changed, 117 insertions(+), 40 deletions(-) create mode 100644 control/service.go delete mode 100644 email/base.go rename email/{ => ref}/base.gohtml.bak (100%) rename email/{ => ref}/text.tmpl (100%) rename cmd/test/main.go => main_test.go (71%) diff --git a/Makefile b/Makefile index 054ab4f..3b9497f 100644 --- a/Makefile +++ b/Makefile @@ -5,4 +5,4 @@ run: APP_LOG_PRETTY=true \ APP_DB_TYPE=sqlite \ APP_DATA=work \ - go run cmd/test/main.go \ No newline at end of file + go test \ No newline at end of file diff --git a/control/service.go b/control/service.go new file mode 100644 index 0000000..0c26600 --- /dev/null +++ b/control/service.go @@ -0,0 +1,44 @@ +package control + +import ( + "encoding/json" + + "github.com/gin-gonic/gin" + "kumoly.io/kumoly/app/auth" + "kumoly.io/kumoly/app/server" + "kumoly.io/kumoly/app/system" + "kumoly.io/kumoly/app/task" +) + +type Service struct{} + +func (srv Service) GetName() string { return "ctrl.Service" } +func (srv Service) GetDependencies() []string { return []string{"server.Service", "auth.Auth"} } +func (srv Service) IsService() bool { return true } +func (srv Service) Init() error { return nil } +func (srv Service) Main() error { return nil } +func (srv Service) Del() {} +func (srv Service) Health() error { return nil } + +func (srv Service) Load() error { + ctlAPI := server.API.Group("ctrl") + ctlAPI.GET("prof", auth.ACAdmin(), func(c *gin.Context) { + server.OK(c, system.GetProfile()) + }) + ctlAPI.GET("config", auth.ACAdmin(), func(c *gin.Context) { + conf, err := system.ConfigShow("json") + if err != nil { + panic(err) + } + data := map[string]interface{}{} + if err := json.Unmarshal([]byte(conf), data); err != nil { + panic(err) + } + server.OK(c, data) + }) + + ctlAPI.GET("tasks", auth.ACAdmin(), func(c *gin.Context) { + server.OK(c, task.GetProfile()) + }) + return nil +} diff --git a/email/base.go b/email/base.go deleted file mode 100644 index 82f4a22..0000000 --- a/email/base.go +++ /dev/null @@ -1,21 +0,0 @@ -package email - -type App struct { - Name string - Link string - Logo string - Copyright string -} - -type Body struct { - App App - Intros []string - Outros []string - Content string - - Greeting string - Receiver string - - Signature string - Sender string -} diff --git a/email/email.go b/email/email.go index 9ee4720..b8c7e17 100644 --- a/email/email.go +++ b/email/email.go @@ -13,6 +13,26 @@ func init() { viper.SetDefault("email.password", "test") } +type App struct { + Name string + Link string + Logo string + Copyright string +} + +type Body struct { + App App + Intros []string + Outros []string + Content string + + Greeting string + Receiver string + + Signature string + Sender string +} + // host string, port int, username string, password string var dial *gomail.Dialer diff --git a/email/base.gohtml.bak b/email/ref/base.gohtml.bak similarity index 100% rename from email/base.gohtml.bak rename to email/ref/base.gohtml.bak diff --git a/email/text.tmpl b/email/ref/text.tmpl similarity index 100% rename from email/text.tmpl rename to email/ref/text.tmpl diff --git a/history/helper.go b/history/helper.go index 0fc3761..ddae37c 100644 --- a/history/helper.go +++ b/history/helper.go @@ -46,3 +46,7 @@ func (h *History) Grp(grp string) *History { h.Group = grp return h } +func (h *History) Scp(sco string) *History { + h.Scope = sco + return h +} diff --git a/history/history.go b/history/history.go index fa690a2..7ab953a 100644 --- a/history/history.go +++ b/history/history.go @@ -3,6 +3,7 @@ package history import ( "encoding/json" "fmt" + "sync" "time" "github.com/rs/zerolog/log" @@ -25,14 +26,16 @@ type History struct { Type string Caller string Trace string + BodyJson string Name string Message string Body interface{} `gorm:"-"` Issuer string - Group string - - BodyJson string + // Group to identify auth, empty for admin + Group string + // Scope for users to narrow down view point + Scope string } func (h *History) BeforeCreate(tx *gorm.DB) (err error) { @@ -48,6 +51,7 @@ func (h *History) BeforeCreate(tx *gorm.DB) (err error) { var Tunnel chan *History var quit chan struct{} var started chan struct{} +var wg sync.WaitGroup func init() { Tunnel = make(chan *History) @@ -56,19 +60,20 @@ func init() { } func Start(r Receiver) { - select { - case started <- struct{}{}: - default: + if len(started) == 1 { panic(errors.New(500, "history reporter has already started!")) } + started <- struct{}{} go func() { for { select { case h := <-Tunnel: + wg.Add(1) if Interceptor != nil { - go Interceptor(h) + Interceptor(h) } r(h) + wg.Done() case <-quit: <-started return @@ -79,9 +84,15 @@ func Start(r Receiver) { func Stop() { quit <- struct{}{} + wg.Wait() } func Send(h *History) { + if len(started) == 0 { + log.Warn().Str("mod", "history"). + Interface("history", h). + Msg("history reporter has not started, report will be discarded") + } if h.Type == "" { h.Type = INFO } @@ -95,7 +106,9 @@ var Interceptor func(*History) = nil var DBReceiver Receiver = func(h *History) { err := store.DB.Create(h).Error if err != nil { - log.Error().Str("mod", "history").Err(err).Msg("DBReceiver error") + log.Error().Str("mod", "history"). + Interface("history", h). + Err(err).Msg("DBReceiver error") } } diff --git a/history/service.go b/history/service.go index e05f3d6..bc6e54a 100644 --- a/history/service.go +++ b/history/service.go @@ -4,11 +4,9 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/viper" "kumoly.io/kumoly/app/store" - "kumoly.io/kumoly/app/system" ) type Service struct { - system.BaseService } func (srv Service) GetName() string { return "history.Service" } @@ -34,3 +32,6 @@ func (srv Service) Main() error { func (srv Service) Del() { Stop() } + +func (srv Service) Load() error { return nil } +func (srv Service) Health() error { return nil } diff --git a/cmd/test/main.go b/main_test.go similarity index 71% rename from cmd/test/main.go rename to main_test.go index 4afed13..5b6e62b 100644 --- a/cmd/test/main.go +++ b/main_test.go @@ -1,7 +1,10 @@ -package main +package app import ( + "testing" + "kumoly.io/kumoly/app/auth" + "kumoly.io/kumoly/app/control" "kumoly.io/kumoly/app/email" "kumoly.io/kumoly/app/history" "kumoly.io/kumoly/app/server" @@ -10,7 +13,7 @@ import ( "kumoly.io/kumoly/app/task" ) -func main() { +func TestMain(t *testing.T) { store.Setup() sys := system.New() server := server.New("app") @@ -20,8 +23,11 @@ func main() { sys.Inject(auth.Injector(server.API)) sys.Append(server, auth.New(server), - &task.Service{}, &history.Service{}, - &email.Service{}) + &task.Service{}, + &history.Service{}, + &email.Service{}, + &control.Service{}, + ) go sys.Start() <-sys.Done() diff --git a/run.sh b/run.sh index e8149a4..4907e4d 100644 --- a/run.sh +++ b/run.sh @@ -6,4 +6,4 @@ export APP_PROD=false export APP_LOG_PRETTY=true export APP_DB_TYPE=sqlite export APP_DATA=work -go run cmd/test/main.go \ No newline at end of file +go test \ No newline at end of file diff --git a/server/service.go b/server/service.go index f432de4..d573fa6 100644 --- a/server/service.go +++ b/server/service.go @@ -8,6 +8,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/viper" + "kumoly.io/kumoly/app/history" ) type SkipLogFunc func(c *gin.Context) bool @@ -23,6 +24,9 @@ type Service struct { l zerolog.Logger } +var Server *gin.Engine +var API *gin.RouterGroup + func New(name string) *Service { if viper.GetBool("prod") { gin.SetMode(gin.ReleaseMode) @@ -34,7 +38,9 @@ func New(name string) *Service { Addr: fmt.Sprintf("%s:%s", viper.GetString("server.host"), viper.GetString("server.port")), } srv.Server.Use(srv.Default) + Server = srv.Server srv.API = srv.Server.Group("/api") + API = srv.API if ipnetstr := viper.GetString("server.allow"); ipnetstr != "" { _, ipnet, err := net.ParseCIDR(ipnetstr) if err != nil { @@ -56,6 +62,7 @@ func (srv *Service) Main() error { go func() { err := srv.Server.Run(srv.Addr) if err != nil { + history.Send(history.Error().Nm("ServerStartError").Msg(err.Error())) srv.l.Panic().Err(err).Msg("Server.Run error") } }() diff --git a/system/system.go b/system/system.go index 021af7d..6156027 100644 --- a/system/system.go +++ b/system/system.go @@ -10,6 +10,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/viper" + "kumoly.io/kumoly/app/history" ) var PROD = true @@ -98,7 +99,7 @@ func New() *System { } func (sys *System) Start() { - // Setup() + Setup() sys.order() sys.status = sys_init go func() { @@ -125,11 +126,12 @@ func (sys *System) Start() { sys.status = sys_main sys.main() + sys.status = sys_wait if !sys.isService { - sys.status = sys_wait sys.quit <- syscall.SIGTERM } }() + history.Send(history.Info().Nm("SysUP").Msg("system started")) <-sys.quit isRestart := false if sys.status == sys_restart { @@ -137,6 +139,7 @@ func (sys *System) Start() { } l.Info().Msg("Terminating...") + history.Send(history.Info().Nm("SysDown").Msg("system stoped")) sys.status = sys_term go func() { time.Sleep(time.Second * time.Duration(viper.GetInt("system.terminate_timeout"))) diff --git a/task/profile.go b/task/profile.go index 51bca41..2768b5e 100644 --- a/task/profile.go +++ b/task/profile.go @@ -37,7 +37,7 @@ type Profile struct { func GetProfile() *Profile { p := &Profile{ - Name: "core/task", + Name: "task", } entries := c.Entries() for i := 0; i < len(entries); i++ {