diff --git a/opts/opts.go b/opts/opts.go index ed93002b24..b0271cda4c 100644 --- a/opts/opts.go +++ b/opts/opts.go @@ -6,8 +6,10 @@ import ( "os" "path" "regexp" + "strconv" "strings" + "github.com/docker/docker/pkg/blkiodev" "github.com/docker/docker/pkg/parsers" ) @@ -168,6 +170,9 @@ func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts { // ValidatorFctType defines a validator function that returns a validated string and/or an error. type ValidatorFctType func(val string) (string, error) +// ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error. +type ValidatorWeightFctType func(val string) (*blkiodev.WeightDevice, error) + // ValidatorFctListType defines a validator function that returns a validated list of string and/or an error type ValidatorFctListType func(val string) ([]string, error) @@ -182,6 +187,29 @@ func ValidateAttach(val string) (string, error) { return val, fmt.Errorf("valid streams are STDIN, STDOUT and STDERR") } +// ValidateWeightDevice validates that the specified string has a valid device-weight format. +func ValidateWeightDevice(val string) (*blkiodev.WeightDevice, error) { + split := strings.SplitN(val, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("bad format: %s", val) + } + if !strings.HasPrefix(split[0], "/dev/") { + return nil, fmt.Errorf("bad format for device path: %s", val) + } + weight, err := strconv.ParseUint(split[1], 10, 0) + if err != nil { + return nil, fmt.Errorf("invalid weight for device: %s", val) + } + if weight > 0 && (weight < 10 || weight > 1000) { + return nil, fmt.Errorf("invalid weight for device: %s", val) + } + + return &blkiodev.WeightDevice{ + Path: split[0], + Weight: uint16(weight), + }, nil +} + // ValidateLink validates that the specified string has a valid link format (containerName:alias). func ValidateLink(val string) (string, error) { if _, _, err := parsers.ParseLink(val); err != nil { diff --git a/opts/weightdevice.go b/opts/weightdevice.go new file mode 100644 index 0000000000..2b0d6e38c9 --- /dev/null +++ b/opts/weightdevice.go @@ -0,0 +1,56 @@ +package opts + +import ( + "fmt" + + "github.com/docker/docker/pkg/blkiodev" +) + +// WeightdeviceOpt defines a map of WeightDevices +type WeightdeviceOpt struct { + values []*blkiodev.WeightDevice + validator ValidatorWeightFctType +} + +// NewWeightdeviceOpt creates a new WeightdeviceOpt +func NewWeightdeviceOpt(validator ValidatorWeightFctType) WeightdeviceOpt { + values := []*blkiodev.WeightDevice{} + return WeightdeviceOpt{ + values: values, + validator: validator, + } +} + +// Set validates a WeightDevice and sets its name as a key in WeightdeviceOpt +func (opt *WeightdeviceOpt) Set(val string) error { + var value *blkiodev.WeightDevice + if opt.validator != nil { + v, err := opt.validator(val) + if err != nil { + return err + } + value = v + } + (opt.values) = append((opt.values), value) + return nil +} + +// String returns Ulimit values as a string. +func (opt *WeightdeviceOpt) String() string { + var out []string + for _, v := range opt.values { + out = append(out, v.String()) + } + + return fmt.Sprintf("%v", out) +} + +// GetList returns a slice of pointers to WeightDevices. +func (opt *WeightdeviceOpt) GetList() []*blkiodev.WeightDevice { + var weightdevice []*blkiodev.WeightDevice + for _, v := range opt.values { + weightdevice = append(weightdevice, v) + } + + return weightdevice +}