Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 155 additions & 1 deletion cmd/oci-runtime-tool/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,19 @@ var generateFlags = []cli.Flag{
cli.StringFlag{Name: "hostname", Usage: "hostname value for the container"},
cli.StringSliceFlag{Name: "label", Usage: "add annotations to the configuration e.g. key=value"},
cli.StringFlag{Name: "linux-apparmor", Usage: "specifies the the apparmor profile for the container"},
cli.IntFlag{Name: "linux-blkio-leaf-weight", Usage: "Block IO (relative leaf weight), the range is from 10 to 1000"},
cli.StringSliceFlag{Name: "linux-blkio-leaf-weight-device", Usage: "Block IO (relative device leaf weight), e.g. major:minor:leaf-weight"},
cli.StringSliceFlag{Name: "linux-blkio-read-bps-device", Usage: "Limit read rate (bytes per second) from a device"},
cli.StringSliceFlag{Name: "linux-blkio-read-iops-device", Usage: "Limit read rate (IO per second) from a device"},
cli.IntFlag{Name: "linux-blkio-weight", Usage: "Block IO (relative weight), the range is from 10 to 1000"},
cli.StringSliceFlag{Name: "linux-blkio-weight-device", Usage: "Block IO (relative device weight), e.g. major:minor:weight"},
cli.StringSliceFlag{Name: "linux-blkio-write-bps-device", Usage: "Limit write rate (bytes per second) to a device"},
cli.StringSliceFlag{Name: "linux-blkio-write-iops-device", Usage: "Limit write rate (IO per second) to a device"},
cli.StringFlag{Name: "linux-cgroups-path", Usage: "specify the path to the cgroups"},
cli.Uint64Flag{Name: "linux-cpu-period", Usage: "the CPU period to be used for hardcapping (in usecs)"},
cli.Uint64Flag{Name: "linux-cpu-quota", Usage: "the allowed CPU time in a given period (in usecs)"},
cli.Uint64Flag{Name: "linux-cpu-shares", Usage: "the relative share of CPU time available to the tasks in a cgroup"},
cli.StringFlag{Name: "linux-cpus", Usage: "CPUs to use within the cpuset (default is to use any CPU available)"},
cli.Uint64Flag{Name: "linux-cpu-shares", Usage: "the relative share of CPU time available to the tasks in a cgroup"},
cli.StringSliceFlag{Name: "linux-device-add", Usage: "add a device which must be made available in the container"},
cli.StringSliceFlag{Name: "linux-device-remove", Usage: "remove a device which must be made available in the container"},
cli.BoolFlag{Name: "linux-device-remove-all", Usage: "remove all devices which must be made available in the container"},
Expand Down Expand Up @@ -388,6 +396,104 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
g.SetProcessOOMScoreAdj(context.Int("linux-oom-score-adj"))
}

if context.IsSet("linux-blkio-leaf-weight") {
g.SetLinuxResourcesBlockIOLeafWeight(uint16(context.Uint64("linux-blkio-leaf-weight")))
}

if context.IsSet("linux-blkio-leaf-weight-device") {
devLeafWeight := context.StringSlice("linux-blkio-leaf-weight-device")
for _, v := range devLeafWeight {
major, minor, leafWeight, err := parseDeviceWeight(v)
if err != nil {
return err
}
if leafWeight == -1 {
g.DropLinuxResourcesBlockIOLeafWeightDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOLeafWeightDevice(major, minor, uint16(leafWeight))
}
}
}

if context.IsSet("linux-blkio-read-bps-device") {
throttleDevices := context.StringSlice("linux-blkio-read-bps-device")
for _, v := range throttleDevices {
major, minor, rate, err := parseThrottleDevice(v)
if err != nil {
return err
}
if rate == -1 {
g.DropLinuxResourcesBlockIOThrottleReadBpsDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOThrottleReadBpsDevice(major, minor, uint64(rate))
}
}
}

if context.IsSet("linux-blkio-read-iops-device") {
throttleDevices := context.StringSlice("linux-blkio-read-iops-device")
for _, v := range throttleDevices {
major, minor, rate, err := parseThrottleDevice(v)
if err != nil {
return err
}
if rate == -1 {
g.DropLinuxResourcesBlockIOThrottleReadIOPSDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major, minor, uint64(rate))
}
}
}

if context.IsSet("linux-blkio-weight") {
g.SetLinuxResourcesBlockIOWeight(uint16(context.Uint64("linux-blkio-weight")))
}

