update
parent
14a5cf1615
commit
977436d334
2
Makefile
2
Makefile
|
@ -5,4 +5,4 @@ run:
|
||||||
APP_LOG_PRETTY=true \
|
APP_LOG_PRETTY=true \
|
||||||
APP_DB_TYPE=sqlite \
|
APP_DB_TYPE=sqlite \
|
||||||
APP_DATA=work \
|
APP_DATA=work \
|
||||||
go run cmd/test/main.go
|
go test
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
|
||||||
}
|
|
|
@ -13,6 +13,26 @@ func init() {
|
||||||
viper.SetDefault("email.password", "test")
|
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
|
// host string, port int, username string, password string
|
||||||
var dial *gomail.Dialer
|
var dial *gomail.Dialer
|
||||||
|
|
||||||
|
|
|
@ -46,3 +46,7 @@ func (h *History) Grp(grp string) *History {
|
||||||
h.Group = grp
|
h.Group = grp
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
func (h *History) Scp(sco string) *History {
|
||||||
|
h.Scope = sco
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package history
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -25,14 +26,16 @@ type History struct {
|
||||||
Type string
|
Type string
|
||||||
Caller string
|
Caller string
|
||||||
Trace string
|
Trace string
|
||||||
|
BodyJson string
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
Message string
|
Message string
|
||||||
Body interface{} `gorm:"-"`
|
Body interface{} `gorm:"-"`
|
||||||
Issuer string
|
Issuer string
|
||||||
|
// Group to identify auth, empty for admin
|
||||||
Group string
|
Group string
|
||||||
|
// Scope for users to narrow down view point
|
||||||
BodyJson string
|
Scope string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *History) BeforeCreate(tx *gorm.DB) (err error) {
|
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 Tunnel chan *History
|
||||||
var quit chan struct{}
|
var quit chan struct{}
|
||||||
var started chan struct{}
|
var started chan struct{}
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Tunnel = make(chan *History)
|
Tunnel = make(chan *History)
|
||||||
|
@ -56,19 +60,20 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(r Receiver) {
|
func Start(r Receiver) {
|
||||||
select {
|
if len(started) == 1 {
|
||||||
case started <- struct{}{}:
|
|
||||||
default:
|
|
||||||
panic(errors.New(500, "history reporter has already started!"))
|
panic(errors.New(500, "history reporter has already started!"))
|
||||||
}
|
}
|
||||||
|
started <- struct{}{}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case h := <-Tunnel:
|
case h := <-Tunnel:
|
||||||
|
wg.Add(1)
|
||||||
if Interceptor != nil {
|
if Interceptor != nil {
|
||||||
go Interceptor(h)
|
Interceptor(h)
|
||||||
}
|
}
|
||||||
r(h)
|
r(h)
|
||||||
|
wg.Done()
|
||||||
case <-quit:
|
case <-quit:
|
||||||
<-started
|
<-started
|
||||||
return
|
return
|
||||||
|
@ -79,9 +84,15 @@ func Start(r Receiver) {
|
||||||
|
|
||||||
func Stop() {
|
func Stop() {
|
||||||
quit <- struct{}{}
|
quit <- struct{}{}
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Send(h *History) {
|
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 == "" {
|
if h.Type == "" {
|
||||||
h.Type = INFO
|
h.Type = INFO
|
||||||
}
|
}
|
||||||
|
@ -95,7 +106,9 @@ var Interceptor func(*History) = nil
|
||||||
var DBReceiver Receiver = func(h *History) {
|
var DBReceiver Receiver = func(h *History) {
|
||||||
err := store.DB.Create(h).Error
|
err := store.DB.Create(h).Error
|
||||||
if err != nil {
|
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,9 @@ import (
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"kumoly.io/kumoly/app/store"
|
"kumoly.io/kumoly/app/store"
|
||||||
"kumoly.io/kumoly/app/system"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
system.BaseService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv Service) GetName() string { return "history.Service" }
|
func (srv Service) GetName() string { return "history.Service" }
|
||||||
|
@ -34,3 +32,6 @@ func (srv Service) Main() error {
|
||||||
func (srv Service) Del() {
|
func (srv Service) Del() {
|
||||||
Stop()
|
Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv Service) Load() error { return nil }
|
||||||
|
func (srv Service) Health() error { return nil }
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package main
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"kumoly.io/kumoly/app/auth"
|
"kumoly.io/kumoly/app/auth"
|
||||||
|
"kumoly.io/kumoly/app/control"
|
||||||
"kumoly.io/kumoly/app/email"
|
"kumoly.io/kumoly/app/email"
|
||||||
"kumoly.io/kumoly/app/history"
|
"kumoly.io/kumoly/app/history"
|
||||||
"kumoly.io/kumoly/app/server"
|
"kumoly.io/kumoly/app/server"
|
||||||
|
@ -10,7 +13,7 @@ import (
|
||||||
"kumoly.io/kumoly/app/task"
|
"kumoly.io/kumoly/app/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func TestMain(t *testing.T) {
|
||||||
store.Setup()
|
store.Setup()
|
||||||
sys := system.New()
|
sys := system.New()
|
||||||
server := server.New("app")
|
server := server.New("app")
|
||||||
|
@ -20,8 +23,11 @@ func main() {
|
||||||
|
|
||||||
sys.Inject(auth.Injector(server.API))
|
sys.Inject(auth.Injector(server.API))
|
||||||
sys.Append(server, auth.New(server),
|
sys.Append(server, auth.New(server),
|
||||||
&task.Service{}, &history.Service{},
|
&task.Service{},
|
||||||
&email.Service{})
|
&history.Service{},
|
||||||
|
&email.Service{},
|
||||||
|
&control.Service{},
|
||||||
|
)
|
||||||
go sys.Start()
|
go sys.Start()
|
||||||
|
|
||||||
<-sys.Done()
|
<-sys.Done()
|
2
run.sh
2
run.sh
|
@ -6,4 +6,4 @@ export APP_PROD=false
|
||||||
export APP_LOG_PRETTY=true
|
export APP_LOG_PRETTY=true
|
||||||
export APP_DB_TYPE=sqlite
|
export APP_DB_TYPE=sqlite
|
||||||
export APP_DATA=work
|
export APP_DATA=work
|
||||||
go run cmd/test/main.go
|
go test
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"kumoly.io/kumoly/app/history"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SkipLogFunc func(c *gin.Context) bool
|
type SkipLogFunc func(c *gin.Context) bool
|
||||||
|
@ -23,6 +24,9 @@ type Service struct {
|
||||||
l zerolog.Logger
|
l zerolog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Server *gin.Engine
|
||||||
|
var API *gin.RouterGroup
|
||||||
|
|
||||||
func New(name string) *Service {
|
func New(name string) *Service {
|
||||||
if viper.GetBool("prod") {
|
if viper.GetBool("prod") {
|
||||||
gin.SetMode(gin.ReleaseMode)
|
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")),
|
Addr: fmt.Sprintf("%s:%s", viper.GetString("server.host"), viper.GetString("server.port")),
|
||||||
}
|
}
|
||||||
srv.Server.Use(srv.Default)
|
srv.Server.Use(srv.Default)
|
||||||
|
Server = srv.Server
|
||||||
srv.API = srv.Server.Group("/api")
|
srv.API = srv.Server.Group("/api")
|
||||||
|
API = srv.API
|
||||||
if ipnetstr := viper.GetString("server.allow"); ipnetstr != "" {
|
if ipnetstr := viper.GetString("server.allow"); ipnetstr != "" {
|
||||||
_, ipnet, err := net.ParseCIDR(ipnetstr)
|
_, ipnet, err := net.ParseCIDR(ipnetstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -56,6 +62,7 @@ func (srv *Service) Main() error {
|
||||||
go func() {
|
go func() {
|
||||||
err := srv.Server.Run(srv.Addr)
|
err := srv.Server.Run(srv.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
history.Send(history.Error().Nm("ServerStartError").Msg(err.Error()))
|
||||||
srv.l.Panic().Err(err).Msg("Server.Run error")
|
srv.l.Panic().Err(err).Msg("Server.Run error")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"kumoly.io/kumoly/app/history"
|
||||||
)
|
)
|
||||||
|
|
||||||
var PROD = true
|
var PROD = true
|
||||||
|
@ -98,7 +99,7 @@ func New() *System {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sys *System) Start() {
|
func (sys *System) Start() {
|
||||||
// Setup()
|
Setup()
|
||||||
sys.order()
|
sys.order()
|
||||||
sys.status = sys_init
|
sys.status = sys_init
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -125,11 +126,12 @@ func (sys *System) Start() {
|
||||||
|
|
||||||
sys.status = sys_main
|
sys.status = sys_main
|
||||||
sys.main()
|
sys.main()
|
||||||
if !sys.isService {
|
|
||||||
sys.status = sys_wait
|
sys.status = sys_wait
|
||||||
|
if !sys.isService {
|
||||||
sys.quit <- syscall.SIGTERM
|
sys.quit <- syscall.SIGTERM
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
history.Send(history.Info().Nm("SysUP").Msg("system started"))
|
||||||
<-sys.quit
|
<-sys.quit
|
||||||
isRestart := false
|
isRestart := false
|
||||||
if sys.status == sys_restart {
|
if sys.status == sys_restart {
|
||||||
|
@ -137,6 +139,7 @@ func (sys *System) Start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Info().Msg("Terminating...")
|
l.Info().Msg("Terminating...")
|
||||||
|
history.Send(history.Info().Nm("SysDown").Msg("system stoped"))
|
||||||
sys.status = sys_term
|
sys.status = sys_term
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(time.Second * time.Duration(viper.GetInt("system.terminate_timeout")))
|
time.Sleep(time.Second * time.Duration(viper.GetInt("system.terminate_timeout")))
|
||||||
|
|
|
@ -37,7 +37,7 @@ type Profile struct {
|
||||||
|
|
||||||
func GetProfile() *Profile {
|
func GetProfile() *Profile {
|
||||||
p := &Profile{
|
p := &Profile{
|
||||||
Name: "core/task",
|
Name: "task",
|
||||||
}
|
}
|
||||||
entries := c.Entries()
|
entries := c.Entries()
|
||||||
for i := 0; i < len(entries); i++ {
|
for i := 0; i < len(entries); i++ {
|
||||||
|
|
Loading…
Reference in New Issue