storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/config/cache/lookup.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  	"errors"
    21  	"strconv"
    22  
    23  	"storj.io/minio/cmd/config"
    24  	"storj.io/minio/pkg/env"
    25  )
    26  
    27  // Cache ENVs
    28  const (
    29  	Drives        = "drives"
    30  	Exclude       = "exclude"
    31  	Expiry        = "expiry"
    32  	MaxUse        = "maxuse"
    33  	Quota         = "quota"
    34  	After         = "after"
    35  	WatermarkLow  = "watermark_low"
    36  	WatermarkHigh = "watermark_high"
    37  	Range         = "range"
    38  	Commit        = "commit"
    39  
    40  	EnvCacheDrives        = "MINIO_CACHE_DRIVES"
    41  	EnvCacheExclude       = "MINIO_CACHE_EXCLUDE"
    42  	EnvCacheExpiry        = "MINIO_CACHE_EXPIRY"
    43  	EnvCacheMaxUse        = "MINIO_CACHE_MAXUSE"
    44  	EnvCacheQuota         = "MINIO_CACHE_QUOTA"
    45  	EnvCacheAfter         = "MINIO_CACHE_AFTER"
    46  	EnvCacheWatermarkLow  = "MINIO_CACHE_WATERMARK_LOW"
    47  	EnvCacheWatermarkHigh = "MINIO_CACHE_WATERMARK_HIGH"
    48  	EnvCacheRange         = "MINIO_CACHE_RANGE"
    49  	EnvCacheCommit        = "MINIO_CACHE_COMMIT"
    50  
    51  	EnvCacheEncryptionKey = "MINIO_CACHE_ENCRYPTION_SECRET_KEY"
    52  
    53  	DefaultExpiry        = "90"
    54  	DefaultQuota         = "80"
    55  	DefaultAfter         = "0"
    56  	DefaultWaterMarkLow  = "70"
    57  	DefaultWaterMarkHigh = "80"
    58  	DefaultCacheCommit   = "writethrough"
    59  )
    60  
    61  // DefaultKVS - default KV settings for caching.
    62  var (
    63  	DefaultKVS = config.KVS{
    64  		config.KV{
    65  			Key:   Drives,
    66  			Value: "",
    67  		},
    68  		config.KV{
    69  			Key:   Exclude,
    70  			Value: "",
    71  		},
    72  		config.KV{
    73  			Key:   Expiry,
    74  			Value: DefaultExpiry,
    75  		},
    76  		config.KV{
    77  			Key:   Quota,
    78  			Value: DefaultQuota,
    79  		},
    80  		config.KV{
    81  			Key:   After,
    82  			Value: DefaultAfter,
    83  		},
    84  		config.KV{
    85  			Key:   WatermarkLow,
    86  			Value: DefaultWaterMarkLow,
    87  		},
    88  		config.KV{
    89  			Key:   WatermarkHigh,
    90  			Value: DefaultWaterMarkHigh,
    91  		},
    92  		config.KV{
    93  			Key:   Range,
    94  			Value: config.EnableOn,
    95  		},
    96  		config.KV{
    97  			Key:   Commit,
    98  			Value: DefaultCacheCommit,
    99  		},
   100  	}
   101  )
   102  
   103  const (
   104  	cacheDelimiter = ","
   105  )
   106  
   107  // Enabled returns if cache is enabled.
   108  func Enabled(kvs config.KVS) bool {
   109  	drives := kvs.Get(Drives)
   110  	return drives != ""
   111  }
   112  
   113  // LookupConfig - extracts cache configuration provided by environment
   114  // variables and merge them with provided CacheConfiguration.
   115  func LookupConfig(kvs config.KVS) (Config, error) {
   116  	cfg := Config{}
   117  	if err := config.CheckValidKeys(config.CacheSubSys, kvs, DefaultKVS); err != nil {
   118  		return cfg, err
   119  	}
   120  
   121  	drives := env.Get(EnvCacheDrives, kvs.Get(Drives))
   122  	if len(drives) == 0 {
   123  		return cfg, nil
   124  	}
   125  
   126  	var err error
   127  	cfg.Drives, err = parseCacheDrives(drives)
   128  	if err != nil {
   129  		return cfg, err
   130  	}
   131  
   132  	cfg.Enabled = true
   133  	if excludes := env.Get(EnvCacheExclude, kvs.Get(Exclude)); excludes != "" {
   134  		cfg.Exclude, err = parseCacheExcludes(excludes)
   135  		if err != nil {
   136  			return cfg, err
   137  		}
   138  	}
   139  
   140  	if expiryStr := env.Get(EnvCacheExpiry, kvs.Get(Expiry)); expiryStr != "" {
   141  		cfg.Expiry, err = strconv.Atoi(expiryStr)
   142  		if err != nil {
   143  			return cfg, config.ErrInvalidCacheExpiryValue(err)
   144  		}
   145  	}
   146  
   147  	if maxUseStr := env.Get(EnvCacheMaxUse, kvs.Get(MaxUse)); maxUseStr != "" {
   148  		cfg.MaxUse, err = strconv.Atoi(maxUseStr)
   149  		if err != nil {
   150  			return cfg, config.ErrInvalidCacheQuota(err)
   151  		}
   152  		// maxUse should be a valid percentage.
   153  		if cfg.MaxUse < 0 || cfg.MaxUse > 100 {
   154  			err := errors.New("config max use value should not be null or negative")
   155  			return cfg, config.ErrInvalidCacheQuota(err)
   156  		}
   157  		cfg.Quota = cfg.MaxUse
   158  	} else if quotaStr := env.Get(EnvCacheQuota, kvs.Get(Quota)); quotaStr != "" {
   159  		cfg.Quota, err = strconv.Atoi(quotaStr)
   160  		if err != nil {
   161  			return cfg, config.ErrInvalidCacheQuota(err)
   162  		}
   163  		// quota should be a valid percentage.
   164  		if cfg.Quota < 0 || cfg.Quota > 100 {
   165  			err := errors.New("config quota value should not be null or negative")
   166  			return cfg, config.ErrInvalidCacheQuota(err)
   167  		}
   168  		cfg.MaxUse = cfg.Quota
   169  	}
   170  
   171  	if afterStr := env.Get(EnvCacheAfter, kvs.Get(After)); afterStr != "" {
   172  		cfg.After, err = strconv.Atoi(afterStr)
   173  		if err != nil {
   174  			return cfg, config.ErrInvalidCacheAfter(err)
   175  		}
   176  		// after should be a valid value >= 0.
   177  		if cfg.After < 0 {
   178  			err := errors.New("cache after value cannot be less than 0")
   179  			return cfg, config.ErrInvalidCacheAfter(err)
   180  		}
   181  	}
   182  
   183  	if lowWMStr := env.Get(EnvCacheWatermarkLow, kvs.Get(WatermarkLow)); lowWMStr != "" {
   184  		cfg.WatermarkLow, err = strconv.Atoi(lowWMStr)
   185  		if err != nil {
   186  			return cfg, config.ErrInvalidCacheWatermarkLow(err)
   187  		}
   188  		// WatermarkLow should be a valid percentage.
   189  		if cfg.WatermarkLow < 0 || cfg.WatermarkLow > 100 {
   190  			err := errors.New("config min watermark value should be between 0 and 100")
   191  			return cfg, config.ErrInvalidCacheWatermarkLow(err)
   192  		}
   193  	}
   194  
   195  	if highWMStr := env.Get(EnvCacheWatermarkHigh, kvs.Get(WatermarkHigh)); highWMStr != "" {
   196  		cfg.WatermarkHigh, err = strconv.Atoi(highWMStr)
   197  		if err != nil {
   198  			return cfg, config.ErrInvalidCacheWatermarkHigh(err)
   199  		}
   200  
   201  		// MaxWatermark should be a valid percentage.
   202  		if cfg.WatermarkHigh < 0 || cfg.WatermarkHigh > 100 {
   203  			err := errors.New("config high watermark value should be between 0 and 100")
   204  			return cfg, config.ErrInvalidCacheWatermarkHigh(err)
   205  		}
   206  	}
   207  	if cfg.WatermarkLow > cfg.WatermarkHigh {
   208  		err := errors.New("config high watermark value should be greater than low watermark value")
   209  		return cfg, config.ErrInvalidCacheWatermarkHigh(err)
   210  	}
   211  
   212  	cfg.Range = true // by default range caching is enabled.
   213  	if rangeStr := env.Get(EnvCacheRange, kvs.Get(Range)); rangeStr != "" {
   214  		rng, err := config.ParseBool(rangeStr)
   215  		if err != nil {
   216  			return cfg, config.ErrInvalidCacheRange(err)
   217  		}
   218  		cfg.Range = rng
   219  	}
   220  	if commit := env.Get(EnvCacheCommit, kvs.Get(Commit)); commit != "" {
   221  		cfg.CommitWriteback, err = parseCacheCommitMode(commit)
   222  		if err != nil {
   223  			return cfg, err
   224  		}
   225  		if cfg.After > 0 && cfg.CommitWriteback {
   226  			err := errors.New("cache after cannot be used with commit writeback")
   227  			return cfg, config.ErrInvalidCacheSetting(err)
   228  		}
   229  	}
   230  
   231  	return cfg, nil
   232  }