if context.IsSet("linux-blkio-weight-device") {
devWeight := context.StringSlice("linux-blkio-weight-device")
for _, v := range devWeight {
major, minor, weight, err := parseDeviceWeight(v)
if err != nil {
return err
}
if weight == -1 {
g.DropLinuxResourcesBlockIOWeightDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOWeightDevice(major, minor, uint16(weight))
}
}
}

if context.IsSet("linux-blkio-write-bps-device") {
throttleDevices := context.StringSlice("linux-blkio-write-bps-device")
for _, v := range throttleDevices {
major, minor, rate, err := parseThrottleDevice(v)
if err != nil {
return err
}
if rate == -1 {
g.DropLinuxResourcesBlockIOThrottleWriteBpsDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major, minor, uint64(rate))
}
}
}

if context.IsSet("linux-blkio-write-iops-device") {
throttleDevices := context.StringSlice("linux-blkio-write-iops-device")
for _, v := range throttleDevices {
major, minor, rate, err := parseThrottleDevice(v)
if err != nil {
return err
}
if rate == -1 {
g.DropLinuxResourcesBlockIOThrottleWriteIOPSDevice(major, minor)
} else {
g.AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major, minor, uint64(rate))
}
}
}

if context.IsSet("linux-cpu-shares") {
g.SetLinuxResourcesCPUShares(context.Uint64("linux-cpu-shares"))
}
Expand Down Expand Up @@ -1003,3 +1109,51 @@ type ErrBadEnvVariable struct {
func (e ErrBadEnvVariable) Error() string {
return fmt.Sprintf("poorly formatted environment: %s", e.msg)
}

func parseDeviceWeight(weightDevice string) (int64, int64, int16, error) {
list := strings.Split(weightDevice, ":")
if len(list) != 3 {
return 0, 0, 0, fmt.Errorf("invalid format: %s", weightDevice)
}

major, err := strconv.Atoi(list[0])
if err != nil {
return 0, 0, 0, err
}

minor, err := strconv.Atoi(list[1])
if err != nil {
return 0, 0, 0, err
}

weight, err := strconv.Atoi(list[2])
if err != nil {
return 0, 0, 0, err
}

return int64(major), int64(minor), int16(weight), nil
}

func parseThrottleDevice(throttleDevice string) (int64, int64, int64, error) {
list := strings.Split(throttleDevice, ":")
if len(list) != 3 {
return 0, 0, 0, fmt.Errorf("invalid format: %s", throttleDevice)
}

major, err := strconv.Atoi(list[0])
if err != nil {
return 0, 0, 0, err
}

minor, err := strconv.Atoi(list[1])
if err != nil {
return 0, 0, 0, err
}

rate, err := strconv.Atoi(list[2])
if err != nil {
return 0, 0, 0, err
}

return int64(major), int64(minor), int64(rate), nil
}
8 changes: 8 additions & 0 deletions completions/bash/oci-runtime-tool
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ _oci-runtime-tool_generate() {
--hostname
--label
--linux-apparmor
--linux-blkio-leaf-weight
--linux-blkio-leaf-weight-device
--linux-blkio-read-bps-device
--linux-blkio-read-iops-device
--linux-blkio-weight
--linux-blkio-weight-device
--linux-blkio-write-bps-device
--linux-blkio-write-iops-device
--linux-cgroups-path
--linux-cpu-period
--linux-cpu-quota
Expand Down
167 changes: 167 additions & 0 deletions generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,144 @@ func (g *Generator) SetProcessOOMScoreAdj(adj int) {
g.spec.Process.OOMScoreAdj = &adj
}

// SetLinuxResourcesBlockIOLeafWeight sets g.spec.Linux.Resources.BlockIO.LeafWeight.
func (g *Generator) SetLinuxResourcesBlockIOLeafWeight(weight uint16) {
g.initSpecLinuxResourcesBlockIO()
g.spec.Linux.Resources.BlockIO.LeafWeight = &weight
}

// AddLinuxResourcesBlockIOLeafWeightDevice adds or sets g.spec.Linux.Resources.BlockIO.WeightDevice.LeafWeight.
func (g *Generator) AddLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64, weight uint16) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
g.spec.Linux.Resources.BlockIO.WeightDevice[i].LeafWeight = &weight
return
}
}
weightDevice := new(rspec.LinuxWeightDevice)
weightDevice.Major = major
weightDevice.Minor = minor
weightDevice.LeafWeight = &weight
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
}

