Use github.com/containerd/cgroups/v3 to remove gogo
Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
parent
135af6d9ab
commit
6596a70861
3
go.mod
3
go.mod
@ -10,7 +10,7 @@ require (
|
||||
github.com/container-orchestrated-devices/container-device-interface v0.5.1
|
||||
github.com/containerd/aufs v1.0.0
|
||||
github.com/containerd/btrfs v1.0.0
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/continuity v0.3.0
|
||||
github.com/containerd/fifo v1.0.0
|
||||
@ -86,6 +86,7 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cilium/ebpf v0.9.1 // indirect
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721 // indirect
|
||||
github.com/containers/ocicrypt v1.1.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -200,6 +200,8 @@ github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f2
|
||||
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721 h1:qWq0iv560E8jXZKwWipx3Xot0dYPyfKBeDNfRwYth/U=
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774 h1:Tej/o6wjJ3icV9qkPopNXJxk2oeVAmRc7JL0q5JeUq8=
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
|
@ -30,8 +30,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
. "github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/containers"
|
||||
@ -93,7 +94,7 @@ func TestTaskUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
var (
|
||||
cgroup cgroups.Cgroup
|
||||
cgroup cgroup1.Cgroup
|
||||
cgroup2 *cgroupsv2.Manager
|
||||
)
|
||||
// check that the task has a limit of 32mb
|
||||
@ -102,7 +103,7 @@ func TestTaskUpdate(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cgroup2, err = cgroupsv2.LoadManager("/sys/fs/cgroup", groupPath)
|
||||
cgroup2, err = cgroupsv2.Load(groupPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -114,11 +115,11 @@ func TestTaskUpdate(t *testing.T) {
|
||||
t.Fatalf("expected memory limit to be set to %d but received %d", limit, stat.Memory.UsageLimit)
|
||||
}
|
||||
} else {
|
||||
cgroup, err = cgroups.Load(cgroups.V1, cgroups.PidPath(int(task.Pid())))
|
||||
cgroup, err = cgroup1.Load(cgroup1.PidPath(int(task.Pid())))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stat, err := cgroup.Stat(cgroups.IgnoreNotExist)
|
||||
stat, err := cgroup.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -144,7 +145,7 @@ func TestTaskUpdate(t *testing.T) {
|
||||
t.Errorf("expected memory limit to be set to %d but received %d", limit, stat.Memory.UsageLimit)
|
||||
}
|
||||
} else {
|
||||
stat, err := cgroup.Stat(cgroups.IgnoreNotExist)
|
||||
stat, err := cgroup.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -189,7 +190,7 @@ func TestShimInCgroup(t *testing.T) {
|
||||
// create a cgroup for the shim to use
|
||||
path := "/containerd/shim"
|
||||
var (
|
||||
cg cgroups.Cgroup
|
||||
cg cgroup1.Cgroup
|
||||
cg2 *cgroupsv2.Manager
|
||||
)
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
@ -199,7 +200,7 @@ func TestShimInCgroup(t *testing.T) {
|
||||
}
|
||||
defer cg2.Delete()
|
||||
} else {
|
||||
cg, err = cgroups.New(cgroups.V1, cgroups.StaticPath(path), &specs.LinuxResources{})
|
||||
cg, err = cgroup1.New(cgroup1.StaticPath(path), &specs.LinuxResources{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -227,7 +228,7 @@ func TestShimInCgroup(t *testing.T) {
|
||||
t.Errorf("created cgroup should have at least one process inside: %d", len(processes))
|
||||
}
|
||||
} else {
|
||||
processes, err := cg.Processes(cgroups.Devices, false)
|
||||
processes, err := cg.Processes(cgroup1.Devices, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1412,7 +1413,7 @@ func TestShimOOMScore(t *testing.T) {
|
||||
|
||||
path := "/containerd/oomshim"
|
||||
var (
|
||||
cg cgroups.Cgroup
|
||||
cg cgroup1.Cgroup
|
||||
cg2 *cgroupsv2.Manager
|
||||
)
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
@ -1422,7 +1423,7 @@ func TestShimOOMScore(t *testing.T) {
|
||||
}
|
||||
defer cg2.Delete()
|
||||
} else {
|
||||
cg, err = cgroups.New(cgroups.V1, cgroups.StaticPath(path), &specs.LinuxResources{})
|
||||
cg, err = cgroup1.New(cgroup1.StaticPath(path), &specs.LinuxResources{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -1472,7 +1473,7 @@ func TestShimOOMScore(t *testing.T) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
processes, err := cg.Processes(cgroups.Devices, false)
|
||||
processes, err := cg.Processes(cgroup1.Devices, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
. "github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
|
@ -5,7 +5,7 @@ go 1.18
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.10.0-rc.1
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721 // indirect
|
||||
github.com/containerd/containerd v1.6.2 // see replace; the actual version of containerd is replaced with the code at the root of this repository
|
||||
github.com/containerd/go-runc v1.0.0
|
||||
github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3
|
||||
@ -19,7 +19,10 @@ require (
|
||||
golang.org/x/sys v0.1.0
|
||||
)
|
||||
|
||||
require github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8
|
||||
require (
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20221103172237-443f56ff4ba8
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20220912195655-e1f97a00006b // indirect
|
||||
|
@ -466,6 +466,8 @@ github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f2
|
||||
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721 h1:qWq0iv560E8jXZKwWipx3Xot0dYPyfKBeDNfRwYth/U=
|
||||
github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774 h1:Tej/o6wjJ3icV9qkPopNXJxk2oeVAmRc7JL0q5JeUq8=
|
||||
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw=
|
||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
|
@ -26,8 +26,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/integration/images"
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -73,7 +74,7 @@ func getCgroupSwapLimitForTask(t *testing.T, task containerd.Task) uint64 {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cgroup2, err := cgroupsv2.LoadManager("/sys/fs/cgroup", groupPath)
|
||||
cgroup2, err := cgroupsv2.Load(groupPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -83,11 +84,11 @@ func getCgroupSwapLimitForTask(t *testing.T, task containerd.Task) uint64 {
|
||||
}
|
||||
return stat.Memory.SwapLimit
|
||||
}
|
||||
cgroup, err := cgroups.Load(cgroups.V1, cgroups.PidPath(int(task.Pid())))
|
||||
cgroup, err := cgroup1.Load(cgroup1.PidPath(int(task.Pid())))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stat, err := cgroup.Stat(cgroups.IgnoreNotExist)
|
||||
stat, err := cgroup.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -100,7 +101,7 @@ func getCgroupMemoryLimitForTask(t *testing.T, task containerd.Task) uint64 {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cgroup2, err := cgroupsv2.LoadManager("/sys/fs/cgroup", groupPath)
|
||||
cgroup2, err := cgroupsv2.Load(groupPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -111,11 +112,11 @@ func getCgroupMemoryLimitForTask(t *testing.T, task containerd.Task) uint64 {
|
||||
return stat.Memory.UsageLimit
|
||||
}
|
||||
|
||||
cgroup, err := cgroups.Load(cgroups.V1, cgroups.PidPath(int(task.Pid())))
|
||||
cgroup, err := cgroup1.Load(cgroup1.PidPath(int(task.Pid())))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stat, err := cgroup.Stat(cgroups.IgnoreNotExist)
|
||||
stat, err := cgroup.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/containerd/events"
|
||||
v1 "github.com/containerd/containerd/metrics/cgroups/v1"
|
||||
v2 "github.com/containerd/containerd/metrics/cgroups/v2"
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/containerd/metrics/cgroups/common"
|
||||
v1 "github.com/containerd/containerd/metrics/cgroups/v1"
|
||||
v2 "github.com/containerd/containerd/metrics/cgroups/v2"
|
||||
|
@ -22,7 +22,7 @@ package v1
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroups "github.com/containerd/cgroups/v3/cgroup1"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroups "github.com/containerd/cgroups/v3/cgroup1"
|
||||
"github.com/containerd/containerd/log"
|
||||
cmetrics "github.com/containerd/containerd/metrics"
|
||||
"github.com/containerd/containerd/metrics/cgroups/common"
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroups "github.com/containerd/cgroups/v3/cgroup1"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -20,7 +20,7 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -20,7 +20,7 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/cgroups/v2/stats"
|
||||
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/containerd/contrib/apparmor"
|
||||
"github.com/containerd/containerd/contrib/seccomp"
|
||||
"github.com/containerd/containerd/oci"
|
||||
|
@ -21,8 +21,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v2 "github.com/containerd/cgroups/v2/stats"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||
containerstore "github.com/containerd/containerd/pkg/cri/store/container"
|
||||
"github.com/stretchr/testify/assert"
|
||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
|
@ -24,8 +24,9 @@ import (
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
@ -151,7 +152,7 @@ func metricsForSandbox(sandbox sandboxstore.Sandbox) (interface{}, error) {
|
||||
|
||||
var statsx interface{}
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", cgroupPath)
|
||||
cg, err := cgroupsv2.Load(cgroupPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load sandbox cgroup: %v: %w", cgroupPath, err)
|
||||
}
|
||||
@ -162,11 +163,11 @@ func metricsForSandbox(sandbox sandboxstore.Sandbox) (interface{}, error) {
|
||||
statsx = stats
|
||||
|
||||
} else {
|
||||
control, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
|
||||
control, err := cgroup1.Load(cgroup1.StaticPath(cgroupPath))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load sandbox cgroup %v: %w", cgroupPath, err)
|
||||
}
|
||||
stats, err := control.Stat(cgroups.IgnoreNotExist)
|
||||
stats, err := control.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get stats for cgroup %v: %w", cgroupPath, err)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/containerd/contrib/apparmor"
|
||||
"github.com/containerd/containerd/contrib/seccomp"
|
||||
"github.com/containerd/containerd/oci"
|
||||
|
@ -21,8 +21,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v2 "github.com/containerd/cgroups/v2/stats"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||
"github.com/stretchr/testify/assert"
|
||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
)
|
||||
|
@ -24,8 +24,9 @@ import (
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
@ -151,7 +152,7 @@ func metricsForSandbox(sandbox sandboxstore.Sandbox) (interface{}, error) {
|
||||
|
||||
var statsx interface{}
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", cgroupPath)
|
||||
cg, err := cgroupsv2.Load(cgroupPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load sandbox cgroup: %v: %w", cgroupPath, err)
|
||||
}
|
||||
@ -162,11 +163,11 @@ func metricsForSandbox(sandbox sandboxstore.Sandbox) (interface{}, error) {
|
||||
statsx = stats
|
||||
|
||||
} else {
|
||||
control, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
|
||||
control, err := cgroup1.Load(cgroup1.StaticPath(cgroupPath))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load sandbox cgroup %v: %w", cgroupPath, err)
|
||||
}
|
||||
stats, err := control.Stat(cgroups.IgnoreNotExist)
|
||||
stats, err := control.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get stats for cgroup %v: %w", cgroupPath, err)
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/pkg/oom"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
@ -58,7 +58,7 @@ type epoller struct {
|
||||
|
||||
type item struct {
|
||||
id string
|
||||
cg cgroups.Cgroup
|
||||
cg cgroup1.Cgroup
|
||||
}
|
||||
|
||||
// Close the epoll fd
|
||||
@ -91,7 +91,7 @@ func (e *epoller) Run(ctx context.Context) {
|
||||
|
||||
// Add cgroups.Cgroup to the epoll monitor
|
||||
func (e *epoller) Add(id string, cgx interface{}) error {
|
||||
cg, ok := cgx.(cgroups.Cgroup)
|
||||
cg, ok := cgx.(cgroup1.Cgroup)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected cgroups.Cgroup, got: %T", cgx)
|
||||
}
|
||||
@ -121,7 +121,7 @@ func (e *epoller) process(ctx context.Context, fd uintptr) {
|
||||
return
|
||||
}
|
||||
e.mu.Unlock()
|
||||
if i.cg.State() == cgroups.Deleted {
|
||||
if i.cg.State() == cgroup1.Deleted {
|
||||
e.mu.Lock()
|
||||
delete(e.set, fd)
|
||||
e.mu.Unlock()
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/pkg/oom"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
|
@ -19,23 +19,24 @@ package opts
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
cgroup1 "github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroup2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
)
|
||||
|
||||
// WithNamespaceCgroupDeletion removes the cgroup directory that was created for the namespace
|
||||
func WithNamespaceCgroupDeletion(ctx context.Context, i *namespaces.DeleteInfo) error {
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", i.Name)
|
||||
cg, err := cgroup2.Load(i.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cg.Delete()
|
||||
}
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(i.Name))
|
||||
cg, err := cgroup1.Load(cgroup1.StaticPath(i.Name))
|
||||
if err != nil {
|
||||
if err == cgroups.ErrCgroupDeleted {
|
||||
if err == cgroup1.ErrCgroupDeleted {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroups "github.com/containerd/cgroups/v3/cgroup1"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events/exchange"
|
||||
@ -58,7 +58,7 @@ func newTask(id, namespace string, pid int, shim *client.Client, events *exchang
|
||||
cg cgroups.Cgroup
|
||||
)
|
||||
if pid > 0 {
|
||||
cg, err = cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
|
||||
cg, err = cgroups.Load(cgroups.PidPath(pid))
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted {
|
||||
return nil, err
|
||||
}
|
||||
@ -135,7 +135,7 @@ func (t *Task) Start(ctx context.Context) error {
|
||||
}
|
||||
t.pid = int(r.Pid)
|
||||
if !hasCgroup {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(t.pid))
|
||||
cg, err := cgroups.Load(cgroups.PidPath(t.pid))
|
||||
if err != nil && err != cgroups.ErrCgroupDeleted {
|
||||
return err
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
exec "golang.org/x/sys/execabs"
|
||||
)
|
||||
|
||||
@ -31,7 +31,7 @@ func getSysProcAttr() *syscall.SysProcAttr {
|
||||
}
|
||||
|
||||
func setCgroup(cgroupPath string, cmd *exec.Cmd) error {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath))
|
||||
cg, err := cgroup1.Load(cgroup1.StaticPath(cgroupPath))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load cgroup %s: %w", cgroupPath, err)
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
"github.com/containerd/console"
|
||||
"github.com/containerd/containerd/api/runtime/task/v2"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
@ -148,12 +149,12 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
|
||||
logrus.WithError(err).Errorf("loading cgroup2 for %d", pid)
|
||||
return container, nil
|
||||
}
|
||||
cg, err = cgroupsv2.LoadManager("/sys/fs/cgroup", g)
|
||||
cg, err = cgroupsv2.Load(g)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("loading cgroup2 for %d", pid)
|
||||
}
|
||||
} else {
|
||||
cg, err = cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
|
||||
cg, err = cgroup1.Load(cgroup1.PidPath(pid))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("loading cgroup for %d", pid)
|
||||
}
|
||||
@ -368,12 +369,12 @@ func (c *Container) Start(ctx context.Context, r *task.StartRequest) (process.Pr
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("loading cgroup2 for %d", p.Pid())
|
||||
}
|
||||
cg, err = cgroupsv2.LoadManager("/sys/fs/cgroup", g)
|
||||
cg, err = cgroupsv2.Load(g)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("loading cgroup2 for %d", p.Pid())
|
||||
}
|
||||
} else {
|
||||
cg, err = cgroups.Load(cgroups.V1, cgroups.PidPath(p.Pid()))
|
||||
cg, err = cgroup1.Load(cgroup1.PidPath(p.Pid()))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("loading cgroup for %d", p.Pid())
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
@ -212,7 +213,7 @@ func (manager) Start(ctx context.Context, id string, opts shim.StartOpts) (_ str
|
||||
if opts, ok := v.(*options.Options); ok {
|
||||
if opts.ShimCgroup != "" {
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", opts.ShimCgroup)
|
||||
cg, err := cgroupsv2.Load(opts.ShimCgroup)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
|
||||
}
|
||||
@ -220,7 +221,7 @@ func (manager) Start(ctx context.Context, id string, opts shim.StartOpts) (_ str
|
||||
return "", fmt.Errorf("failed to join cgroup %s: %w", opts.ShimCgroup, err)
|
||||
}
|
||||
} else {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(opts.ShimCgroup))
|
||||
cg, err := cgroup1.Load(cgroup1.StaticPath(opts.ShimCgroup))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
|
||||
}
|
||||
|
@ -25,8 +25,9 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
taskAPI "github.com/containerd/containerd/api/runtime/task/v2"
|
||||
"github.com/containerd/containerd/api/types/task"
|
||||
@ -168,7 +169,7 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
|
||||
switch r.ExecID {
|
||||
case "":
|
||||
switch cg := container.Cgroup().(type) {
|
||||
case cgroups.Cgroup:
|
||||
case cgroup1.Cgroup:
|
||||
if err := s.ep.Add(container.ID, cg); err != nil {
|
||||
logrus.WithError(err).Error("add cg to OOM monitor")
|
||||
}
|
||||
@ -483,8 +484,8 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
|
||||
}
|
||||
var statsx interface{}
|
||||
switch cg := cgx.(type) {
|
||||
case cgroups.Cgroup:
|
||||
stats, err := cg.Stat(cgroups.IgnoreNotExist)
|
||||
case cgroup1.Cgroup:
|
||||
stats, err := cg.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
"github.com/containerd/cgroups/v3/cgroup1"
|
||||
eventstypes "github.com/containerd/containerd/api/events"
|
||||
taskAPI "github.com/containerd/containerd/api/runtime/task/v2"
|
||||
"github.com/containerd/containerd/api/types/task"
|
||||
@ -204,7 +204,7 @@ func (s *service) StartShim(ctx context.Context, opts shim.StartOpts) (_ string,
|
||||
}
|
||||
if opts, ok := v.(*options.Options); ok {
|
||||
if opts.ShimCgroup != "" {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(opts.ShimCgroup))
|
||||
cg, err := cgroup1.Load(cgroup1.StaticPath(opts.ShimCgroup))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
|
||||
}
|
||||
@ -318,7 +318,7 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
|
||||
}
|
||||
switch r.ExecID {
|
||||
case "":
|
||||
if cg, ok := container.Cgroup().(cgroups.Cgroup); ok {
|
||||
if cg, ok := container.Cgroup().(cgroup1.Cgroup); ok {
|
||||
if err := s.ep.Add(container.ID, cg); err != nil {
|
||||
logrus.WithError(err).Error("add cg to OOM monitor")
|
||||
}
|
||||
@ -604,14 +604,14 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
|
||||
if cgx == nil {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "cgroup does not exist")
|
||||
}
|
||||
cg, ok := cgx.(cgroups.Cgroup)
|
||||
cg, ok := cgx.(cgroup1.Cgroup)
|
||||
if !ok {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotImplemented, "cgroup v2 not implemented for Stats")
|
||||
}
|
||||
if cg == nil {
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "cgroup does not exist")
|
||||
}
|
||||
stats, err := cg.Stat(cgroups.IgnoreNotExist)
|
||||
stats, err := cg.Stat(cgroup1.IgnoreNotExist)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -20,8 +20,9 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
cgroup1 "github.com/containerd/cgroups/v3/cgroup1"
|
||||
cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
|
||||
"github.com/containerd/containerd/log"
|
||||
srvconfig "github.com/containerd/containerd/services/server/config"
|
||||
"github.com/containerd/containerd/sys"
|
||||
@ -39,7 +40,7 @@ func apply(ctx context.Context, config *srvconfig.Config) error {
|
||||
}
|
||||
if config.Cgroup.Path != "" {
|
||||
if cgroups.Mode() == cgroups.Unified {
|
||||
cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup", config.Cgroup.Path)
|
||||
cg, err := cgroupsv2.Load(config.Cgroup.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,12 +48,12 @@ func apply(ctx context.Context, config *srvconfig.Config) error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path))
|
||||
cg, err := cgroup1.Load(cgroup1.StaticPath(config.Cgroup.Path))
|
||||
if err != nil {
|
||||
if err != cgroups.ErrCgroupDeleted {
|
||||
if err != cgroup1.ErrCgroupDeleted {
|
||||
return err
|
||||
}
|
||||
if cg, err = cgroups.New(cgroups.V1, cgroups.StaticPath(config.Cgroup.Path), &specs.LinuxResources{}); err != nil {
|
||||
if cg, err = cgroup1.New(cgroup1.StaticPath(config.Cgroup.Path), &specs.LinuxResources{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
46
vendor/github.com/containerd/cgroups/Protobuild.toml
generated
vendored
46
vendor/github.com/containerd/cgroups/Protobuild.toml
generated
vendored
@ -1,46 +0,0 @@
|
||||
version = "unstable"
|
||||
generator = "gogoctrd"
|
||||
plugins = ["grpc"]
|
||||
|
||||
# Control protoc include paths. Below are usually some good defaults, but feel
|
||||
# free to try it without them if it works for your project.
|
||||
[includes]
|
||||
# Include paths that will be added before all others. Typically, you want to
|
||||
# treat the root of the project as an include, but this may not be necessary.
|
||||
# before = ["."]
|
||||
|
||||
# Paths that should be treated as include roots in relation to the vendor
|
||||
# directory. These will be calculated with the vendor directory nearest the
|
||||
# target package.
|
||||
# vendored = ["github.com/gogo/protobuf"]
|
||||
packages = ["github.com/gogo/protobuf"]
|
||||
|
||||
# Paths that will be added untouched to the end of the includes. We use
|
||||
# `/usr/local/include` to pickup the common install location of protobuf.
|
||||
# This is the default.
|
||||
after = ["/usr/local/include", "/usr/include"]
|
||||
|
||||
# This section maps protobuf imports to Go packages. These will become
|
||||
# `-M` directives in the call to the go protobuf generator.
|
||||
[packages]
|
||||
"gogoproto/gogo.proto" = "github.com/gogo/protobuf/gogoproto"
|
||||
"google/protobuf/any.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/descriptor.proto" = "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types"
|
||||
|
||||
# Aggregrate the API descriptors to lock down API changes.
|
||||
[[descriptors]]
|
||||
prefix = "github.com/containerd/cgroups/stats/v1"
|
||||
target = "stats/v1/metrics.pb.txt"
|
||||
ignore_files = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
"gogoproto/gogo.proto"
|
||||
]
|
||||
[[descriptors]]
|
||||
prefix = "github.com/containerd/cgroups/v2/stats"
|
||||
target = "v2/stats/metrics.pb.txt"
|
||||
ignore_files = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
"gogoproto/gogo.proto"
|
||||
]
|
3992
vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go
generated
vendored
3992
vendor/github.com/containerd/cgroups/v2/stats/metrics.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
201
vendor/github.com/containerd/cgroups/v3/LICENSE
generated
vendored
Normal file
201
vendor/github.com/containerd/cgroups/v3/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
@ -22,3 +22,5 @@ cgutil:
|
||||
|
||||
proto:
|
||||
protobuild --quiet ${PACKAGES}
|
||||
# Keep them Go-idiomatic and backward-compatible with the gogo/protobuf era.
|
||||
go-fix-acronym -w -a '(Cpu|Tcp|Rss)' $(shell find cgroup1/stats/ cgroup2/stats/ -name '*.pb.go')
|
31
vendor/github.com/containerd/cgroups/v3/Protobuild.toml
generated
vendored
Normal file
31
vendor/github.com/containerd/cgroups/v3/Protobuild.toml
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
version = "2"
|
||||
generators = ["go"]
|
||||
|
||||
# Control protoc include paths. Below are usually some good defaults, but feel
|
||||
# free to try it without them if it works for your project.
|
||||
[includes]
|
||||
# Include paths that will be added before all others. Typically, you want to
|
||||
# treat the root of the project as an include, but this may not be necessary.
|
||||
# before = ["."]
|
||||
|
||||
# Paths that will be added untouched to the end of the includes. We use
|
||||
# `/usr/local/include` to pickup the common install location of protobuf.
|
||||
# This is the default.
|
||||
after = ["/usr/local/include", "/usr/include"]
|
||||
|
||||
# Aggregrate the API descriptors to lock down API changes.
|
||||
[[descriptors]]
|
||||
prefix = "github.com/containerd/cgroups/cgroup1/stats"
|
||||
target = "cgroup1/stats/metrics.pb.txt"
|
||||
ignore_files = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
]
|
||||
[[descriptors]]
|
||||
prefix = "github.com/containerd/cgroups/cgroup2/stats"
|
||||
target = "cgroup2/stats/metrics.pb.txt"
|
||||
ignore_files = [
|
||||
"google/protobuf/descriptor.proto",
|
||||
]
|
||||
|
||||
[parameters.go]
|
||||
paths = "source_relative"
|
@ -25,7 +25,7 @@ uses the v1 implementation of cgroups.
|
||||
|
||||
```go
|
||||
shares := uint64(100)
|
||||
control, err := cgroups.New(cgroups.V1, cgroups.StaticPath("/test"), &specs.LinuxResources{
|
||||
control, err := cgroup1.New(cgroup1.StaticPath("/test"), &specs.LinuxResources{
|
||||
CPU: &specs.LinuxCPU{
|
||||
Shares: &shares,
|
||||
},
|
||||
@ -37,7 +37,7 @@ defer control.Delete()
|
||||
|
||||
|
||||
```go
|
||||
control, err := cgroups.New(cgroups.Systemd, cgroups.Slice("system.slice", "runc-test"), &specs.LinuxResources{
|
||||
control, err := cgroup1.New(cgroup1.Systemd, cgroup1.Slice("system.slice", "runc-test"), &specs.LinuxResources{
|
||||
CPU: &specs.CPU{
|
||||
Shares: &shares,
|
||||
},
|
||||
@ -48,13 +48,13 @@ control, err := cgroups.New(cgroups.Systemd, cgroups.Slice("system.slice", "runc
|
||||
### Load an existing cgroup
|
||||
|
||||
```go
|
||||
control, err = cgroups.Load(cgroups.V1, cgroups.StaticPath("/test"))
|
||||
control, err = cgroup1.Load(cgroup1.Default, cgroups.StaticPath("/test"))
|
||||
```
|
||||
|
||||
### Add a process to the cgroup
|
||||
|
||||
```go
|
||||
if err := control.Add(cgroups.Process{Pid:1234}); err != nil {
|
||||
if err := control.Add(cgroup1.Process{Pid:1234}); err != nil {
|
||||
}
|
||||
```
|
||||
|
||||
@ -84,7 +84,7 @@ if err := control.Thaw(); err != nil {
|
||||
### List all processes in the cgroup or recursively
|
||||
|
||||
```go
|
||||
processes, err := control.Processes(cgroups.Devices, recursive)
|
||||
processes, err := control.Processes(cgroup1.Devices, recursive)
|
||||
```
|
||||
|
||||
### Get Stats on the cgroup
|
||||
@ -95,7 +95,7 @@ stats, err := control.Stat()
|
||||
|
||||
By adding `cgroups.IgnoreNotExist` all non-existent files will be ignored, e.g. swap memory stats without swap enabled
|
||||
```go
|
||||
stats, err := control.Stat(cgroups.IgnoreNotExist)
|
||||
stats, err := control.Stat(cgroup1.IgnoreNotExist)
|
||||
```
|
||||
|
||||
### Move process across cgroups
|
||||
@ -117,19 +117,19 @@ subCgroup, err := control.New("child", resources)
|
||||
This allows you to get notified by an eventfd for v1 memory cgroups events.
|
||||
|
||||
```go
|
||||
event := cgroups.MemoryThresholdEvent(50 * 1024 * 1024, false)
|
||||
event := cgroup1.MemoryThresholdEvent(50 * 1024 * 1024, false)
|
||||
efd, err := control.RegisterMemoryEvent(event)
|
||||
```
|
||||
|
||||
```go
|
||||
event := cgroups.MemoryPressureEvent(cgroups.MediumPressure, cgroups.DefaultMode)
|
||||
event := cgroup1.MemoryPressureEvent(cgroup1.MediumPressure, cgroup1.DefaultMode)
|
||||
efd, err := control.RegisterMemoryEvent(event)
|
||||
```
|
||||
|
||||
```go
|
||||
efd, err := control.OOMEventFD()
|
||||
// or by using RegisterMemoryEvent
|
||||
event := cgroups.OOMEvent()
|
||||
event := cgroup1.OOMEvent()
|
||||
efd, err := control.RegisterMemoryEvent(event)
|
||||
```
|
||||
|
||||
@ -153,14 +153,14 @@ so the resulting slice would be located here on disk:
|
||||
|
||||
```go
|
||||
import (
|
||||
cgroupsv2 "github.com/containerd/cgroups/v2"
|
||||
"github.com/containerd/cgroups/v3/cgroup2"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
res := cgroupsv2.Resources{}
|
||||
res := cgroup2.Resources{}
|
||||
// dummy PID of -1 is used for creating a "general slice" to be used as a parent cgroup.
|
||||
// see https://github.com/containerd/cgroups/blob/1df78138f1e1e6ee593db155c6b369466f577651/v2/manager.go#L732-L735
|
||||
m, err := cgroupsv2.NewSystemd("/", "my-cgroup-abc.slice", -1, &res)
|
||||
m, err := cgroup2.NewSystemd("/", "my-cgroup-abc.slice", -1, &res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -169,7 +169,7 @@ if err != nil {
|
||||
### Load an existing cgroup
|
||||
|
||||
```go
|
||||
m, err := cgroupsv2.LoadSystemd("/", "my-cgroup-abc.slice")
|
||||
m, err := cgroup2.LoadSystemd("/", "my-cgroup-abc.slice")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -178,7 +178,7 @@ if err != nil {
|
||||
### Delete a cgroup
|
||||
|
||||
```go
|
||||
m, err := cgroupsv2.LoadSystemd("/", "my-cgroup-abc.slice")
|
||||
m, err := cgroup2.LoadSystemd("/", "my-cgroup-abc.slice")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@ -25,7 +25,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -71,7 +72,7 @@ func (b *blkioController) Create(path string, resources *specs.LinuxResources) e
|
||||
}
|
||||
for _, t := range createBlkioSettings(resources.BlockIO) {
|
||||
if t.value != nil {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(b.Path(path), "blkio."+t.name),
|
||||
t.format(t.value),
|
||||
defaultFilePerm,
|
@ -14,31 +14,34 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// New returns a new control via the cgroup cgroups interface
|
||||
func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) {
|
||||
func New(path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) {
|
||||
config := newInitConfig()
|
||||
for _, o := range opts {
|
||||
if err := o(config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
subsystems, err := hierarchy()
|
||||
subsystems, err := config.hiearchy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -68,7 +71,7 @@ func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts .
|
||||
|
||||
// Load will load an existing cgroup and allow it to be controlled
|
||||
// All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name
|
||||
func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) {
|
||||
func Load(path Path, opts ...InitOpts) (Cgroup, error) {
|
||||
config := newInitConfig()
|
||||
for _, o := range opts {
|
||||
if err := o(config); err != nil {
|
||||
@ -76,7 +79,7 @@ func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) {
|
||||
}
|
||||
}
|
||||
var activeSubsystems []Subsystem
|
||||
subsystems, err := hierarchy()
|
||||
subsystems, err := config.hiearchy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -193,6 +196,31 @@ func (c *cgroup) AddTask(process Process, subsystems ...Name) error {
|
||||
return c.add(process, cgroupTasks, subsystems...)
|
||||
}
|
||||
|
||||
// writeCgroupsProcs writes to the file, but retries on EINVAL.
|
||||
func writeCgroupProcs(path string, content []byte, perm fs.FileMode) error {
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err = f.Write(content)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
// If the process's associated task's state is TASK_NEW, the kernel
|
||||
// returns EINVAL. The function will retry on the error like runc.
|
||||
// https://github.com/torvalds/linux/blob/v6.0/kernel/sched/core.c#L10308-L10337
|
||||
// https://github.com/opencontainers/runc/pull/1950
|
||||
if !errors.Is(err, syscall.EINVAL) {
|
||||
return err
|
||||
}
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *cgroup) add(process Process, pType procType, subsystems ...Name) error {
|
||||
if process.Pid <= 0 {
|
||||
return ErrInvalidPid
|
||||
@ -207,7 +235,7 @@ func (c *cgroup) add(process Process, pType procType, subsystems ...Name) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = retryingWriteFile(
|
||||
err = writeCgroupProcs(
|
||||
filepath.Join(s.Path(p), pType),
|
||||
[]byte(strconv.Itoa(process.Pid)),
|
||||
defaultFilePerm,
|
||||
@ -228,6 +256,15 @@ func (c *cgroup) Delete() error {
|
||||
}
|
||||
var errs []string
|
||||
for _, s := range c.subsystems {
|
||||
// kernel prevents cgroups with running process from being removed, check the tree is empty
|
||||
procs, err := c.processes(s.Name(), true, cgroupProcs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(procs) > 0 {
|
||||
errs = append(errs, fmt.Sprintf("%s (contains running processes)", string(s.Name())))
|
||||
continue
|
||||
}
|
||||
if d, ok := s.(deleter); ok {
|
||||
sp, err := c.path(s.Name())
|
||||
if err != nil {
|
||||
@ -247,6 +284,7 @@ func (c *cgroup) Delete() error {
|
||||
if err := remove(path); err != nil {
|
||||
errs = append(errs, path)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
@ -14,12 +14,12 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@ -22,7 +22,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -82,7 +82,7 @@ func (c *cpuController) Create(path string, resources *specs.LinuxResources) err
|
||||
value = []byte(strconv.FormatInt(*t.ivalue, 10))
|
||||
}
|
||||
if value != nil {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(c.Path(path), "cpu."+t.name),
|
||||
value,
|
||||
defaultFilePerm,
|
@ -14,16 +14,17 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
)
|
||||
|
||||
const nanosecondsInSecond = 1000000000
|
||||
@ -70,7 +71,7 @@ func (c *cpuacctController) Stat(path string, stats *v1.Metrics) error {
|
||||
|
||||
func (c *cpuacctController) percpuUsage(path string) ([]uint64, error) {
|
||||
var usage []uint64
|
||||
data, err := ioutil.ReadFile(filepath.Join(c.Path(path), "cpuacct.usage_percpu"))
|
||||
data, err := os.ReadFile(filepath.Join(c.Path(path), "cpuacct.usage_percpu"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -86,36 +87,41 @@ func (c *cpuacctController) percpuUsage(path string) ([]uint64, error) {
|
||||
|
||||
func (c *cpuacctController) getUsage(path string) (user uint64, kernel uint64, err error) {
|
||||
statPath := filepath.Join(c.Path(path), "cpuacct.stat")
|
||||
data, err := ioutil.ReadFile(statPath)
|
||||
f, err := os.Open(statPath)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
fields := strings.Fields(string(data))
|
||||
if len(fields) != 4 {
|
||||
return 0, 0, fmt.Errorf("%q is expected to have 4 fields", statPath)
|
||||
defer f.Close()
|
||||
var (
|
||||
raw = make(map[string]uint64)
|
||||
sc = bufio.NewScanner(f)
|
||||
)
|
||||
for sc.Scan() {
|
||||
key, v, err := parseKV(sc.Text())
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
raw[key] = v
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
for _, t := range []struct {
|
||||
index int
|
||||
name string
|
||||
value *uint64
|
||||
}{
|
||||
{
|
||||
index: 0,
|
||||
name: "user",
|
||||
value: &user,
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
name: "system",
|
||||
value: &kernel,
|
||||
},
|
||||
} {
|
||||
if fields[t.index] != t.name {
|
||||
return 0, 0, fmt.Errorf("expected field %q but found %q in %q", t.name, fields[t.index], statPath)
|
||||
}
|
||||
v, err := strconv.ParseUint(fields[t.index+1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
v, ok := raw[t.name]
|
||||
if !ok {
|
||||
return 0, 0, fmt.Errorf("expected field %q but not found in %q", t.name, statPath)
|
||||
}
|
||||
*t.value = v
|
||||
}
|
@ -14,12 +14,11 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -69,7 +68,7 @@ func (c *cpusetController) Create(path string, resources *specs.LinuxResources)
|
||||
},
|
||||
} {
|
||||
if t.value != "" {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(c.Path(path), "cpuset."+t.name),
|
||||
[]byte(t.value),
|
||||
defaultFilePerm,
|
||||
@ -87,10 +86,10 @@ func (c *cpusetController) Update(path string, resources *specs.LinuxResources)
|
||||
}
|
||||
|
||||
func (c *cpusetController) getValues(path string) (cpus []byte, mems []byte, err error) {
|
||||
if cpus, err = ioutil.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil && !os.IsNotExist(err) {
|
||||
if cpus, err = os.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil && !os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
if mems, err = ioutil.ReadFile(filepath.Join(path, "cpuset.mems")); err != nil && !os.IsNotExist(err) {
|
||||
if mems, err = os.ReadFile(filepath.Join(path, "cpuset.mems")); err != nil && !os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
return cpus, mems, nil
|
||||
@ -134,7 +133,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error {
|
||||
return err
|
||||
}
|
||||
if isEmpty(currentCpus) {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(current, "cpuset.cpus"),
|
||||
parentCpus,
|
||||
defaultFilePerm,
|
||||
@ -143,7 +142,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error {
|
||||
}
|
||||
}
|
||||
if isEmpty(currentMems) {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(current, "cpuset.mems"),
|
||||
parentMems,
|
||||
defaultFilePerm,
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -60,7 +60,7 @@ func (d *devicesController) Create(path string, resources *specs.LinuxResources)
|
||||
if device.Type == "" {
|
||||
device.Type = "a"
|
||||
}
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(d.Path(path), file),
|
||||
[]byte(deviceString(device)),
|
||||
defaultFilePerm,
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"errors"
|
@ -14,10 +14,10 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@ -50,7 +50,7 @@ func (f *freezerController) Thaw(path string) error {
|
||||
}
|
||||
|
||||
func (f *freezerController) changeState(path string, state State) error {
|
||||
return retryingWriteFile(
|
||||
return os.WriteFile(
|
||||
filepath.Join(f.root, path, "freezer.state"),
|
||||
[]byte(strings.ToUpper(string(state))),
|
||||
defaultFilePerm,
|
||||
@ -58,7 +58,7 @@ func (f *freezerController) changeState(path string, state State) error {
|
||||
}
|
||||
|
||||
func (f *freezerController) state(path string) (State, error) {
|
||||
current, err := ioutil.ReadFile(filepath.Join(f.root, path, "freezer.state"))
|
||||
current, err := os.ReadFile(filepath.Join(f.root, path, "freezer.state"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
// Hierarchy enables both unified and split hierarchy for cgroups
|
||||
type Hierarchy func() ([]Subsystem, error)
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"os"
|
||||
@ -22,7 +22,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -56,7 +56,7 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources)
|
||||
return err
|
||||
}
|
||||
for _, limit := range resources.HugepageLimits {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", limit.Pagesize, "limit_in_bytes"}, ".")),
|
||||
[]byte(strconv.FormatUint(limit.Limit, 10)),
|
||||
defaultFilePerm,
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@ -25,7 +25,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -394,7 +394,7 @@ func (m *memoryController) parseOomControlStats(r io.Reader, stat *v1.MemoryOomC
|
||||
func (m *memoryController) set(path string, settings []memorySettings) error {
|
||||
for _, t := range settings {
|
||||
if t.value != nil {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(m.Path(path), "memory."+t.name),
|
||||
[]byte(strconv.FormatInt(*t.value, 10)),
|
||||
defaultFilePerm,
|
||||
@ -472,7 +472,7 @@ func (m *memoryController) memoryEvent(path string, event MemoryEvent) (uintptr,
|
||||
defer evtFile.Close()
|
||||
data := fmt.Sprintf("%d %d %s", efd, evtFile.Fd(), event.Arg())
|
||||
evctlPath := filepath.Join(root, "cgroup.event_control")
|
||||
if err := retryingWriteFile(evctlPath, []byte(data), 0700); err != nil {
|
||||
if err := os.WriteFile(evctlPath, []byte(data), 0700); err != nil {
|
||||
unix.Close(efd)
|
||||
return 0, err
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import "path/filepath"
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"os"
|
||||
@ -47,7 +47,7 @@ func (n *netclsController) Create(path string, resources *specs.LinuxResources)
|
||||
return err
|
||||
}
|
||||
if resources.Network != nil && resources.Network.ClassID != nil && *resources.Network.ClassID > 0 {
|
||||
return retryingWriteFile(
|
||||
return os.WriteFile(
|
||||
filepath.Join(n.Path(path), "net_cls.classid"),
|
||||
[]byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)),
|
||||
defaultFilePerm,
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -48,7 +48,7 @@ func (n *netprioController) Create(path string, resources *specs.LinuxResources)
|
||||
}
|
||||
if resources.Network != nil {
|
||||
for _, prio := range resources.Network.Priorities {
|
||||
if err := retryingWriteFile(
|
||||
if err := os.WriteFile(
|
||||
filepath.Join(n.Path(path), "net_prio.ifpriomap"),
|
||||
formatPrio(prio.Name, prio.Priority),
|
||||
defaultFilePerm,
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@ -36,11 +36,13 @@ type InitOpts func(*InitConfig) error
|
||||
type InitConfig struct {
|
||||
// InitCheck can be used to check initialization errors from the subsystem
|
||||
InitCheck InitCheck
|
||||
hiearchy Hierarchy
|
||||
}
|
||||
|
||||
func newInitConfig() *InitConfig {
|
||||
return &InitConfig{
|
||||
InitCheck: RequireDevices,
|
||||
hiearchy: Default,
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,3 +61,12 @@ func RequireDevices(s Subsystem, _ Path, _ error) error {
|
||||
}
|
||||
return ErrIgnoreSubsystem
|
||||
}
|
||||
|
||||
// WithHiearchy sets a list of cgroup subsystems.
|
||||
// The default list is coming from /proc/self/mountinfo.
|
||||
func WithHiearchy(h Hierarchy) InitOpts {
|
||||
return func(c *InitConfig) error {
|
||||
c.hiearchy = h
|
||||
return nil
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"errors"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import "path/filepath"
|
||||
|
@ -14,16 +14,15 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -50,7 +49,7 @@ func (p *pidsController) Create(path string, resources *specs.LinuxResources) er
|
||||
return err
|
||||
}
|
||||
if resources.Pids != nil && resources.Pids.Limit > 0 {
|
||||
return retryingWriteFile(
|
||||
return os.WriteFile(
|
||||
filepath.Join(p.Path(path), "pids.max"),
|
||||
[]byte(strconv.FormatInt(resources.Pids.Limit, 10)),
|
||||
defaultFilePerm,
|
||||
@ -69,7 +68,7 @@ func (p *pidsController) Stat(path string, stats *v1.Metrics) error {
|
||||
return err
|
||||
}
|
||||
var max uint64
|
||||
maxData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "pids.max"))
|
||||
maxData, err := os.ReadFile(filepath.Join(p.Path(path), "pids.max"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
@ -14,17 +14,16 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -68,7 +67,7 @@ func (p *rdmaController) Create(path string, resources *specs.LinuxResources) er
|
||||
for device, limit := range resources.Rdma {
|
||||
if device != "" && (limit.HcaHandles != nil || limit.HcaObjects != nil) {
|
||||
limit := limit
|
||||
return retryingWriteFile(
|
||||
return os.WriteFile(
|
||||
filepath.Join(p.Path(path), "rdma.max"),
|
||||
[]byte(createCmdString(device, &limit)),
|
||||
defaultFilePerm,
|
||||
@ -126,13 +125,13 @@ func toRdmaEntry(strEntries []string) []*v1.RdmaEntry {
|
||||
|
||||
func (p *rdmaController) Stat(path string, stats *v1.Metrics) error {
|
||||
|
||||
currentData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.current"))
|
||||
currentData, err := os.ReadFile(filepath.Join(p.Path(path), "rdma.current"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentPerDevices := strings.Split(string(currentData), "\n")
|
||||
|
||||
maxData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.max"))
|
||||
maxData, err := os.ReadFile(filepath.Join(p.Path(path), "rdma.max"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
// State is a type that represents the state of the current cgroup
|
||||
type State string
|
1959
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.pb.go
generated
vendored
Normal file
1959
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
771
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.pb.txt
generated
vendored
Normal file
771
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.pb.txt
generated
vendored
Normal file
@ -0,0 +1,771 @@
|
||||
file {
|
||||
name: "github.com/containerd/cgroups/cgroup1/stats/metrics.proto"
|
||||
package: "io.containerd.cgroups.v1"
|
||||
message_type {
|
||||
name: "Metrics"
|
||||
field {
|
||||
name: "hugetlb"
|
||||
number: 1
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.HugetlbStat"
|
||||
json_name: "hugetlb"
|
||||
}
|
||||
field {
|
||||
name: "pids"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.PidsStat"
|
||||
json_name: "pids"
|
||||
}
|
||||
field {
|
||||
name: "cpu"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.CPUStat"
|
||||
json_name: "cpu"
|
||||
}
|
||||
field {
|
||||
name: "memory"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryStat"
|
||||
json_name: "memory"
|
||||
}
|
||||
field {
|
||||
name: "blkio"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOStat"
|
||||
json_name: "blkio"
|
||||
}
|
||||
field {
|
||||
name: "rdma"
|
||||
number: 6
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.RdmaStat"
|
||||
json_name: "rdma"
|
||||
}
|
||||
field {
|
||||
name: "network"
|
||||
number: 7
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.NetworkStat"
|
||||
json_name: "network"
|
||||
}
|
||||
field {
|
||||
name: "cgroup_stats"
|
||||
number: 8
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.CgroupStats"
|
||||
json_name: "cgroupStats"
|
||||
}
|
||||
field {
|
||||
name: "memory_oom_control"
|
||||
number: 9
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryOomControl"
|
||||
json_name: "memoryOomControl"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "HugetlbStat"
|
||||
field {
|
||||
name: "usage"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "usage"
|
||||
}
|
||||
field {
|
||||
name: "max"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "max"
|
||||
}
|
||||
field {
|
||||
name: "failcnt"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "failcnt"
|
||||
}
|
||||
field {
|
||||
name: "pagesize"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
json_name: "pagesize"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "PidsStat"
|
||||
field {
|
||||
name: "current"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "current"
|
||||
}
|
||||
field {
|
||||
name: "limit"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "limit"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "CPUStat"
|
||||
field {
|
||||
name: "usage"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.CPUUsage"
|
||||
json_name: "usage"
|
||||
}
|
||||
field {
|
||||
name: "throttling"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.Throttle"
|
||||
json_name: "throttling"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "CPUUsage"
|
||||
field {
|
||||
name: "total"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "total"
|
||||
}
|
||||
field {
|
||||
name: "kernel"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "kernel"
|
||||
}
|
||||
field {
|
||||
name: "user"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "user"
|
||||
}
|
||||
field {
|
||||
name: "per_cpu"
|
||||
number: 4
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_UINT64
|
||||
json_name: "perCpu"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "Throttle"
|
||||
field {
|
||||
name: "periods"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "periods"
|
||||
}
|
||||
field {
|
||||
name: "throttled_periods"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "throttledPeriods"
|
||||
}
|
||||
field {
|
||||
name: "throttled_time"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "throttledTime"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "MemoryStat"
|
||||
field {
|
||||
name: "cache"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "cache"
|
||||
}
|
||||
field {
|
||||
name: "rss"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rss"
|
||||
}
|
||||
field {
|
||||
name: "rss_huge"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rssHuge"
|
||||
}
|
||||
field {
|
||||
name: "mapped_file"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "mappedFile"
|
||||
}
|
||||
field {
|
||||
name: "dirty"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "dirty"
|
||||
}
|
||||
field {
|
||||
name: "writeback"
|
||||
number: 6
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "writeback"
|
||||
}
|
||||
field {
|
||||
name: "pg_pg_in"
|
||||
number: 7
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "pgPgIn"
|
||||
}
|
||||
field {
|
||||
name: "pg_pg_out"
|
||||
number: 8
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "pgPgOut"
|
||||
}
|
||||
field {
|
||||
name: "pg_fault"
|
||||
number: 9
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "pgFault"
|
||||
}
|
||||
field {
|
||||
name: "pg_maj_fault"
|
||||
number: 10
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "pgMajFault"
|
||||
}
|
||||
field {
|
||||
name: "inactive_anon"
|
||||
number: 11
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "inactiveAnon"
|
||||
}
|
||||
field {
|
||||
name: "active_anon"
|
||||
number: 12
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "activeAnon"
|
||||
}
|
||||
field {
|
||||
name: "inactive_file"
|
||||
number: 13
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "inactiveFile"
|
||||
}
|
||||
field {
|
||||
name: "active_file"
|
||||
number: 14
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "activeFile"
|
||||
}
|
||||
field {
|
||||
name: "unevictable"
|
||||
number: 15
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "unevictable"
|
||||
}
|
||||
field {
|
||||
name: "hierarchical_memory_limit"
|
||||
number: 16
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "hierarchicalMemoryLimit"
|
||||
}
|
||||
field {
|
||||
name: "hierarchical_swap_limit"
|
||||
number: 17
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "hierarchicalSwapLimit"
|
||||
}
|
||||
field {
|
||||
name: "total_cache"
|
||||
number: 18
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalCache"
|
||||
}
|
||||
field {
|
||||
name: "total_rss"
|
||||
number: 19
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalRss"
|
||||
}
|
||||
field {
|
||||
name: "total_rss_huge"
|
||||
number: 20
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalRssHuge"
|
||||
}
|
||||
field {
|
||||
name: "total_mapped_file"
|
||||
number: 21
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalMappedFile"
|
||||
}
|
||||
field {
|
||||
name: "total_dirty"
|
||||
number: 22
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalDirty"
|
||||
}
|
||||
field {
|
||||
name: "total_writeback"
|
||||
number: 23
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalWriteback"
|
||||
}
|
||||
field {
|
||||
name: "total_pg_pg_in"
|
||||
number: 24
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalPgPgIn"
|
||||
}
|
||||
field {
|
||||
name: "total_pg_pg_out"
|
||||
number: 25
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalPgPgOut"
|
||||
}
|
||||
field {
|
||||
name: "total_pg_fault"
|
||||
number: 26
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalPgFault"
|
||||
}
|
||||
field {
|
||||
name: "total_pg_maj_fault"
|
||||
number: 27
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalPgMajFault"
|
||||
}
|
||||
field {
|
||||
name: "total_inactive_anon"
|
||||
number: 28
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalInactiveAnon"
|
||||
}
|
||||
field {
|
||||
name: "total_active_anon"
|
||||
number: 29
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalActiveAnon"
|
||||
}
|
||||
field {
|
||||
name: "total_inactive_file"
|
||||
number: 30
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalInactiveFile"
|
||||
}
|
||||
field {
|
||||
name: "total_active_file"
|
||||
number: 31
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalActiveFile"
|
||||
}
|
||||
field {
|
||||
name: "total_unevictable"
|
||||
number: 32
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "totalUnevictable"
|
||||
}
|
||||
field {
|
||||
name: "usage"
|
||||
number: 33
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryEntry"
|
||||
json_name: "usage"
|
||||
}
|
||||
field {
|
||||
name: "swap"
|
||||
number: 34
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryEntry"
|
||||
json_name: "swap"
|
||||
}
|
||||
field {
|
||||
name: "kernel"
|
||||
number: 35
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryEntry"
|
||||
json_name: "kernel"
|
||||
}
|
||||
field {
|
||||
name: "kernel_tcp"
|
||||
number: 36
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.MemoryEntry"
|
||||
json_name: "kernelTcp"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "MemoryEntry"
|
||||
field {
|
||||
name: "limit"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "limit"
|
||||
}
|
||||
field {
|
||||
name: "usage"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "usage"
|
||||
}
|
||||
field {
|
||||
name: "max"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "max"
|
||||
}
|
||||
field {
|
||||
name: "failcnt"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "failcnt"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "MemoryOomControl"
|
||||
field {
|
||||
name: "oom_kill_disable"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "oomKillDisable"
|
||||
}
|
||||
field {
|
||||
name: "under_oom"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "underOom"
|
||||
}
|
||||
field {
|
||||
name: "oom_kill"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "oomKill"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "BlkIOStat"
|
||||
field {
|
||||
name: "io_service_bytes_recursive"
|
||||
number: 1
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioServiceBytesRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_serviced_recursive"
|
||||
number: 2
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioServicedRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_queued_recursive"
|
||||
number: 3
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioQueuedRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_service_time_recursive"
|
||||
number: 4
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioServiceTimeRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_wait_time_recursive"
|
||||
number: 5
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioWaitTimeRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_merged_recursive"
|
||||
number: 6
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioMergedRecursive"
|
||||
}
|
||||
field {
|
||||
name: "io_time_recursive"
|
||||
number: 7
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "ioTimeRecursive"
|
||||
}
|
||||
field {
|
||||
name: "sectors_recursive"
|
||||
number: 8
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.BlkIOEntry"
|
||||
json_name: "sectorsRecursive"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "BlkIOEntry"
|
||||
field {
|
||||
name: "op"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
json_name: "op"
|
||||
}
|
||||
field {
|
||||
name: "device"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
json_name: "device"
|
||||
}
|
||||
field {
|
||||
name: "major"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "major"
|
||||
}
|
||||
field {
|
||||
name: "minor"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "minor"
|
||||
}
|
||||
field {
|
||||
name: "value"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "value"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "RdmaStat"
|
||||
field {
|
||||
name: "current"
|
||||
number: 1
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.RdmaEntry"
|
||||
json_name: "current"
|
||||
}
|
||||
field {
|
||||
name: "limit"
|
||||
number: 2
|
||||
label: LABEL_REPEATED
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v1.RdmaEntry"
|
||||
json_name: "limit"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "RdmaEntry"
|
||||
field {
|
||||
name: "device"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
json_name: "device"
|
||||
}
|
||||
field {
|
||||
name: "hca_handles"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT32
|
||||
json_name: "hcaHandles"
|
||||
}
|
||||
field {
|
||||
name: "hca_objects"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT32
|
||||
json_name: "hcaObjects"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "NetworkStat"
|
||||
field {
|
||||
name: "name"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_STRING
|
||||
json_name: "name"
|
||||
}
|
||||
field {
|
||||
name: "rx_bytes"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rxBytes"
|
||||
}
|
||||
field {
|
||||
name: "rx_packets"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rxPackets"
|
||||
}
|
||||
field {
|
||||
name: "rx_errors"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rxErrors"
|
||||
}
|
||||
field {
|
||||
name: "rx_dropped"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "rxDropped"
|
||||
}
|
||||
field {
|
||||
name: "tx_bytes"
|
||||
number: 6
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "txBytes"
|
||||
}
|
||||
field {
|
||||
name: "tx_packets"
|
||||
number: 7
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "txPackets"
|
||||
}
|
||||
field {
|
||||
name: "tx_errors"
|
||||
number: 8
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "txErrors"
|
||||
}
|
||||
field {
|
||||
name: "tx_dropped"
|
||||
number: 9
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "txDropped"
|
||||
}
|
||||
}
|
||||
message_type {
|
||||
name: "CgroupStats"
|
||||
field {
|
||||
name: "nr_sleeping"
|
||||
number: 1
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "nrSleeping"
|
||||
}
|
||||
field {
|
||||
name: "nr_running"
|
||||
number: 2
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "nrRunning"
|
||||
}
|
||||
field {
|
||||
name: "nr_stopped"
|
||||
number: 3
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "nrStopped"
|
||||
}
|
||||
field {
|
||||
name: "nr_uninterruptible"
|
||||
number: 4
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "nrUninterruptible"
|
||||
}
|
||||
field {
|
||||
name: "nr_io_wait"
|
||||
number: 5
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_UINT64
|
||||
json_name: "nrIoWait"
|
||||
}
|
||||
}
|
||||
options {
|
||||
go_package: "github.com/containerd/cgroups/cgroup1/stats"
|
||||
}
|
||||
syntax: "proto3"
|
||||
}
|
158
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.proto
generated
vendored
Normal file
158
vendor/github.com/containerd/cgroups/v3/cgroup1/stats/metrics.proto
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package io.containerd.cgroups.v1;
|
||||
|
||||
option go_package = "github.com/containerd/cgroups/cgroup1/stats";
|
||||
|
||||
message Metrics {
|
||||
repeated HugetlbStat hugetlb = 1;
|
||||
PidsStat pids = 2;
|
||||
CPUStat cpu = 3;
|
||||
MemoryStat memory = 4;
|
||||
BlkIOStat blkio = 5;
|
||||
RdmaStat rdma = 6;
|
||||
repeated NetworkStat network = 7;
|
||||
CgroupStats cgroup_stats = 8;
|
||||
MemoryOomControl memory_oom_control = 9;
|
||||
}
|
||||
|
||||
message HugetlbStat {
|
||||
uint64 usage = 1;
|
||||
uint64 max = 2;
|
||||
uint64 failcnt = 3;
|
||||
string pagesize = 4;
|
||||
}
|
||||
|
||||
message PidsStat {
|
||||
uint64 current = 1;
|
||||
uint64 limit = 2;
|
||||
}
|
||||
|
||||
message CPUStat {
|
||||
CPUUsage usage = 1;
|
||||
Throttle throttling = 2;
|
||||
}
|
||||
|
||||
message CPUUsage {
|
||||
// values in nanoseconds
|
||||
uint64 total = 1;
|
||||
uint64 kernel = 2;
|
||||
uint64 user = 3;
|
||||
repeated uint64 per_cpu = 4;
|
||||
|
||||
}
|
||||
|
||||
message Throttle {
|
||||
uint64 periods = 1;
|
||||
uint64 throttled_periods = 2;
|
||||
uint64 throttled_time = 3;
|
||||
}
|
||||
|
||||
message MemoryStat {
|
||||
uint64 cache = 1;
|
||||
uint64 rss = 2;
|
||||
uint64 rss_huge = 3;
|
||||
uint64 mapped_file = 4;
|
||||
uint64 dirty = 5;
|
||||
uint64 writeback = 6;
|
||||
uint64 pg_pg_in = 7;
|
||||
uint64 pg_pg_out = 8;
|
||||
uint64 pg_fault = 9;
|
||||
uint64 pg_maj_fault = 10;
|
||||
uint64 inactive_anon = 11;
|
||||
uint64 active_anon = 12;
|
||||
uint64 inactive_file = 13;
|
||||
uint64 active_file = 14;
|
||||
uint64 unevictable = 15;
|
||||
uint64 hierarchical_memory_limit = 16;
|
||||
uint64 hierarchical_swap_limit = 17;
|
||||
uint64 total_cache = 18;
|
||||
uint64 total_rss = 19;
|
||||
uint64 total_rss_huge = 20;
|
||||
uint64 total_mapped_file = 21;
|
||||
uint64 total_dirty = 22;
|
||||
uint64 total_writeback = 23;
|
||||
uint64 total_pg_pg_in = 24;
|
||||
uint64 total_pg_pg_out = 25;
|
||||
uint64 total_pg_fault = 26;
|
||||
uint64 total_pg_maj_fault = 27;
|
||||
uint64 total_inactive_anon = 28;
|
||||
uint64 total_active_anon = 29;
|
||||
uint64 total_inactive_file = 30;
|
||||
uint64 total_active_file = 31;
|
||||
uint64 total_unevictable = 32;
|
||||
MemoryEntry usage = 33;
|
||||
MemoryEntry swap = 34;
|
||||
MemoryEntry kernel = 35;
|
||||
MemoryEntry kernel_tcp = 36;
|
||||
|
||||
}
|
||||
|
||||
message MemoryEntry {
|
||||
uint64 limit = 1;
|
||||
uint64 usage = 2;
|
||||
uint64 max = 3;
|
||||
uint64 failcnt = 4;
|
||||
}
|
||||
|
||||
message MemoryOomControl {
|
||||
uint64 oom_kill_disable = 1;
|
||||
uint64 under_oom = 2;
|
||||
uint64 oom_kill = 3;
|
||||
}
|
||||
|
||||
message BlkIOStat {
|
||||
repeated BlkIOEntry io_service_bytes_recursive = 1;
|
||||
repeated BlkIOEntry io_serviced_recursive = 2;
|
||||
repeated BlkIOEntry io_queued_recursive = 3;
|
||||
repeated BlkIOEntry io_service_time_recursive = 4;
|
||||
repeated BlkIOEntry io_wait_time_recursive = 5;
|
||||
repeated BlkIOEntry io_merged_recursive = 6;
|
||||
repeated BlkIOEntry io_time_recursive = 7;
|
||||
repeated BlkIOEntry sectors_recursive = 8;
|
||||
}
|
||||
|
||||
message BlkIOEntry {
|
||||
string op = 1;
|
||||
string device = 2;
|
||||
uint64 major = 3;
|
||||
uint64 minor = 4;
|
||||
uint64 value = 5;
|
||||
}
|
||||
|
||||
message RdmaStat {
|
||||
repeated RdmaEntry current = 1;
|
||||
repeated RdmaEntry limit = 2;
|
||||
}
|
||||
|
||||
message RdmaEntry {
|
||||
string device = 1;
|
||||
uint32 hca_handles = 2;
|
||||
uint32 hca_objects = 3;
|
||||
}
|
||||
|
||||
message NetworkStat {
|
||||
string name = 1;
|
||||
uint64 rx_bytes = 2;
|
||||
uint64 rx_packets = 3;
|
||||
uint64 rx_errors = 4;
|
||||
uint64 rx_dropped = 5;
|
||||
uint64 tx_bytes = 6;
|
||||
uint64 tx_packets = 7;
|
||||
uint64 tx_errors = 8;
|
||||
uint64 tx_dropped = 9;
|
||||
}
|
||||
|
||||
// CgroupStats exports per-cgroup statistics.
|
||||
message CgroupStats {
|
||||
// number of tasks sleeping
|
||||
uint64 nr_sleeping = 1;
|
||||
// number of tasks running
|
||||
uint64 nr_running = 2;
|
||||
// number of tasks in stopped state
|
||||
uint64 nr_stopped = 3;
|
||||
// number of tasks in uninterruptible state
|
||||
uint64 nr_uninterruptible = 4;
|
||||
// number of tasks waiting on IO
|
||||
uint64 nr_io_wait = 5;
|
||||
}
|
@ -14,13 +14,14 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
"github.com/containerd/cgroups/v3"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
@ -59,7 +60,7 @@ func Subsystems() []Name {
|
||||
Blkio,
|
||||
Rdma,
|
||||
}
|
||||
if !RunningInUserNS() {
|
||||
if !cgroups.RunningInUserNS() {
|
||||
n = append(n, Devices)
|
||||
}
|
||||
if _, err := os.Stat("/sys/kernel/mm/hugepages"); err == nil {
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"context"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
func getClockTicks() uint64 {
|
||||
// The value comes from `C.sysconf(C._SC_CLK_TCK)`, and
|
@ -14,107 +14,23 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v3"
|
||||
units "github.com/docker/go-units"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
nsOnce sync.Once
|
||||
inUserNS bool
|
||||
checkMode sync.Once
|
||||
cgMode CGMode
|
||||
)
|
||||
|
||||
const unifiedMountpoint = "/sys/fs/cgroup"
|
||||
|
||||
// CGMode is the cgroups mode of the host system
|
||||
type CGMode int
|
||||
|
||||
const (
|
||||
// Unavailable cgroup mountpoint
|
||||
Unavailable CGMode = iota
|
||||
// Legacy cgroups v1
|
||||
Legacy
|
||||
// Hybrid with cgroups v1 and v2 controllers mounted
|
||||
Hybrid
|
||||
// Unified with only cgroups v2 mounted
|
||||
Unified
|
||||
)
|
||||
|
||||
// Mode returns the cgroups mode running on the host
|
||||
func Mode() CGMode {
|
||||
checkMode.Do(func() {
|
||||
var st unix.Statfs_t
|
||||
if err := unix.Statfs(unifiedMountpoint, &st); err != nil {
|
||||
cgMode = Unavailable
|
||||
return
|
||||
}
|
||||
switch st.Type {
|
||||
case unix.CGROUP2_SUPER_MAGIC:
|
||||
cgMode = Unified
|
||||
default:
|
||||
cgMode = Legacy
|
||||
if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil {
|
||||
return
|
||||
}
|
||||
if st.Type == unix.CGROUP2_SUPER_MAGIC {
|
||||
cgMode = Hybrid
|
||||
}
|
||||
}
|
||||
})
|
||||
return cgMode
|
||||
}
|
||||
|
||||
// RunningInUserNS detects whether we are currently running in a user namespace.
|
||||
// Copied from github.com/lxc/lxd/shared/util.go
|
||||
func RunningInUserNS() bool {
|
||||
nsOnce.Do(func() {
|
||||
file, err := os.Open("/proc/self/uid_map")
|
||||
if err != nil {
|
||||
// This kernel-provided file only exists if user namespaces are supported
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
buf := bufio.NewReader(file)
|
||||
l, _, err := buf.ReadLine()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
line := string(l)
|
||||
var a, b, c int64
|
||||
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
|
||||
|
||||
/*
|
||||
* We assume we are in the initial user namespace if we have a full
|
||||
* range - 4294967295 uids starting at uid 0.
|
||||
*/
|
||||
if a == 0 && b == 0 && c == 4294967295 {
|
||||
return
|
||||
}
|
||||
inUserNS = true
|
||||
})
|
||||
return inUserNS
|
||||
}
|
||||
|
||||
// defaults returns all known groups
|
||||
func defaults(root string) ([]Subsystem, error) {
|
||||
h, err := NewHugetlb(root)
|
||||
@ -137,7 +53,7 @@ func defaults(root string) ([]Subsystem, error) {
|
||||
}
|
||||
// only add the devices cgroup if we are not in a user namespace
|
||||
// because modifications are not allowed
|
||||
if !RunningInUserNS() {
|
||||
if !cgroups.RunningInUserNS() {
|
||||
s = append(s, NewDevices(root))
|
||||
}
|
||||
// add the hugetlb cgroup if error wasn't due to missing hugetlb
|
||||
@ -200,7 +116,7 @@ func hugePageSizes() ([]string, error) {
|
||||
pageSizes []string
|
||||
sizeList = []string{"B", "KB", "MB", "GB", "TB", "PB"}
|
||||
)
|
||||
files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages")
|
||||
files, err := os.ReadDir("/sys/kernel/mm/hugepages")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -216,7 +132,7 @@ func hugePageSizes() ([]string, error) {
|
||||
}
|
||||
|
||||
func readUint(path string) (uint64, error) {
|
||||
v, err := ioutil.ReadFile(path)
|
||||
v, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -257,8 +173,10 @@ func parseKV(raw string) (string, uint64, error) {
|
||||
|
||||
// ParseCgroupFile parses the given cgroup file, typically /proc/self/cgroup
|
||||
// or /proc/<pid>/cgroup, into a map of subsystems to cgroup paths, e.g.
|
||||
//
|
||||
// "cpu": "/user.slice/user-1000.slice"
|
||||
// "pids": "/user.slice/user-1000.slice"
|
||||
//
|
||||
// etc.
|
||||
//
|
||||
// The resulting map does not have an element for cgroup v2 unified hierarchy.
|
||||
@ -377,16 +295,3 @@ func cleanPath(path string) string {
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func retryingWriteFile(path string, data []byte, mode os.FileMode) error {
|
||||
// Retry writes on EINTR; see:
|
||||
// https://github.com/golang/go/issues/38033
|
||||
for {
|
||||
err := ioutil.WriteFile(path, data, mode)
|
||||
if err == nil {
|
||||
return nil
|
||||
} else if !errors.Is(err, syscall.EINTR) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
package cgroup1
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@ -24,8 +24,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// V1 returns all the groups in the default cgroups mountpoint in a single hierarchy
|
||||
func V1() ([]Subsystem, error) {
|
||||
// Default returns all the groups in the default cgroups mountpoint in a single hierarchy
|
||||
func Default() ([]Subsystem, error) {
|
||||
root, err := v1MountPoint()
|
||||
if err != nil {
|
||||
return nil, err
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"math"
|
@ -24,7 +24,7 @@
|
||||
// This particular Go implementation based on runc version
|
||||
// https://github.com/opencontainers/runc/blob/master/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"errors"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"errors"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import "strings"
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import "fmt"
|
||||
|
@ -14,14 +14,14 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -30,7 +30,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
"github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||
|
||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
||||
"github.com/godbus/dbus/v5"
|
||||
@ -147,7 +147,7 @@ func (c *Value) write(path string, perm os.FileMode) error {
|
||||
// Retry writes on EINTR; see:
|
||||
// https://github.com/golang/go/issues/38033
|
||||
for {
|
||||
err := ioutil.WriteFile(
|
||||
err := os.WriteFile(
|
||||
filepath.Join(path, c.filename),
|
||||
data,
|
||||
perm,
|
||||
@ -196,13 +196,35 @@ func NewManager(mountpoint string, group string, resources *Resources) (*Manager
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func LoadManager(mountpoint string, group string) (*Manager, error) {
|
||||
type InitConfig struct {
|
||||
mountpoint string
|
||||
}
|
||||
|
||||
type InitOpts func(c *InitConfig) error
|
||||
|
||||
// WithMountpoint sets the unified mountpoint. The deault path is /sys/fs/cgroup.
|
||||
func WithMountpoint(path string) InitOpts {
|
||||
return func(c *InitConfig) error {
|
||||
c.mountpoint = path
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Load a cgroup.
|
||||
func Load(group string, opts ...InitOpts) (*Manager, error) {
|
||||
c := InitConfig{mountpoint: defaultCgroup2Path}
|
||||
for _, opt := range opts {
|
||||
if err := opt(&c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := VerifyGroupPath(group); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := filepath.Join(mountpoint, group)
|
||||
path := filepath.Join(c.mountpoint, group)
|
||||
return &Manager{
|
||||
unifiedMountpoint: mountpoint,
|
||||
unifiedMountpoint: c.mountpoint,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
@ -225,7 +247,7 @@ func setResources(path string, resources *Resources) error {
|
||||
}
|
||||
|
||||
func (c *Manager) RootControllers() ([]string, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join(c.unifiedMountpoint, controllersFile))
|
||||
b, err := os.ReadFile(filepath.Join(c.unifiedMountpoint, controllersFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -233,7 +255,7 @@ func (c *Manager) RootControllers() ([]string, error) {
|
||||
}
|
||||
|
||||
func (c *Manager) Controllers() ([]string, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join(c.path, controllersFile))
|
||||
b, err := os.ReadFile(filepath.Join(c.path, controllersFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -336,7 +358,23 @@ func (c *Manager) AddProc(pid uint64) error {
|
||||
return writeValues(c.path, []Value{v})
|
||||
}
|
||||
|
||||
func (c *Manager) AddThread(tid uint64) error {
|
||||
v := Value{
|
||||
filename: cgroupThreads,
|
||||
value: tid,
|
||||
}
|
||||
return writeValues(c.path, []Value{v})
|
||||
}
|
||||
|
||||
func (c *Manager) Delete() error {
|
||||
// kernel prevents cgroups with running process from being removed, check the tree is empty
|
||||
processes, err := c.Procs(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(processes) > 0 {
|
||||
return fmt.Errorf("cgroups: unable to remove path %q: still contains running processes", c.path)
|
||||
}
|
||||
return remove(c.path)
|
||||
}
|
||||
|
||||
@ -522,7 +560,7 @@ func readSingleFile(path string, file string, out map[string]interface{}) error
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
data, err := ioutil.ReadAll(f)
|
||||
data, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
type Memory struct {
|
||||
Swap *int64
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import "strconv"
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -14,10 +14,10 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
@ -50,7 +50,7 @@ func (s State) Values() []Value {
|
||||
}
|
||||
|
||||
func fetchState(path string) (State, error) {
|
||||
current, err := ioutil.ReadFile(filepath.Join(path, cgroupFreeze))
|
||||
current, err := os.ReadFile(filepath.Join(path, cgroupFreeze))
|
||||
if err != nil {
|
||||
return Unknown, err
|
||||
}
|
17
vendor/github.com/containerd/cgroups/v3/cgroup2/stats/doc.go
generated
vendored
Normal file
17
vendor/github.com/containerd/cgroups/v3/cgroup2/stats/doc.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package stats
|
1333
vendor/github.com/containerd/cgroups/v3/cgroup2/stats/metrics.pb.go
generated
vendored
Normal file
1333
vendor/github.com/containerd/cgroups/v3/cgroup2/stats/metrics.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
||||
file {
|
||||
name: "github.com/containerd/cgroups/v2/stats/metrics.proto"
|
||||
name: "github.com/containerd/cgroups/cgroup2/stats/metrics.proto"
|
||||
package: "io.containerd.cgroups.v2"
|
||||
dependency: "gogoproto/gogo.proto"
|
||||
message_type {
|
||||
name: "Metrics"
|
||||
field {
|
||||
@ -18,9 +17,6 @@ file {
|
||||
label: LABEL_OPTIONAL
|
||||
type: TYPE_MESSAGE
|
||||
type_name: ".io.containerd.cgroups.v2.CPUStat"
|
||||
options {
|
||||
65004: "CPU"
|
||||
}
|
||||
json_name: "cpu"
|
||||
}
|
||||
field {
|
||||
@ -535,5 +531,8 @@ file {
|
||||
json_name: "pagesize"
|
||||
}
|
||||
}
|
||||
options {
|
||||
go_package: "github.com/containerd/cgroups/cgroup2/stats"
|
||||
}
|
||||
syntax: "proto3"
|
||||
}
|
@ -2,11 +2,11 @@ syntax = "proto3";
|
||||
|
||||
package io.containerd.cgroups.v2;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
option go_package = "github.com/containerd/cgroups/cgroup2/stats";
|
||||
|
||||
message Metrics {
|
||||
PidsStat pids = 1;
|
||||
CPUStat cpu = 2 [(gogoproto.customname) = "CPU"];
|
||||
CPUStat cpu = 2;
|
||||
MemoryStat memory = 4;
|
||||
RdmaStat rdma = 5;
|
||||
IOStat io = 6;
|
@ -14,13 +14,12 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v2
|
||||
package cgroup2
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -28,7 +27,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/cgroups/v2/stats"
|
||||
"github.com/containerd/cgroups/v3/cgroup2/stats"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -37,6 +36,7 @@ import (
|
||||
|
||||
const (
|
||||
cgroupProcs = "cgroup.procs"
|
||||
cgroupThreads = "cgroup.threads"
|
||||
defaultDirPerm = 0755
|
||||
)
|
||||
|
||||
@ -242,7 +242,7 @@ func ToResources(spec *specs.LinuxResources) *Resources {
|
||||
|
||||
// Gets uint64 parsed content of single value cgroup stat file
|
||||
func getStatFileContentUint64(filePath string) uint64 {
|
||||
contents, err := ioutil.ReadFile(filePath)
|
||||
contents, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
@ -264,7 +264,7 @@ func readIoStats(path string) []*stats.IOEntry {
|
||||
// more details on the io.stat file format: https://www.kernel.org/doc/Documentation/cgroup-v2.txt
|
||||
var usage []*stats.IOEntry
|
||||
fpath := filepath.Join(path, "io.stat")
|
||||
currentData, err := ioutil.ReadFile(fpath)
|
||||
currentData, err := os.ReadFile(fpath)
|
||||
if err != nil {
|
||||
return usage
|
||||
}
|
||||
@ -318,7 +318,7 @@ func readIoStats(path string) []*stats.IOEntry {
|
||||
}
|
||||
|
||||
func rdmaStats(filepath string) []*stats.RdmaEntry {
|
||||
currentData, err := ioutil.ReadFile(filepath)
|
||||
currentData, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
return []*stats.RdmaEntry{}
|
||||
}
|
||||
@ -406,7 +406,7 @@ func readHugeTlbStats(path string) []*stats.HugeTlbStat {
|
||||
hugeTlb = &stats.HugeTlbStat{}
|
||||
}
|
||||
hugeTlb.Pagesize = pageSize
|
||||
out, err := ioutil.ReadFile(filepath.Join(path, file.Name()))
|
||||
out, err := os.ReadFile(filepath.Join(path, file.Name()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
107
vendor/github.com/containerd/cgroups/v3/utils.go
generated
vendored
Normal file
107
vendor/github.com/containerd/cgroups/v3/utils.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cgroups
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
nsOnce sync.Once
|
||||
inUserNS bool
|
||||
checkMode sync.Once
|
||||
cgMode CGMode
|
||||
)
|
||||
|
||||
const unifiedMountpoint = "/sys/fs/cgroup"
|
||||
|
||||
// CGMode is the cgroups mode of the host system
|
||||
type CGMode int
|
||||
|
||||
const (
|
||||
// Unavailable cgroup mountpoint
|
||||
Unavailable CGMode = iota
|
||||
// Legacy cgroups v1
|
||||
Legacy
|
||||
// Hybrid with cgroups v1 and v2 controllers mounted
|
||||
Hybrid
|
||||
// Unified with only cgroups v2 mounted
|
||||
Unified
|
||||
)
|
||||
|
||||
// Mode returns the cgroups mode running on the host
|
||||
func Mode() CGMode {
|
||||
checkMode.Do(func() {
|
||||
var st unix.Statfs_t
|
||||
if err := unix.Statfs(unifiedMountpoint, &st); err != nil {
|
||||
cgMode = Unavailable
|
||||
return
|
||||
}
|
||||
switch st.Type {
|
||||
case unix.CGROUP2_SUPER_MAGIC:
|
||||
cgMode = Unified
|
||||
default:
|
||||
cgMode = Legacy
|
||||
if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil {
|
||||
return
|
||||
}
|
||||
if st.Type == unix.CGROUP2_SUPER_MAGIC {
|
||||
cgMode = Hybrid
|
||||
}
|
||||
}
|
||||
})
|
||||
return cgMode
|
||||
}
|
||||
|
||||
// RunningInUserNS detects whether we are currently running in a user namespace.
|
||||
// Copied from github.com/lxc/lxd/shared/util.go
|
||||
func RunningInUserNS() bool {
|
||||
nsOnce.Do(func() {
|
||||
file, err := os.Open("/proc/self/uid_map")
|
||||
if err != nil {
|
||||
// This kernel-provided file only exists if user namespaces are supported
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
buf := bufio.NewReader(file)
|
||||
l, _, err := buf.ReadLine()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
line := string(l)
|
||||
var a, b, c int64
|
||||
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
|
||||
|
||||
/*
|
||||
* We assume we are in the initial user namespace if we have a full
|
||||
* range - 4294967295 uids starting at uid 0.
|
||||
*/
|
||||
if a == 0 && b == 0 && c == 4294967295 {
|
||||
return
|
||||
}
|
||||
inUserNS = true
|
||||
})
|
||||
return inUserNS
|
||||
}
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -93,10 +93,14 @@ github.com/containerd/aufs/plugin
|
||||
github.com/containerd/btrfs
|
||||
# github.com/containerd/cgroups v1.0.5-0.20220816231112-7083cd60b721
|
||||
## explicit; go 1.17
|
||||
github.com/containerd/cgroups
|
||||
github.com/containerd/cgroups/stats/v1
|
||||
github.com/containerd/cgroups/v2
|
||||
github.com/containerd/cgroups/v2/stats
|
||||
# github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774
|
||||
## explicit; go 1.17
|
||||
github.com/containerd/cgroups/v3
|
||||
github.com/containerd/cgroups/v3/cgroup1
|
||||
github.com/containerd/cgroups/v3/cgroup1/stats
|
||||
github.com/containerd/cgroups/v3/cgroup2
|
||||
github.com/containerd/cgroups/v3/cgroup2/stats
|
||||
# github.com/containerd/console v1.0.3
|
||||
## explicit; go 1.13
|
||||
github.com/containerd/console
|
||||
|
Loading…
Reference in New Issue
Block a user