diff options
Diffstat (limited to 'pkg/spec/parse.go')
-rw-r--r-- | pkg/spec/parse.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go new file mode 100644 index 000000000..920674b10 --- /dev/null +++ b/pkg/spec/parse.go @@ -0,0 +1,128 @@ +package createconfig + +import ( + "fmt" + "strconv" + "strings" + + "github.com/docker/go-units" + "github.com/opencontainers/runc/libcontainer/configs" + spec "github.com/opencontainers/runtime-spec/specs-go" +) + +// 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) +} + +// 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 <device-path>:<number>[<unit>]. 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 <device-path>:<number>[<unit>]. 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 <device-path>:<number>. Number must be a positive integer", val) + } + if rate < 0 { + return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. 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 "" +} + +// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object. +func Device(d *configs.Device) spec.LinuxDevice { + return spec.LinuxDevice{ + Type: string(d.Type), + Path: d.Path, + Major: d.Major, + Minor: d.Minor, + FileMode: fmPtr(int64(d.FileMode)), + UID: u32Ptr(int64(d.Uid)), + GID: u32Ptr(int64(d.Gid)), + } +} |