github.com/docker/docker-ce@v17.12.1-ce-rc2+incompatible/components/cli/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/docker/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 split := strings.SplitN(val, ":", 2) 18 if len(split) != 2 { 19 return nil, fmt.Errorf("bad format: %s", val) 20 } 21 if !strings.HasPrefix(split[0], "/dev/") { 22 return nil, fmt.Errorf("bad format for device path: %s", val) 23 } 24 rate, err := units.RAMInBytes(split[1]) 25 if err != nil { 26 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) 27 } 28 if rate < 0 { 29 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) 30 } 31 32 return &blkiodev.ThrottleDevice{ 33 Path: split[0], 34 Rate: uint64(rate), 35 }, nil 36 } 37 38 // ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format. 39 func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) { 40 split := strings.SplitN(val, ":", 2) 41 if len(split) != 2 { 42 return nil, fmt.Errorf("bad format: %s", val) 43 } 44 if !strings.HasPrefix(split[0], "/dev/") { 45 return nil, fmt.Errorf("bad format for device path: %s", val) 46 } 47 rate, err := strconv.ParseUint(split[1], 10, 64) 48 if err != nil { 49 return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val) 50 } 51 if rate < 0 { 52 return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val) 53 } 54 55 return &blkiodev.ThrottleDevice{Path: split[0], Rate: rate}, nil 56 } 57 58 // ThrottledeviceOpt defines a map of ThrottleDevices 59 type ThrottledeviceOpt struct { 60 values []*blkiodev.ThrottleDevice 61 validator ValidatorThrottleFctType 62 } 63 64 // NewThrottledeviceOpt creates a new ThrottledeviceOpt 65 func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt { 66 values := []*blkiodev.ThrottleDevice{} 67 return ThrottledeviceOpt{ 68 values: values, 69 validator: validator, 70 } 71 } 72 73 // Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt 74 func (opt *ThrottledeviceOpt) Set(val string) error { 75 var value *blkiodev.ThrottleDevice 76 if opt.validator != nil { 77 v, err := opt.validator(val) 78 if err != nil { 79 return err 80 } 81 value = v 82 } 83 (opt.values) = append((opt.values), value) 84 return nil 85 } 86 87 // String returns ThrottledeviceOpt values as a string. 88 func (opt *ThrottledeviceOpt) String() string { 89 var out []string 90 for _, v := range opt.values { 91 out = append(out, v.String()) 92 } 93 94 return fmt.Sprintf("%v", out) 95 } 96 97 // GetList returns a slice of pointers to ThrottleDevices. 98 func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice { 99 var throttledevice []*blkiodev.ThrottleDevice 100 throttledevice = append(throttledevice, opt.values...) 101 102 return throttledevice 103 } 104 105 // Type returns the option type 106 func (opt *ThrottledeviceOpt) Type() string { 107 return "list" 108 }