Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
go-version: [1.23.x, 1.24.x]
go-version: [1.24.x, 1.25.x]
race: ["-race", ""]
runs-on: ubuntu-24.04

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
# Runs at 00:00 UTC every Monday
- cron: '0 0 * * 1'
env:
GO_VERSION: 1.24
GO_VERSION: 1.25
permissions:
contents: read

Expand Down
8 changes: 8 additions & 0 deletions .golangci-extra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,11 @@ linters:
- -QF1008 # https://staticcheck.dev/docs/checks/#QF1008 Omit embedded fields from selector expression.
exclusions:
generated: strict
rules:
# Legacy names we can't change without breaking compatibility.
- path: stats.go
text: "(type|struct field) (CpuUsage|CpuStats) should be "
- path: config_linux.go
text: "struct field (CpuShares|CpuQuota|CpuBurst|CpuPeriod|CpuRtRuntime|CpuRtPeriod|CpuWeight) should be "
- path: devices/config/device.go
text: "struct field (Uid|Gid) should be "
76 changes: 38 additions & 38 deletions config_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,132 +16,132 @@ const (
// Cgroup holds properties of a cgroup on Linux.
type Cgroup struct {
// Name specifies the name of the cgroup
Name string `json:"name,omitempty"`
Name string `json:"name,omitzero"`

// Parent specifies the name of parent of cgroup or slice
Parent string `json:"parent,omitempty"`
Parent string `json:"parent,omitzero"`

// Path specifies the path to cgroups that are created and/or joined by the container.
// The path is assumed to be relative to the host system cgroup mountpoint.
Path string `json:"path,omitempty"`
Path string `json:"path,omitzero"`

// ScopePrefix describes prefix for the scope name.
ScopePrefix string `json:"scope_prefix,omitempty"`
ScopePrefix string `json:"scope_prefix,omitzero"`

// Resources contains various cgroups settings to apply.
*Resources

// Systemd tells if systemd should be used to manage cgroups.
Systemd bool `json:"Systemd,omitempty"`
Systemd bool `json:"Systemd,omitzero"`

// SystemdProps are any additional properties for systemd,
// derived from org.systemd.property.xxx annotations.
// Ignored unless systemd is used for managing cgroups.
SystemdProps []systemdDbus.Property `json:"-"`

// Rootless tells if rootless cgroups should be used.
Rootless bool `json:"Rootless,omitempty"`
Rootless bool `json:"Rootless,omitzero"`

// The host UID that should own the cgroup, or nil to accept
// the default ownership. This should only be set when the
// cgroupfs is to be mounted read/write.
// Not all cgroup manager implementations support changing
// the ownership.
OwnerUID *int `json:"owner_uid,omitempty"`
OwnerUID *int `json:"owner_uid,omitzero"`
}

type Resources struct {
// Devices is the set of access rules for devices in the container.
Devices []*devices.Rule `json:"devices,omitempty"`
Devices []*devices.Rule `json:"devices,omitzero"`

// Memory limit (in bytes).
Memory int64 `json:"memory,omitempty"`
Memory int64 `json:"memory,omitzero"`

// Memory reservation or soft_limit (in bytes).
MemoryReservation int64 `json:"memory_reservation,omitempty"`
MemoryReservation int64 `json:"memory_reservation,omitzero"`

// Total memory usage (memory+swap); use -1 for unlimited swap.
MemorySwap int64 `json:"memory_swap,omitempty"`
MemorySwap int64 `json:"memory_swap,omitzero"`

// CPU shares (relative weight vs. other containers).
CpuShares uint64 `json:"cpu_shares,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuShares should be CPUShares".
CpuShares uint64 `json:"cpu_shares,omitzero"`

// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
CpuQuota int64 `json:"cpu_quota,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuQuota should be CPUQuota".
CpuQuota int64 `json:"cpu_quota,omitzero"`

// CPU hardcap burst limit (in usecs). Allowed accumulated cpu time additionally for burst in a given period.
CpuBurst *uint64 `json:"cpu_burst,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuBurst should be CPUBurst".
CpuBurst *uint64 `json:"cpu_burst,omitzero"`

// CPU period to be used for hardcapping (in usecs). 0 to use system default.
CpuPeriod uint64 `json:"cpu_period,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuPeriod should be CPUPeriod".
CpuPeriod uint64 `json:"cpu_period,omitzero"`

// How many time CPU will use in realtime scheduling (in usecs).
CpuRtRuntime int64 `json:"cpu_rt_quota,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuRtRuntime should be CPURtRuntime".
CpuRtRuntime int64 `json:"cpu_rt_quota,omitzero"`

// CPU period to be used for realtime scheduling (in usecs).
CpuRtPeriod uint64 `json:"cpu_rt_period,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuQuota should be CPUQuota".
CpuRtPeriod uint64 `json:"cpu_rt_period,omitzero"`

// Cpuset CPUs to use.
CpusetCpus string `json:"cpuset_cpus,omitempty"`
CpusetCpus string `json:"cpuset_cpus,omitzero"`

// Cpuset memory nodes to use.
CpusetMems string `json:"cpuset_mems,omitempty"`
CpusetMems string `json:"cpuset_mems,omitzero"`

// Cgroup's SCHED_IDLE value.
CPUIdle *int64 `json:"cpu_idle,omitempty"`
CPUIdle *int64 `json:"cpu_idle,omitzero"`

// Process limit; set < `0' to disable limit. `nil` means "keep current limit".
PidsLimit *int64 `json:"pids_limit,omitempty"`
PidsLimit *int64 `json:"pids_limit,omitzero"`

// Specifies per cgroup weight, range is from 10 to 1000.
BlkioWeight uint16 `json:"blkio_weight,omitempty"`
BlkioWeight uint16 `json:"blkio_weight,omitzero"`

// Tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, cfq scheduler only.
BlkioLeafWeight uint16 `json:"blkio_leaf_weight,omitempty"`
BlkioLeafWeight uint16 `json:"blkio_leaf_weight,omitzero"`

// Weight per cgroup per device, can override BlkioWeight.
BlkioWeightDevice []*WeightDevice `json:"blkio_weight_device,omitempty"`
BlkioWeightDevice []*WeightDevice `json:"blkio_weight_device,omitzero"`

// IO read rate limit per cgroup per device, bytes per second.
BlkioThrottleReadBpsDevice []*ThrottleDevice `json:"blkio_throttle_read_bps_device,omitempty"`
BlkioThrottleReadBpsDevice []*ThrottleDevice `json:"blkio_throttle_read_bps_device,omitzero"`

// IO write rate limit per cgroup per device, bytes per second.
BlkioThrottleWriteBpsDevice []*ThrottleDevice `json:"blkio_throttle_write_bps_device,omitempty"`
BlkioThrottleWriteBpsDevice []*ThrottleDevice `json:"blkio_throttle_write_bps_device,omitzero"`

// IO read rate limit per cgroup per device, IO per second.
BlkioThrottleReadIOPSDevice []*ThrottleDevice `json:"blkio_throttle_read_iops_device,omitempty"`
BlkioThrottleReadIOPSDevice []*ThrottleDevice `json:"blkio_throttle_read_iops_device,omitzero"`

// IO write rate limit per cgroup per device, IO per second.
BlkioThrottleWriteIOPSDevice []*ThrottleDevice `json:"blkio_throttle_write_iops_device,omitempty"`
BlkioThrottleWriteIOPSDevice []*ThrottleDevice `json:"blkio_throttle_write_iops_device,omitzero"`

// Freeze value for the process.
Freezer FreezerState `json:"freezer,omitempty"`
Freezer FreezerState `json:"freezer,omitzero"`

// Hugetlb limit (in bytes).
HugetlbLimit []*HugepageLimit `json:"hugetlb_limit,omitempty"`
HugetlbLimit []*HugepageLimit `json:"hugetlb_limit,omitzero"`

// Whether to disable OOM killer.
OomKillDisable bool `json:"oom_kill_disable,omitempty"`
OomKillDisable bool `json:"oom_kill_disable,omitzero"`

// Tuning swappiness behaviour per cgroup.
MemorySwappiness *uint64 `json:"memory_swappiness,omitempty"`
MemorySwappiness *uint64 `json:"memory_swappiness,omitzero"`

// Set priority of network traffic for container.
NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap,omitempty"`
NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap,omitzero"`

// Set class identifier for container's network packets.
NetClsClassid uint32 `json:"net_cls_classid_u,omitempty"`
NetClsClassid uint32 `json:"net_cls_classid_u,omitzero"`

// Rdma resource restriction configuration.
Rdma map[string]LinuxRdma `json:"rdma,omitempty"`
Rdma map[string]LinuxRdma `json:"rdma,omitzero"`

// Used on cgroups v2:

// CpuWeight sets a proportional bandwidth limit.
CpuWeight uint64 `json:"cpu_weight,omitempty"` //nolint:revive // Suppress "var-naming: struct field CpuWeight should be CPUWeight".
CpuWeight uint64 `json:"cpu_weight,omitzero"`

// Unified is cgroupv2-only key-value map.
Unified map[string]string `json:"unified,omitempty"`
Unified map[string]string `json:"unified,omitzero"`

// SkipDevices allows to skip configuring device permissions.
// Used by e.g. kubelet while creating a parent cgroup (kubepods)
Expand All @@ -165,5 +165,5 @@ type Resources struct {
// MemoryCheckBeforeUpdate is a flag for cgroup v2 managers to check
// if the new memory limits (Memory and MemorySwap) being set are lower
// than the current memory usage, and reject if so.
MemoryCheckBeforeUpdate bool `json:"memory_check_before_update,omitempty"`
MemoryCheckBeforeUpdate bool `json:"memory_check_before_update,omitzero"`
}
4 changes: 2 additions & 2 deletions devices/config/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ type Device struct {
FileMode os.FileMode `json:"file_mode"`

// Uid of the device.
Uid uint32 `json:"uid,omitempty"` //nolint:revive // Suppress "var-naming: struct field Uid should be UID".
Uid uint32 `json:"uid,omitzero"`

// Gid of the device.
Gid uint32 `json:"gid,omitempty"` //nolint:revive // Suppress "var-naming: struct field Gid should be GID".
Gid uint32 `json:"gid,omitzero"`
}

// Permissions is a cgroupv1-style string to represent device access. It
Expand Down
2 changes: 1 addition & 1 deletion devices/devicefilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

func hash(s, comm string) string {
var res []string
for _, l := range strings.Split(s, "\n") {
for l := range strings.SplitSeq(s, "\n") {
trimmed := strings.TrimSpace(l)
if trimmed == "" || strings.HasPrefix(trimmed, comm) {
continue
Expand Down
5 changes: 1 addition & 4 deletions devices/devices_emulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ c 10:200 rwm`,
}

for _, test := range tests {
test := test // capture range variable
t.Run(test.name, func(t *testing.T) {
list := bytes.NewBufferString(test.list)
emu, err := emulatorFromList(list)
Expand Down Expand Up @@ -741,7 +740,6 @@ func testDeviceEmulatorApply(t *testing.T, baseDefaultAllow bool) {
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
err := test.base.Apply(test.rule)
if err != nil && test.expected != nil {
Expand Down Expand Up @@ -1058,7 +1056,6 @@ func testDeviceEmulatorTransition(t *testing.T, sourceDefaultAllow bool) {
}

for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
// If we are in black-list mode, we need to prepend the relevant
// clear-all rule (the expected rule lists are written with
Expand Down Expand Up @@ -1130,7 +1127,7 @@ c 10:200 rwm`

var r *deviceRule
var err error
for i := 0; i < b.N; i++ {
for b.Loop() {
s := bufio.NewScanner(strings.NewReader(list))
for s.Scan() {
line := s.Text()
Expand Down
2 changes: 1 addition & 1 deletion devices/systemd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func TestFindDeviceGroup(t *testing.T) {
}

func BenchmarkFindDeviceGroup(b *testing.B) {
for i := 0; i < b.N; i++ {
for b.Loop() {
if err := testFindDeviceGroup(); err != nil {
b.Fatal(err)
}
Expand Down
3 changes: 1 addition & 2 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ func BenchmarkWriteFile(b *testing.B) {
"\n\n\n\n\n\n\n\n",
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
for _, val := range tc {
if err := WriteFileByLine(dir, "file", val); err != nil {
b.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion fs/cpuacct.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func getPercpuUsage(path string) ([]uint64, error) {
if err != nil {
return percpuUsage, err
}
for _, value := range strings.Fields(data) {
for value := range strings.FieldsSeq(data) {
value, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return percpuUsage, &parseError{Path: path, File: file, Err: err}
Expand Down
3 changes: 1 addition & 2 deletions fs/cpuacct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ func BenchmarkGetCpuUsageBreakdown(b *testing.B) {
"cpuacct.stat": cpuAcctStatContents,
})

b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
_, _, err := getCpuUsageBreakdown(path)
if err != nil {
b.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion fs/cpuset.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func getCpusetStat(path string, file string) ([]uint16, error) {
return extracted, &parseError{Path: path, File: file, Err: errors.New("empty file")}
}

for _, s := range strings.Split(fileContent, ",") {
for s := range strings.SplitSeq(fileContent, ",") {
fromStr, toStr, ok := strings.Cut(s, "-")
if ok {
from, err := strconv.ParseUint(fromStr, 10, 16)
Expand Down
3 changes: 1 addition & 2 deletions fs/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ func BenchmarkGetStats(b *testing.B) {

var st *cgroups.Stats

b.ResetTimer()
for i := 0; i < b.N; i++ {
for b.Loop() {
st, err = m.GetStats()
if err != nil {
b.Fatal(err)
Expand Down
5 changes: 2 additions & 3 deletions fs2/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func needAnyControllers(r *cgroups.Resources) (bool, error) {
return false, err
}
avail := make(map[string]struct{})
for _, ctr := range strings.Fields(content) {
for ctr := range strings.FieldsSeq(content) {
avail[ctr] = struct{}{}
}

Expand Down Expand Up @@ -137,8 +137,7 @@ func CreateCgroupPath(path string, c *cgroups.Cgroup) (Err error) {
if i < len(elements)-1 {
if err := cgroups.WriteFile(current, cgStCtlFile, res); err != nil {
// try write one by one
allCtrs := strings.Split(res, " ")
for _, ctr := range allCtrs {
for ctr := range strings.SplitSeq(res, " ") {
_ = cgroups.WriteFile(current, cgStCtlFile, ctr)
}
}
Expand Down
3 changes: 1 addition & 2 deletions fscommon/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ func GetValueByKey(path, file, key string) (uint64, error) {
}

key += " "
lines := strings.Split(content, "\n")
for _, line := range lines {
for line := range strings.SplitSeq(content, "\n") {
v, ok := strings.CutPrefix(line, key)
if ok {
val, err := ParseUint(v, 10, 64)
Expand Down
2 changes: 1 addition & 1 deletion getallpids_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

func BenchmarkGetAllPids(b *testing.B) {
total := 0
for i := 0; i < b.N; i++ {
for b.Loop() {
i, err := GetAllPids("/sys/fs/cgroup")
if err != nil {
b.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/opencontainers/cgroups

go 1.23.0
go 1.24.0

require (
github.com/cilium/ebpf v0.17.3
Expand Down
Loading
Loading