2015-07-25 08:35:07 +00:00
|
|
|
// Package parsers provides helper functions to parse and validate different type
|
|
|
|
// of string. It can be hosts, unix addresses, tcp addresses, filters, kernel
|
|
|
|
// operating system versions.
|
2018-02-05 21:05:59 +00:00
|
|
|
package parsers // import "github.com/docker/docker/pkg/parsers"
|
2014-07-29 00:23:38 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-11-01 12:09:43 +00:00
|
|
|
// ParseKeyValueOpt parses and validates the specified string as a key/value
|
|
|
|
// pair (key=value).
|
|
|
|
func ParseKeyValueOpt(opt string) (key string, value string, err error) {
|
|
|
|
k, v, ok := strings.Cut(opt, "=")
|
|
|
|
if !ok {
|
|
|
|
return "", "", fmt.Errorf("unable to parse key/value option: %s", opt)
|
2014-07-29 00:23:38 +00:00
|
|
|
}
|
2022-11-01 12:09:43 +00:00
|
|
|
return strings.TrimSpace(k), strings.TrimSpace(v), nil
|
2014-07-29 00:23:38 +00:00
|
|
|
}
|
2014-11-03 18:15:55 +00:00
|
|
|
|
2018-09-04 14:49:09 +00:00
|
|
|
// ParseUintListMaximum parses and validates the specified string as the value
|
|
|
|
// found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be
|
|
|
|
// one of the formats below. Note that duplicates are actually allowed in the
|
|
|
|
// input string. It returns a `map[int]bool` with available elements from `val`
|
|
|
|
// set to `true`. Values larger than `maximum` cause an error if max is non zero,
|
|
|
|
// in order to stop the map becoming excessively large.
|
|
|
|
// Supported formats:
|
2022-07-08 16:27:07 +00:00
|
|
|
//
|
|
|
|
// 7
|
|
|
|
// 1-6
|
|
|
|
// 0,3-4,7,8-10
|
|
|
|
// 0-0,0,1-7
|
|
|
|
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
|
|
|
// 3,2,1
|
|
|
|
// 0-2,3,1
|
2018-09-04 14:49:09 +00:00
|
|
|
func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) {
|
|
|
|
return parseUintList(val, maximum)
|
|
|
|
}
|
|
|
|
|
2015-09-08 18:40:55 +00:00
|
|
|
// ParseUintList parses and validates the specified string as the value
|
|
|
|
// found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be
|
|
|
|
// one of the formats below. Note that duplicates are actually allowed in the
|
|
|
|
// input string. It returns a `map[int]bool` with available elements from `val`
|
|
|
|
// set to `true`.
|
|
|
|
// Supported formats:
|
2022-07-08 16:27:07 +00:00
|
|
|
//
|
|
|
|
// 7
|
|
|
|
// 1-6
|
|
|
|
// 0,3-4,7,8-10
|
|
|
|
// 0-0,0,1-7
|
|
|
|
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
|
|
|
// 3,2,1
|
|
|
|
// 0-2,3,1
|
2015-09-08 18:40:55 +00:00
|
|
|
func ParseUintList(val string) (map[int]bool, error) {
|
2018-09-04 14:49:09 +00:00
|
|
|
return parseUintList(val, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseUintList(val string, maximum int) (map[int]bool, error) {
|
2015-09-08 18:40:55 +00:00
|
|
|
if val == "" {
|
|
|
|
return map[int]bool{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
availableInts := make(map[int]bool)
|
|
|
|
split := strings.Split(val, ",")
|
|
|
|
errInvalidFormat := fmt.Errorf("invalid format: %s", val)
|
|
|
|
|
|
|
|
for _, r := range split {
|
|
|
|
if !strings.Contains(r, "-") {
|
|
|
|
v, err := strconv.Atoi(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errInvalidFormat
|
|
|
|
}
|
2018-09-04 14:49:09 +00:00
|
|
|
if maximum != 0 && v > maximum {
|
|
|
|
return nil, fmt.Errorf("value of out range, maximum is %d", maximum)
|
|
|
|
}
|
2015-09-08 18:40:55 +00:00
|
|
|
availableInts[v] = true
|
|
|
|
} else {
|
2022-11-01 12:09:43 +00:00
|
|
|
minS, maxS, _ := strings.Cut(r, "-")
|
|
|
|
min, err := strconv.Atoi(minS)
|
2015-09-08 18:40:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errInvalidFormat
|
|
|
|
}
|
2022-11-01 12:09:43 +00:00
|
|
|
max, err := strconv.Atoi(maxS)
|
2015-09-08 18:40:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errInvalidFormat
|
|
|
|
}
|
|
|
|
if max < min {
|
|
|
|
return nil, errInvalidFormat
|
|
|
|
}
|
2018-09-04 14:49:09 +00:00
|
|
|
if maximum != 0 && max > maximum {
|
|
|
|
return nil, fmt.Errorf("value of out range, maximum is %d", maximum)
|
|
|
|
}
|
2015-09-08 18:40:55 +00:00
|
|
|
for i := min; i <= max; i++ {
|
|
|
|
availableInts[i] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return availableInts, nil
|
|
|
|
}
|