storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/config/cache/config.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2019 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package cache 18 19 import ( 20 "encoding/json" 21 "errors" 22 "path/filepath" 23 "strings" 24 25 "storj.io/minio/cmd/config" 26 "storj.io/minio/pkg/ellipses" 27 ) 28 29 // Config represents cache config settings 30 type Config struct { 31 Enabled bool `json:"-"` 32 Drives []string `json:"drives"` 33 Expiry int `json:"expiry"` 34 MaxUse int `json:"maxuse"` 35 Quota int `json:"quota"` 36 Exclude []string `json:"exclude"` 37 After int `json:"after"` 38 WatermarkLow int `json:"watermark_low"` 39 WatermarkHigh int `json:"watermark_high"` 40 Range bool `json:"range"` 41 CommitWriteback bool `json:"-"` 42 } 43 44 // UnmarshalJSON - implements JSON unmarshal interface for unmarshalling 45 // json entries for CacheConfig. 46 func (cfg *Config) UnmarshalJSON(data []byte) (err error) { 47 type Alias Config 48 var _cfg = &struct { 49 *Alias 50 }{ 51 Alias: (*Alias)(cfg), 52 } 53 if err = json.Unmarshal(data, _cfg); err != nil { 54 return err 55 } 56 57 if _cfg.Expiry < 0 { 58 return errors.New("config expiry value should not be negative") 59 } 60 61 if _cfg.MaxUse < 0 { 62 return errors.New("config max use value should not be null or negative") 63 } 64 65 if _cfg.Quota < 0 { 66 return errors.New("config quota value should not be null or negative") 67 } 68 if _cfg.After < 0 { 69 return errors.New("cache after value should not be less than 0") 70 } 71 if _cfg.WatermarkLow < 0 || _cfg.WatermarkLow > 100 { 72 return errors.New("config low watermark value should be between 0 and 100") 73 } 74 if _cfg.WatermarkHigh < 0 || _cfg.WatermarkHigh > 100 { 75 return errors.New("config high watermark value should be between 0 and 100") 76 } 77 if _cfg.WatermarkLow > 0 && (_cfg.WatermarkLow >= _cfg.WatermarkHigh) { 78 return errors.New("config low watermark value should be less than high watermark") 79 } 80 return nil 81 } 82 83 // Parses given cacheDrivesEnv and returns a list of cache drives. 84 func parseCacheDrives(drives string) ([]string, error) { 85 var drivesSlice []string 86 if len(drives) == 0 { 87 return drivesSlice, nil 88 } 89 90 drivesSlice = strings.Split(drives, cacheDelimiterLegacy) 91 if len(drivesSlice) == 1 && drivesSlice[0] == drives { 92 drivesSlice = strings.Split(drives, cacheDelimiter) 93 } 94 95 var endpoints []string 96 for _, d := range drivesSlice { 97 if len(d) == 0 { 98 return nil, config.ErrInvalidCacheDrivesValue(nil).Msg("cache dir cannot be an empty path") 99 } 100 if ellipses.HasEllipses(d) { 101 s, err := parseCacheDrivePaths(d) 102 if err != nil { 103 return nil, err 104 } 105 endpoints = append(endpoints, s...) 106 } else { 107 endpoints = append(endpoints, d) 108 } 109 } 110 111 for _, d := range endpoints { 112 if !filepath.IsAbs(d) { 113 return nil, config.ErrInvalidCacheDrivesValue(nil).Msg("cache dir should be absolute path: %s", d) 114 } 115 } 116 return endpoints, nil 117 } 118 119 // Parses all arguments and returns a slice of drive paths following the ellipses pattern. 120 func parseCacheDrivePaths(arg string) (ep []string, err error) { 121 patterns, perr := ellipses.FindEllipsesPatterns(arg) 122 if perr != nil { 123 return []string{}, config.ErrInvalidCacheDrivesValue(nil).Msg(perr.Error()) 124 } 125 126 for _, lbls := range patterns.Expand() { 127 ep = append(ep, strings.Join(lbls, "")) 128 } 129 130 return ep, nil 131 } 132 133 // Parses given cacheExcludesEnv and returns a list of cache exclude patterns. 134 func parseCacheExcludes(excludes string) ([]string, error) { 135 var excludesSlice []string 136 if len(excludes) == 0 { 137 return excludesSlice, nil 138 } 139 140 excludesSlice = strings.Split(excludes, cacheDelimiterLegacy) 141 if len(excludesSlice) == 1 && excludesSlice[0] == excludes { 142 excludesSlice = strings.Split(excludes, cacheDelimiter) 143 } 144 145 for _, e := range excludesSlice { 146 if len(e) == 0 { 147 return nil, config.ErrInvalidCacheExcludesValue(nil).Msg("cache exclude path (%s) cannot be empty", e) 148 } 149 if strings.HasPrefix(e, "/") { 150 return nil, config.ErrInvalidCacheExcludesValue(nil).Msg("cache exclude pattern (%s) cannot start with / as prefix", e) 151 } 152 } 153 154 return excludesSlice, nil 155 } 156 157 func parseCacheCommitMode(commitStr string) (bool, error) { 158 switch strings.ToLower(commitStr) { 159 case "writeback": 160 return true, nil 161 case "writethrough": 162 return false, nil 163 } 164 return false, config.ErrInvalidCacheCommitValue(nil).Msg("cache commit value must be `writeback` or `writethrough`") 165 }