github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/config/scanner/scanner.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package scanner 19 20 import ( 21 "fmt" 22 "strconv" 23 "time" 24 25 "github.com/minio/minio/internal/config" 26 "github.com/minio/pkg/v2/env" 27 ) 28 29 // Compression environment variables 30 const ( 31 Speed = "speed" 32 EnvSpeed = "MINIO_SCANNER_SPEED" 33 34 IdleSpeed = "idle_speed" 35 EnvIdleSpeed = "MINIO_SCANNER_IDLE_SPEED" 36 37 ExcessVersions = "alert_excess_versions" 38 EnvExcessVersions = "MINIO_SCANNER_ALERT_EXCESS_VERSIONS" 39 40 ExcessFolders = "alert_excess_folders" 41 EnvExcessFolders = "MINIO_SCANNER_ALERT_EXCESS_FOLDERS" 42 43 // All below are deprecated in October 2022 and 44 // replaced them with a single speed parameter 45 Delay = "delay" 46 MaxWait = "max_wait" 47 Cycle = "cycle" 48 EnvDelay = "MINIO_SCANNER_DELAY" 49 EnvCycle = "MINIO_SCANNER_CYCLE" 50 EnvDelayLegacy = "MINIO_CRAWLER_DELAY" 51 EnvMaxWait = "MINIO_SCANNER_MAX_WAIT" 52 EnvMaxWaitLegacy = "MINIO_CRAWLER_MAX_WAIT" 53 ) 54 55 // Config represents the heal settings. 56 type Config struct { 57 // Delay is the sleep multiplier. 58 Delay float64 `json:"delay"` 59 60 // Sleep always or based on incoming S3 requests. 61 IdleMode int32 // 0 => on, 1 => off 62 63 // Alert upon this many excess object versions 64 ExcessVersions int64 // 100 65 66 // Alert upon this many excess sub-folders per folder in an erasure set. 67 ExcessFolders int64 // 50000 68 69 // MaxWait is maximum wait time between operations 70 MaxWait time.Duration 71 // Cycle is the time.Duration between each scanner cycles 72 Cycle time.Duration 73 } 74 75 // DefaultKVS - default KV config for heal settings 76 var DefaultKVS = config.KVS{ 77 config.KV{ 78 Key: Speed, 79 Value: "default", 80 }, 81 config.KV{ 82 Key: IdleSpeed, 83 Value: "", 84 HiddenIfEmpty: true, 85 }, 86 config.KV{ 87 Key: ExcessVersions, 88 Value: "100", 89 }, 90 config.KV{ 91 Key: ExcessFolders, 92 Value: "50000", 93 }, 94 95 // Deprecated Oct 2022 96 config.KV{ 97 Key: Delay, 98 Value: "", 99 HiddenIfEmpty: true, 100 }, 101 // Deprecated Oct 2022 102 config.KV{ 103 Key: MaxWait, 104 Value: "", 105 HiddenIfEmpty: true, 106 }, 107 // Deprecated Oct 2022 108 config.KV{ 109 Key: Cycle, 110 Value: "", 111 HiddenIfEmpty: true, 112 }, 113 } 114 115 // LookupConfig - lookup config and override with valid environment settings if any. 116 func LookupConfig(kvs config.KVS) (cfg Config, err error) { 117 if err = config.CheckValidKeys(config.ScannerSubSys, kvs, DefaultKVS); err != nil { 118 return cfg, err 119 } 120 121 // Stick to loading deprecated config/env if they are already set, and the Speed value 122 // has not been changed from its "default" value, if it has been changed honor new settings. 123 if kvs.GetWithDefault(Speed, DefaultKVS) == "default" { 124 if kvs.Get(Delay) != "" && kvs.Get(MaxWait) != "" { 125 return lookupDeprecatedScannerConfig(kvs) 126 } 127 } 128 129 switch speed := env.Get(EnvSpeed, kvs.GetWithDefault(Speed, DefaultKVS)); speed { 130 case "fastest": 131 cfg.Delay, cfg.MaxWait, cfg.Cycle = 0, 0, time.Second 132 case "fast": 133 cfg.Delay, cfg.MaxWait, cfg.Cycle = 1, 100*time.Millisecond, time.Minute 134 case "default": 135 cfg.Delay, cfg.MaxWait, cfg.Cycle = 2, time.Second, time.Minute 136 case "slow": 137 cfg.Delay, cfg.MaxWait, cfg.Cycle = 10, 15*time.Second, time.Minute 138 case "slowest": 139 cfg.Delay, cfg.MaxWait, cfg.Cycle = 100, 15*time.Second, 30*time.Minute 140 default: 141 return cfg, fmt.Errorf("unknown '%s' value", speed) 142 } 143 144 switch idleSpeed := env.Get(EnvIdleSpeed, kvs.GetWithDefault(IdleSpeed, DefaultKVS)); idleSpeed { 145 case "", config.EnableOn: 146 cfg.IdleMode = 0 147 case config.EnableOff: 148 cfg.IdleMode = 1 149 default: 150 return cfg, fmt.Errorf("unknown value: '%s'", idleSpeed) 151 } 152 153 excessVersions, err := strconv.ParseInt(env.Get(EnvExcessVersions, kvs.GetWithDefault(ExcessVersions, DefaultKVS)), 10, 64) 154 if err != nil { 155 return cfg, err 156 } 157 cfg.ExcessVersions = excessVersions 158 159 excessFolders, err := strconv.ParseInt(env.Get(EnvExcessFolders, kvs.GetWithDefault(ExcessFolders, DefaultKVS)), 10, 64) 160 if err != nil { 161 return cfg, err 162 } 163 cfg.ExcessFolders = excessFolders 164 165 return cfg, nil 166 } 167 168 func lookupDeprecatedScannerConfig(kvs config.KVS) (cfg Config, err error) { 169 delay := env.Get(EnvDelayLegacy, "") 170 if delay == "" { 171 delay = env.Get(EnvDelay, kvs.GetWithDefault(Delay, DefaultKVS)) 172 } 173 cfg.Delay, err = strconv.ParseFloat(delay, 64) 174 if err != nil { 175 return cfg, err 176 } 177 maxWait := env.Get(EnvMaxWaitLegacy, "") 178 if maxWait == "" { 179 maxWait = env.Get(EnvMaxWait, kvs.GetWithDefault(MaxWait, DefaultKVS)) 180 } 181 cfg.MaxWait, err = time.ParseDuration(maxWait) 182 if err != nil { 183 return cfg, err 184 } 185 cycle := env.Get(EnvCycle, kvs.GetWithDefault(Cycle, DefaultKVS)) 186 if cycle == "" { 187 cycle = "1m" 188 } 189 cfg.Cycle, err = time.ParseDuration(cycle) 190 if err != nil { 191 return cfg, err 192 } 193 return cfg, nil 194 }