diff --git a/settings/pkg/command/root.go b/settings/pkg/command/root.go index e952d28188..be06943a9a 100644 --- a/settings/pkg/command/root.go +++ b/settings/pkg/command/root.go @@ -69,15 +69,9 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error { if err != nil { return err } - - // load all env variables relevant to the config in the current context. conf.LoadOSEnv(config.GetEnv(), false) - - if err = cfg.UnmapEnv(conf); err != nil { - return err - } - - return nil + bindings := config.StructMappings(cfg) + return ociscfg.BindEnv(conf, bindings) } // SutureService allows for the settings command to be embedded and supervised by a suture supervisor tree. @@ -87,11 +81,7 @@ type SutureService struct { // NewSutureService creates a new settings.SutureService func NewSutureService(cfg *ociscfg.Config) suture.Service { - inheritLogging(cfg) - if cfg.Mode == 0 { - cfg.Settings.Supervised = true - } - cfg.Settings.Log.File = cfg.Log.File + cfg.Settings.Log = cfg.Log return SutureService{ cfg: cfg.Settings, } @@ -105,13 +95,3 @@ func (s SutureService) Serve(ctx context.Context) error { return nil } - -// inheritLogging is a poor man's global logging state tip-toeing around circular dependencies. It sets the logging -// of the service to whatever is in the higher config (in this case coming from ocis.yaml) and sets them as defaults, -// being overwritten when the extension parses its config file / env variables. -func inheritLogging(cfg *ociscfg.Config) { - cfg.Settings.Log.File = cfg.Log.File - cfg.Settings.Log.Color = cfg.Log.Color - cfg.Settings.Log.Pretty = cfg.Log.Pretty - cfg.Settings.Log.Level = cfg.Log.Level -} diff --git a/settings/pkg/command/server.go b/settings/pkg/command/server.go index 894b159ff7..e8215fe7d2 100644 --- a/settings/pkg/command/server.go +++ b/settings/pkg/command/server.go @@ -25,11 +25,7 @@ func Server(cfg *config.Config) *cli.Command { cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/") } - if err := ParseConfig(ctx, cfg); err != nil { - return err - } - - return nil + return ParseConfig(ctx, cfg) }, Action: func(c *cli.Context) error { logger := NewLogger(cfg) diff --git a/settings/pkg/config/config.go b/settings/pkg/config/config.go index b6d3f29e7d..62da7e7781 100644 --- a/settings/pkg/config/config.go +++ b/settings/pkg/config/config.go @@ -2,23 +2,13 @@ package config import ( "context" - "fmt" "path" - "reflect" - gofig "github.com/gookit/config/v2" + "github.com/owncloud/ocis/ocis-pkg/shared" "github.com/owncloud/ocis/ocis-pkg/config/defaults" ) -// Log defines the available logging configuration. -type Log struct { - Level string - Pretty bool - Color bool - File string -} - // Debug defines the available debug configuration. type Debug struct { Addr string @@ -80,7 +70,7 @@ type TokenManager struct { type Config struct { File string Service Service - Log Log + Log shared.Log Debug Debug HTTP HTTP GRPC GRPC @@ -100,7 +90,7 @@ func New() *Config { // DefaultConfig provides sane bootstrapping defaults. func DefaultConfig() *Config { return &Config{ - Log: Log{}, + Log: shared.Log{}, Service: Service{ Name: "settings", DataPath: path.Join(defaults.BaseDataPath(), "settings"), @@ -153,38 +143,3 @@ func GetEnv() []string { return r } - -// UnmapEnv loads values from the gooconf.Config argument and sets them in the expected destination. -func (c *Config) UnmapEnv(gooconf *gofig.Config) error { - vals := structMappings(c) - for i := range vals { - for j := range vals[i].EnvVars { - // we need to guard against v != "" because this is the condition that checks that the value is set from the environment. - // the `ok` guard is not enough, apparently. - if v, ok := gooconf.GetValue(vals[i].EnvVars[j]); ok && v != "" { - - // get the destination type from destination - switch reflect.ValueOf(vals[i].Destination).Type().String() { - case "*bool": - r := gooconf.Bool(vals[i].EnvVars[j]) - *vals[i].Destination.(*bool) = r - case "*string": - r := gooconf.String(vals[i].EnvVars[j]) - *vals[i].Destination.(*string) = r - case "*int": - r := gooconf.Int(vals[i].EnvVars[j]) - *vals[i].Destination.(*int) = r - case "*float64": - // defaults to float64 - r := gooconf.Float(vals[i].EnvVars[j]) - *vals[i].Destination.(*float64) = r - default: - // it is unlikely we will ever get here. Let this serve more as a runtime check for when debugging. - return fmt.Errorf("invalid type for env var: `%v`", vals[i].EnvVars[j]) - } - } - } - } - - return nil -} diff --git a/settings/pkg/config/env.go b/settings/pkg/config/mappings.go similarity index 83% rename from settings/pkg/config/env.go rename to settings/pkg/config/mappings.go index 0160dd8737..f37e05b848 100644 --- a/settings/pkg/config/env.go +++ b/settings/pkg/config/mappings.go @@ -1,13 +1,17 @@ package config -type mapping struct { - EnvVars []string // name of the EnvVars var. - Destination interface{} // memory address of the original config value to modify. +import "github.com/owncloud/ocis/ocis-pkg/shared" + +// StructMappings binds a set of environment variables to a destination on cfg. Iterating over this set and editing the +// Destination value of a binding will alter the original value, as it is a pointer to its memory address. This lets +// us propagate changes easier. +func StructMappings(cfg *Config) []shared.EnvBinding { + return structMappings(cfg) } // structMappings binds a set of environment variables to a destination on cfg. -func structMappings(cfg *Config) []mapping { - return []mapping{ +func structMappings(cfg *Config) []shared.EnvBinding { + return []shared.EnvBinding{ { EnvVars: []string{"SETTINGS_LOG_LEVEL", "OCIS_LOG_LEVEL"}, Destination: &cfg.Log.Level,