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  }