diff --git a/.gitignore b/.gitignore index 910d051..4a20e21 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ ui/dist .env .test_keyfile test.db -shokku +./shokku .idea diff --git a/cmd/shokku/bootstrap.go b/cmd/shokku/bootstrap.go new file mode 100644 index 0000000..998b7d4 --- /dev/null +++ b/cmd/shokku/bootstrap.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "gitlab.com/texm/shokku/internal/server" + "os" +) + +func bootstrapServer() { + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + + if err := server.Bootstrap(); err != nil { + log.Fatal().Err(err).Msg("failed to create key") + } +} diff --git a/cmd/shokku/dist/bleh b/cmd/shokku/dist/bleh new file mode 100644 index 0000000..e69de29 diff --git a/cmd/shokku/serve.go b/cmd/shokku/serve.go new file mode 100644 index 0000000..39e80e7 --- /dev/null +++ b/cmd/shokku/serve.go @@ -0,0 +1,83 @@ +package main + +import ( + "context" + "embed" + "io/fs" + "net" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "gitlab.com/texm/shokku/internal/env" + "gitlab.com/texm/shokku/internal/server" +) + +//go:embed all:dist/* +var embeddedFiles embed.FS + +func runServer() { + cfg, err := server.LoadConfig() + if err != nil { + log.Fatal().Err(err).Msg("failed to load config") + } + + zerolog.SetGlobalLevel(zerolog.InfoLevel) + if cfg.DebugMode { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) + } + + appFS, err := fs.Sub(embeddedFiles, ".") + if err != nil { + log.Fatal().Err(err).Msg("failed to create embedded fs") + } + + e, err := server.New(cfg, appFS) + if err != nil { + log.Fatal().Err(err).Msg("failed to create server service") + } + + address := net.JoinHostPort(cfg.Host, cfg.Port) + + s := &http.Server{ + Addr: address, + Handler: e.Router, + } + + defer shutdown(e, s) + + go serve(s) + log.Info().Msgf("Serving on %s", address) + + quit := make(chan os.Signal, 1) + defer close(quit) + + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit +} + +func serve(s *http.Server) { + if err := s.ListenAndServe(); err != http.ErrServerClosed { + log.Fatal().Err(err).Msg("Fatal server error") + } +} + +func shutdown(e *env.Env, s *http.Server) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + if err := e.Shutdown(); err != nil { + log.Error().Err(err).Msg("failed to shut down env") + } + + if err := s.Shutdown(ctx); err != nil { + log.Fatal().Err(err).Msg("failed to shut down server") + } + + log.Info().Msg("Shutdown server successfully") +} diff --git a/cmd/shokku/shokku.go b/cmd/shokku/shokku.go new file mode 100644 index 0000000..483d812 --- /dev/null +++ b/cmd/shokku/shokku.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/rs/zerolog/pkgerrors" + "math/rand" + "os" + "time" +) + +const ( + BootstrapCmd = "bootstrap" +) + +func main() { + rand.Seed(time.Now().UnixNano()) + + zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack + + if len(os.Args) <= 1 { + runServer() + return + } else { + switch cmd := os.Args[1]; cmd { + case BootstrapCmd: + bootstrapServer() + default: + log.Fatal().Msgf("invalid command '%s' provided", cmd) + } + } +}