package createconfig import ( "fmt" "strconv" "strings" "github.com/docker/go-units" ) // weightDevice is a structure that holds device:weight pair type weightDevice struct { path string weight uint16 } func (w *weightDevice) String() string { return fmt.Sprintf("%s:%d", w.path, w.weight) } // IsNS returns if the specified string has a ns: prefix func IsNS(s string) bool { parts := strings.SplitN(s, ":", 2) return len(parts) > 1 && parts[0] == "ns" } // NS is the path to the namespace to join. func NS(s string) string { parts := strings.SplitN(s, ":", 2) if len(parts) > 1 { return parts[1] } return "" } // validateweightDevice validates that the specified string has a valid device-weight format // for blkio-weight-device flag func validateweightDevice(val string) (*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 &weightDevice{ path: split[0], weight: uint16(weight), }, nil } // throttleDevice is a structure that holds device:rate_per_second pair type throttleDevice struct { path string rate uint64 } func (t *throttleDevice) String() string { return fmt.Sprintf("%s:%d", t.path, t.rate) } // validateBpsDevice validates that the specified string has a valid device-rate format // for device-read-bps and device-write-bps flags func validateBpsDevice(val string) (*throttleDevice, 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) } rate, err := units.RAMInBytes(split[1]) if err != nil { return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :[]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) } if rate < 0 { return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :[]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val) } return &throttleDevice{ path: split[0], rate: uint64(rate), }, nil } // validateIOpsDevice validates that the specified string has a valid device-rate format // for device-write-iops and device-read-iops flags func validateIOpsDevice(val string) (*throttleDevice, error) { //nolint 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) } rate, err := strconv.ParseUint(split[1], 10, 64) if err != nil { return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) } if rate < 0 { return nil, fmt.Errorf("invalid rate for device: %s. The correct format is :. Number must be a positive integer", val) } return &throttleDevice{ path: split[0], rate: uint64(rate), }, nil } func getLoggingPath(opts []string) string { for _, opt := range opts { arr := strings.SplitN(opt, "=", 2) if len(arr) == 2 { if strings.TrimSpace(arr[0]) == "path" { return strings.TrimSpace(arr[1]) } } } return "" }