github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/opts/throttledevice.go (about) 1 package opts 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/docker/docker/api/types/blkiodev" 9 "github.com/khulnasoft-lab/go-units" 10 ) 11 12 // ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error. 13 type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error) 14 15 // ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format. 16 func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) { 17 k, v, ok := strings.Cut(val, ":") 18 if !ok || k == "" { 19 return nil, fmt.Errorf("bad format: %s", val) 20 } 21 // TODO(thaJeztah): should we really validate this on the client? 22 if !strings.HasPrefix(k, "/dev/") { 23 return nil, fmt.Errorf("bad format for device path: %s", val) 24 } 25 rate, err := units.RAMInBytes(v) 26 if err != nil { 27 return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) 28 } 29 if rate < 0 { 30 return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) 31 } 32 33 return &blkiodev.ThrottleDevice{ 34 Path: k, 35 Rate: uint64(rate), 36 }, nil 37 } 38 39 // ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format. 40 func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) { 41 k, v, ok := strings.Cut(val, ":") 42 if !ok || k == "" { 43 return nil, fmt.Errorf("bad format: %s", val) 44 } 45 // TODO(thaJeztah): should we really validate this on the client? 46 if !strings.HasPrefix(k, "/dev/") { 47 return nil, fmt.Errorf("bad format for device path: %s", val) 48 } 49 rate, err := strconv.ParseUint(v, 10, 64) 50 if err != nil { 51 return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val) 52 } 53 54 return &blkiodev.ThrottleDevice{Path: k, Rate: rate}, nil 55 } 56 57 // ThrottledeviceOpt defines a map of ThrottleDevices 58 type ThrottledeviceOpt struct { 59 values []*blkiodev.ThrottleDevice 60 validator ValidatorThrottleFctType 61 } 62 63 // NewThrottledeviceOpt creates a new ThrottledeviceOpt 64 func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt { 65 return ThrottledeviceOpt{ 66 values: []*blkiodev.ThrottleDevice{}, 67 validator: validator, 68 } 69 } 70 71 // Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt 72 func (opt *ThrottledeviceOpt) Set(val string) error { 73 var value *blkiodev.ThrottleDevice 74 if opt.validator != nil { 75 v, err := opt.validator(val) 76 if err != nil { 77 return err 78 } 79 value = v 80 } 81 opt.values = append(opt.values, value) 82 return nil 83 } 84 85 // String returns ThrottledeviceOpt values as a string. 86 func (opt *ThrottledeviceOpt) String() string { 87 out := make([]string, 0, len(opt.values)) 88 for _, v := range opt.values { 89 out = append(out, v.String()) 90 } 91 92 return fmt.Sprintf("%v", out) 93 } 94 95 // GetList returns a slice of pointers to ThrottleDevices. 96 func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice { 97 out := make([]*blkiodev.ThrottleDevice, 0, len(opt.values)) 98 copy(out, opt.values) 99 return out 100 } 101 102 // Type returns the option type 103 func (opt *ThrottledeviceOpt) Type() string { 104 return "list" 105 }