// DropLinuxResourcesBlockIOLeafWeightDevice drops a item form g.spec.Linux.Resources.BlockIO.WeightDevice.LeafWeight
func (g *Generator) DropLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
if weightDevice.Weight != nil {
newWeightDevice := new(rspec.LinuxWeightDevice)
newWeightDevice.Major = major
newWeightDevice.Minor = minor
newWeightDevice.Weight = weightDevice.Weight
g.spec.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
} else {
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice[:i], g.spec.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
}
return
}
}
}

// SetLinuxResourcesBlockIOWeight sets g.spec.Linux.Resources.BlockIO.Weight.
func (g *Generator) SetLinuxResourcesBlockIOWeight(weight uint16) {
g.initSpecLinuxResourcesBlockIO()
g.spec.Linux.Resources.BlockIO.Weight = &weight
}

// AddLinuxResourcesBlockIOWeightDevice adds or sets g.spec.Linux.Resources.BlockIO.WeightDevice.Weight.
func (g *Generator) AddLinuxResourcesBlockIOWeightDevice(major int64, minor int64, weight uint16) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
g.spec.Linux.Resources.BlockIO.WeightDevice[i].Weight = &weight
return
}
}
weightDevice := new(rspec.LinuxWeightDevice)
weightDevice.Major = major
weightDevice.Minor = minor
weightDevice.Weight = &weight
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
}

// DropLinuxResourcesBlockIOWeightDevice drops a item form g.spec.Linux.Resources.BlockIO.WeightDevice.Weight
func (g *Generator) DropLinuxResourcesBlockIOWeightDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
if weightDevice.LeafWeight != nil {
newWeightDevice := new(rspec.LinuxWeightDevice)
newWeightDevice.Major = major
newWeightDevice.Minor = minor
newWeightDevice.LeafWeight = weightDevice.LeafWeight
g.spec.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
} else {
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice[:i], g.spec.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
}
return
}
}
}

// AddLinuxResourcesBlockIOThrottleReadBpsDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
}

// DropLinuxResourcesBlockIOThrottleReadBpsDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
}

// AddLinuxResourcesBlockIOThrottleReadIOPSDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
}

// DropLinuxResourcesBlockIOThrottleReadIOPSDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
}

// AddLinuxResourcesBlockIOThrottleWriteBpsDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
}

// DropLinuxResourcesBlockIOThrottleWriteBpsDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
}

// AddLinuxResourcesBlockIOThrottleWriteIOPSDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
}

// DropLinuxResourcesBlockIOThrottleWriteIOPSDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
}

// SetLinuxResourcesCPUShares sets g.spec.Linux.Resources.CPU.Shares.
func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) {
g.initSpecLinuxResourcesCPU()
Expand Down Expand Up @@ -1124,3 +1262,32 @@ func (g *Generator) AddLinuxReadonlyPaths(path string) {
g.initSpecLinux()
g.spec.Linux.ReadonlyPaths = append(g.spec.Linux.ReadonlyPaths, path)
}

func addOrReplaceBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64, rate uint64) []rspec.LinuxThrottleDevice {
throttleDevices := tmpList
for i, throttleDevice := range throttleDevices {
if throttleDevice.Major == major && throttleDevice.Minor == minor {
throttleDevices[i].Rate = rate
return throttleDevices
}
}
throttleDevice := new(rspec.LinuxThrottleDevice)
throttleDevice.Major = major
throttleDevice.Minor = minor
throttleDevice.Rate = rate
throttleDevices = append(throttleDevices, *throttleDevice)

return throttleDevices
}

func dropBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64) []rspec.LinuxThrottleDevice {
throttleDevices := tmpList
for i, throttleDevice := range throttleDevices {
if throttleDevice.Major == major && throttleDevice.Minor == minor {
throttleDevices = append(throttleDevices[:i], throttleDevices[i+1:]...)
return throttleDevices
}
}

return throttleDevices
}
7 changes: 7 additions & 0 deletions generate/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ func (g *Generator) initSpecLinuxResources() {
}
}

func (g *Generator) initSpecLinuxResourcesBlockIO() {
g.initSpecLinuxResources()
if g.spec.Linux.Resources.BlockIO == nil {
g.spec.Linux.Resources.BlockIO = &rspec.LinuxBlockIO{}
}
}

func (g *Generator) initSpecLinuxResourcesCPU() {
g.initSpecLinuxResources()
if g.spec.Linux.Resources.CPU == nil {
Expand Down
Loading