diff --git a/server/internal/command/command.go b/server/internal/command/command.go index 08cd38bf..37a6deaf 100644 --- a/server/internal/command/command.go +++ b/server/internal/command/command.go @@ -2,6 +2,7 @@ package command import ( "errors" + "fmt" "os" "path" "strings" @@ -36,8 +37,8 @@ func SetupCommand() { flags := rootCmd.PersistentFlags() // Flags only. Not part of config file - flags.StringP("workdir", "W", "", "Set working directory") - flags.StringP("config-file", "c", "config.yml", "Set working directory") + flags.StringP("workdir", "W", "", "Working Directory") + flags.StringP("config-file", "c", "config.yml", "Config File Path") flags.Bool("debug", false, "Debug mode") flags.MarkHidden("debug") @@ -76,7 +77,9 @@ func SetupCommand() { if !f.Changed { return "", "" } - return strings.ReplaceAll(f.Name, "_", "."), posflag.FlagVal(cmd.Flags(), f) + k, v := strings.ReplaceAll(f.Name, "_", "."), posflag.FlagVal(cmd.Flags(), f) + fmt.Printf("%s: %v\n", k, v) + return k, v }), nil); err != nil { logrus.Fatalf("Unable to load flags: %v", err) } @@ -91,6 +94,7 @@ func SetupCommand() { db.Cfg = cfg.DB storage.Cfg = cfg.Storage + serve.Cfg = cfg.Server } defer func() { diff --git a/server/internal/command/config.go b/server/internal/command/config.go index 883c7c16..98949d60 100644 --- a/server/internal/command/config.go +++ b/server/internal/command/config.go @@ -1,6 +1,7 @@ package command import ( + "github.com/shroff/phylum/server/internal/command/serve" "github.com/shroff/phylum/server/internal/core/db" "github.com/shroff/phylum/server/internal/core/storage" ) @@ -19,15 +20,15 @@ var defaultConfig = Config{ Storage: storage.Config{ Location: "storage", }, - Server: ServerConfig{ + Server: serve.Config{ Host: "", Port: 2448, WebAppSrc: "web", PublinkPath: "/publink", WebDAVPath: "/webdav", - CORS: CORSConfig{ + CORS: serve.CORSConfig{ Enabled: false, - Orifins: []string{"*"}, + Origins: []string{"*"}, }, }, } @@ -36,19 +37,5 @@ type Config struct { Debug bool `koanf:"debug"` DB db.Config `koanf:"db"` Storage storage.Config `koanf:"storage"` - Server ServerConfig `koanf:"server"` -} - -type ServerConfig struct { - Host string `koanf:"host"` - Port int `koanf:"port"` - WebAppSrc string `koanf:"web_app_src"` - PublinkPath string `koanf:"publink_path"` - WebDAVPath string `koanf:"webdav_path"` - CORS CORSConfig `koanf:"cors"` -} - -type CORSConfig struct { - Enabled bool `koanf:"enabled"` - Orifins []string `koanf:"origins"` + Server serve.Config `koanf:"server"` } diff --git a/server/internal/command/serve/cmd.go b/server/internal/command/serve/cmd.go index c6698680..85d8ed26 100644 --- a/server/internal/command/serve/cmd.go +++ b/server/internal/command/serve/cmd.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "path" + "strconv" "time" "github.com/fvbock/endless" @@ -15,76 +16,58 @@ import ( "github.com/shroff/phylum/server/internal/core/fs" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/spf13/viper" ) const trashRetainDuration = 30 * 24 * time.Hour +var Cfg Config + func SetupCommand() *cobra.Command { var cmd = &cobra.Command{ Use: "serve", Short: "Run the server", GroupID: "server", - Run: func(cmd *cobra.Command, args []string) { - config := viper.Sub("server") - - flags := cmd.Flags() - // TODO: Hack. flag bindings don't work in viper for nested keys - config.BindPFlag("host", flags.Lookup("host")) - config.BindPFlag("port", flags.Lookup("port")) - config.BindPFlag("cors.enabled", flags.Lookup("cors-enabled")) - config.BindPFlag("cors.origins", flags.Lookup("cors-origins")) - config.BindPFlag("log_body", flags.Lookup("log-body")) - config.BindPFlag("web_app_src", flags.Lookup("web-app-src")) - config.BindPFlag("publink_path", flags.Lookup("publink-path")) - config.BindPFlag("webdav_path", flags.Lookup("webdav-path")) - - if !viper.GetBool("debug") { - gin.SetMode(gin.ReleaseMode) - } - engine := createEngine(config) - - webdav.SetupHandler(engine.Group(config.GetString("webdav_path"))) - apiv1.Setup(engine.Group("/api/v1")) - publink.Setup(engine.Group(config.GetString("publink_path"))) - - webAppSrcDir := config.GetString("web_app_src") - if webAppSrcDir != "" { - setupWebApp(engine, webAppSrcDir) - } - setupTrashCompactor() - - listen := config.GetString("host") + ":" + config.GetString("port") - server := endless.NewServer(listen, engine) - server.BeforeBegin = func(addr string) { - logrus.Info("Listening on " + addr) - } - - if err := server.ListenAndServe(); err != nil { - logrus.Fatal(err.Error()) - } - }, } + flags := cmd.Flags() - flags.String("host", "", "Server Host") - flags.String("port", "2448", "Server Port") - flags.Bool("cors-enabled", false, "Enable CORS") - flags.StringSlice("cors-origins", []string{"*"}, "CORS origins") - flags.Bool("log-body", false, "Log Response Body (Must be used with --debug)") - flags.String("web-app-src", "web", "Web App Source Directory") - flags.String("publink-path", "/publink", "Public Share path prefix") - flags.String("webdav-path", "/webdav", "WebDAV path prefix") + flags.Bool("db_trace", false, "Trace Database Queries") + flags.MarkHidden("db_trace") - // Must be specified otherwise env variables won't be parsed - viper.SetDefault("server.host", "") - viper.SetDefault("server.port", "2448") - viper.SetDefault("server.log_body", false) - viper.SetDefault("server.cors.enabled", false) - viper.SetDefault("server.cors.origins", []string{"*"}) - viper.SetDefault("server.web_app_src", "web") - viper.SetDefault("server.publink_path", "/publink") - viper.SetDefault("server.webdav_path", "/webdav") + flags.String("server_host", "", "Server Host") + flags.String("server_port", "", "Server Port") + flags.String("server_webappsrc", "", "Web App Source Directory") + flags.String("server_publinkpath", "", "Public Share path prefix") + flags.String("server_webdavpath", "", "WebDAV path prefix") + flags.Bool("server_cors_enabled", false, "Enable CORS") + flags.StringSlice("server_cors_origins", nil, "CORS origins") + flags.Bool("server_logbody", false, "Log Response Body (Must be used with --debug)") + + cmd.Run = func(cmd *cobra.Command, args []string) { + if !Cfg.Debug { + gin.SetMode(gin.ReleaseMode) + } + engine := createEngine() + + webdav.SetupHandler(engine.Group(Cfg.WebDAVPath)) + apiv1.Setup(engine.Group("/api/v1")) + publink.Setup(engine.Group(Cfg.PublinkPath)) + + if Cfg.WebAppSrc != "" { + setupWebApp(engine, Cfg.WebAppSrc) + } + setupTrashCompactor() + + listen := Cfg.Host + ":" + strconv.Itoa(Cfg.Port) + server := endless.NewServer(listen, engine) + server.BeforeBegin = func(addr string) { + logrus.Info("Listening on " + addr) + } + + if err := server.ListenAndServe(); err != nil { + logrus.Fatal(err.Error()) + } + } return cmd } diff --git a/server/internal/command/serve/config.go b/server/internal/command/serve/config.go new file mode 100644 index 00000000..8dd59e02 --- /dev/null +++ b/server/internal/command/serve/config.go @@ -0,0 +1,17 @@ +package serve + +type Config struct { + Host string `koanf:"host"` + Port int `koanf:"port"` + WebAppSrc string `koanf:"webappsrc"` + PublinkPath string `koanf:"publinkpath"` + WebDAVPath string `koanf:"webdavpath"` + CORS CORSConfig `koanf:"cors"` + Debug bool `koanf:"debug"` + LogBody bool `koanf:"logbody"` +} + +type CORSConfig struct { + Enabled bool `koanf:"enabled"` + Origins []string `koanf:"origins"` +} diff --git a/server/internal/command/serve/engine.go b/server/internal/command/serve/engine.go index 58771530..6bd1a593 100644 --- a/server/internal/command/serve/engine.go +++ b/server/internal/command/serve/engine.go @@ -9,11 +9,10 @@ import ( "github.com/gin-gonic/gin" "github.com/shroff/phylum/server/internal/core/errors" "github.com/sirupsen/logrus" - "github.com/spf13/viper" ) // func createEngine(logBody bool, corsEnabled bool, corsOrigins []string) *gin.Engine { -func createEngine(config *viper.Viper) *gin.Engine { +func createEngine() *gin.Engine { engine := gin.New() engine.Use(gin.Logger(), gin.CustomRecovery(func(c *gin.Context, err any) { c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ @@ -22,12 +21,12 @@ func createEngine(config *viper.Viper) *gin.Engine { "msg": "Internal Server Error", }) })) - if config.GetBool("log_body") { + if Cfg.LogBody { engine.Use(logBodyMiddleware) } - if config.GetBool("cors.enabled") { - origins := config.GetStringSlice("cors.origins") + if Cfg.CORS.Enabled { + origins := Cfg.CORS.Origins logrus.Info("Enabling cors (" + strings.Join(origins, ", ") + ")") engine.Use(cors.New(cors.Config{ AllowOrigins: origins,