diff --git a/cmd/admin-handlers-config-kv.go b/cmd/admin-handlers-config-kv.go index fdbe021c0..a84822cbf 100644 --- a/cmd/admin-handlers-config-kv.go +++ b/cmd/admin-handlers-config-kv.go @@ -19,6 +19,7 @@ package cmd import ( "bytes" + "context" "encoding/json" "io" "net/http" @@ -78,6 +79,22 @@ func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Requ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } + + dynamic := config.SubSystemsDynamic.Contains(string(kvBytes)) + if dynamic { + applyDynamic(ctx, objectAPI, cfg, r, w) + } +} + +func applyDynamic(ctx context.Context, objectAPI ObjectLayer, cfg config.Config, r *http.Request, w http.ResponseWriter) { + // Apply dynamic values. + if err := applyDynamicConfig(GlobalContext, objectAPI, cfg); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + globalNotificationSys.SignalService(serviceReloadDynamic) + // Tell the client that dynamic config was applied. + w.Header().Set(madmin.ConfigAppliedHeader, madmin.ConfigAppliedTrue) } // SetConfigKVHandler - PUT /minio/admin/v3/set-config-kv @@ -135,14 +152,7 @@ func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Requ } if dynamic { - // Apply dynamic values. - if err := applyDynamicConfig(GlobalContext, objectAPI, cfg); err != nil { - writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) - return - } - globalNotificationSys.SignalService(serviceReloadDynamic) - // If all values were dynamic, tell the client. - w.Header().Set(madmin.ConfigAppliedHeader, madmin.ConfigAppliedTrue) + applyDynamic(ctx, objectAPI, cfg, r, w) } writeSuccessResponseHeadersOnly(w) } diff --git a/internal/config/config.go b/internal/config/config.go index 3d95acc3d..c9bc5a682 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -217,6 +217,20 @@ func (kvs KVS) Empty() bool { return len(kvs) == 0 } +// Clone - returns a copy of the KVS +func (kvs KVS) Clone() KVS { + return append(make(KVS, 0, len(kvs)), kvs...) +} + +// GetWithDefault - returns default value if key not set +func (kvs KVS) GetWithDefault(key string, defaultKVS KVS) string { + v := kvs.Get(key) + if len(v) == 0 { + return defaultKVS.Get(key) + } + return v +} + // Keys returns the list of keys for the current KVS func (kvs KVS) Keys() []string { var keys = make([]string, len(kvs)) @@ -759,10 +773,12 @@ func (c Config) SetKVS(s string, defaultKVS map[string]KVS) (dynamic bool, err e kvs.Set(Enable, EnableOn) } - currKVS, ok := c[subSys][tgt] + var currKVS KVS + ck, ok := c[subSys][tgt] if !ok { - currKVS = defaultKVS[subSys] + currKVS = defaultKVS[subSys].Clone() } else { + currKVS = ck.Clone() for _, kv := range defaultKVS[subSys] { if _, ok = currKVS.Lookup(kv.Key); !ok { currKVS.Set(kv.Key, kv.Value) diff --git a/internal/config/heal/heal.go b/internal/config/heal/heal.go index 89c31dad1..9cd1db8ce 100644 --- a/internal/config/heal/heal.go +++ b/internal/config/heal/heal.go @@ -150,15 +150,15 @@ func LookupConfig(kvs config.KVS) (cfg Config, err error) { if err = config.CheckValidKeys(config.HealSubSys, kvs, DefaultKVS); err != nil { return cfg, err } - cfg.Bitrot, err = config.ParseBool(env.Get(EnvBitrot, kvs.Get(Bitrot))) + cfg.Bitrot, err = config.ParseBool(env.Get(EnvBitrot, kvs.GetWithDefault(Bitrot, DefaultKVS))) if err != nil { return cfg, fmt.Errorf("'heal:bitrotscan' value invalid: %w", err) } - cfg.Sleep, err = time.ParseDuration(env.Get(EnvSleep, kvs.Get(Sleep))) + cfg.Sleep, err = time.ParseDuration(env.Get(EnvSleep, kvs.GetWithDefault(Sleep, DefaultKVS))) if err != nil { return cfg, fmt.Errorf("'heal:max_sleep' value invalid: %w", err) } - cfg.IOCount, err = strconv.Atoi(env.Get(EnvIOCount, kvs.Get(IOCount))) + cfg.IOCount, err = strconv.Atoi(env.Get(EnvIOCount, kvs.GetWithDefault(IOCount, DefaultKVS))) if err != nil { return cfg, fmt.Errorf("'heal:max_io' value invalid: %w", err) } diff --git a/internal/config/scanner/scanner.go b/internal/config/scanner/scanner.go index d4c891a9c..51aef2847 100644 --- a/internal/config/scanner/scanner.go +++ b/internal/config/scanner/scanner.go @@ -95,7 +95,7 @@ func LookupConfig(kvs config.KVS) (cfg Config, err error) { } delay := env.Get(EnvDelayLegacy, "") if delay == "" { - delay = env.Get(EnvDelay, kvs.Get(Delay)) + delay = env.Get(EnvDelay, kvs.GetWithDefault(Delay, DefaultKVS)) } cfg.Delay, err = strconv.ParseFloat(delay, 64) if err != nil { @@ -103,14 +103,14 @@ func LookupConfig(kvs config.KVS) (cfg Config, err error) { } maxWait := env.Get(EnvMaxWaitLegacy, "") if maxWait == "" { - maxWait = env.Get(EnvMaxWait, kvs.Get(MaxWait)) + maxWait = env.Get(EnvMaxWait, kvs.GetWithDefault(MaxWait, DefaultKVS)) } cfg.MaxWait, err = time.ParseDuration(maxWait) if err != nil { return cfg, err } - cfg.Cycle, err = time.ParseDuration(env.Get(EnvCycle, kvs.Get(Cycle))) + cfg.Cycle, err = time.ParseDuration(env.Get(EnvCycle, kvs.GetWithDefault(Cycle, DefaultKVS))) if err != nil { return cfg, err }