mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 02:41:25 +00:00
Bump cAdvisor to v0.43.0
Bumping cAdvisor from v0.39.2 -> v0.43.0 * Also pin transitive dependencies * containerd v1.4.9 -> v1.4.11 * docker v20.10.2+incompatible> v20.10.7+incompatible Signed-off-by: David Porter <david@porter.me>
This commit is contained in:
parent
e4adf7f31c
commit
c6452be958
11
go.mod
11
go.mod
@ -32,7 +32,7 @@ require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker v20.10.2+incompatible
|
||||
github.com/docker/docker v20.10.7+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153
|
||||
@ -45,7 +45,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||
github.com/golang/mock v1.5.0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/cadvisor v0.39.2
|
||||
github.com/google/cadvisor v0.43.0
|
||||
github.com/google/go-cmp v0.5.5
|
||||
github.com/google/gofuzz v1.1.0
|
||||
github.com/google/uuid v1.1.2
|
||||
@ -78,6 +78,7 @@ require (
|
||||
github.com/storageos/go-api v2.2.0+incompatible
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/vishvananda/netlink v1.1.0
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
|
||||
github.com/vmware/govmomi v0.20.3
|
||||
go.etcd.io/etcd/api/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0
|
||||
@ -198,7 +199,7 @@ replace (
|
||||
github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.5.0
|
||||
github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1
|
||||
github.com/containerd/console => github.com/containerd/console v1.0.2
|
||||
github.com/containerd/containerd => github.com/containerd/containerd v1.4.9
|
||||
github.com/containerd/containerd => github.com/containerd/containerd v1.4.11
|
||||
github.com/containerd/continuity => github.com/containerd/continuity v0.1.0
|
||||
github.com/containerd/fifo => github.com/containerd/fifo v1.0.0
|
||||
github.com/containerd/go-runc => github.com/containerd/go-runc v1.0.0
|
||||
@ -217,7 +218,7 @@ replace (
|
||||
github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd
|
||||
github.com/dnaeon/go-vcr => github.com/dnaeon/go-vcr v1.0.1
|
||||
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible
|
||||
github.com/docker/docker => github.com/docker/docker v20.10.7+incompatible
|
||||
github.com/docker/go-connections => github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units => github.com/docker/go-units v0.4.0
|
||||
github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
@ -262,7 +263,7 @@ replace (
|
||||
github.com/golang/protobuf => github.com/golang/protobuf v1.5.2
|
||||
github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e
|
||||
github.com/google/btree => github.com/google/btree v1.0.1
|
||||
github.com/google/cadvisor => github.com/google/cadvisor v0.39.2
|
||||
github.com/google/cadvisor => github.com/google/cadvisor v0.43.0
|
||||
github.com/google/go-cmp => github.com/google/go-cmp v0.5.5
|
||||
github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
|
||||
github.com/google/martian/v3 => github.com/google/martian/v3 v3.1.0
|
||||
|
12
go.sum
12
go.sum
@ -101,8 +101,8 @@ github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5
|
||||
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||
github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE=
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
github.com/containerd/containerd v1.4.9 h1:JIw9mjVw4LsGmnA/Bqg9j9e+XB7soOJufrKUpA6n2Ns=
|
||||
github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.11 h1:QCGOUN+i70jEEL/A6JVIbhy4f4fanzAzSR4kNG7SlcE=
|
||||
github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
@ -136,8 +136,8 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw=
|
||||
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
@ -212,8 +212,8 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZ
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/cadvisor v0.39.2 h1:SzgL5IYoMZEFVA9usi0xCy8SXSVXKQ6aL/rYs/kQjXE=
|
||||
github.com/google/cadvisor v0.39.2/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI=
|
||||
github.com/google/cadvisor v0.43.0 h1:z0ULgYPKZ7L/c7Zjq+ZD6ltklWwYdCSvBMgSjNC/hGo=
|
||||
github.com/google/cadvisor v0.43.0/go.mod h1:+RdMSbc3FVr5NYCD2dOEJy/LI0jYJ/0xJXkzWXEyiFQ=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
|
6
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
6
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
@ -560,7 +560,7 @@ definitions:
|
||||
format: "int64"
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
NanoCPUs:
|
||||
NanoCpus:
|
||||
description: "CPU quota in units of 10<sup>-9</sup> CPUs."
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
@ -5466,7 +5466,7 @@ paths:
|
||||
MemorySwap: 0
|
||||
MemoryReservation: 0
|
||||
KernelMemory: 0
|
||||
NanoCPUs: 500000
|
||||
NanoCpus: 500000
|
||||
CpuPercent: 80
|
||||
CpuShares: 512
|
||||
CpuPeriod: 100000
|
||||
@ -7310,7 +7310,7 @@ paths:
|
||||
|
||||
|
||||
For example, the build arg `FOO=bar` would become `{"FOO":"bar"}` in JSON. This would result in the
|
||||
the query parameter `buildargs={"FOO":"bar"}`. Note that `{"FOO":"bar"}` should be URI component encoded.
|
||||
query parameter `buildargs={"FOO":"bar"}`. Note that `{"FOO":"bar"}` should be URI component encoded.
|
||||
|
||||
|
||||
[Read more about the buildargs instruction.](https://docs.docker.com/engine/reference/builder/#arg)
|
||||
|
2
vendor/github.com/docker/docker/client/client.go
generated
vendored
2
vendor/github.com/docker/docker/client/client.go
generated
vendored
@ -2,7 +2,7 @@
|
||||
Package client is a Go client for the Docker Engine API.
|
||||
|
||||
For more information about the Engine API, see the documentation:
|
||||
https://docs.docker.com/engine/reference/api/
|
||||
https://docs.docker.com/engine/api/
|
||||
|
||||
Usage
|
||||
|
||||
|
2
vendor/github.com/google/cadvisor/client/v2/client.go
generated
vendored
2
vendor/github.com/google/cadvisor/client/v2/client.go
generated
vendored
@ -27,7 +27,7 @@ import (
|
||||
"strings"
|
||||
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/info/v2"
|
||||
v2 "github.com/google/cadvisor/info/v2"
|
||||
)
|
||||
|
||||
// Client represents the base URL for a cAdvisor client.
|
||||
|
2
vendor/github.com/google/cadvisor/collector/collector_manager.go
generated
vendored
2
vendor/github.com/google/cadvisor/collector/collector_manager.go
generated
vendored
@ -19,7 +19,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
const metricLabelPrefix = "io.cadvisor.metric."
|
||||
|
3
vendor/github.com/google/cadvisor/collector/config.go
generated
vendored
3
vendor/github.com/google/cadvisor/collector/config.go
generated
vendored
@ -18,7 +18,8 @@ import (
|
||||
"time"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
2
vendor/github.com/google/cadvisor/collector/fakes.go
generated
vendored
2
vendor/github.com/google/cadvisor/collector/fakes.go
generated
vendored
@ -17,7 +17,7 @@ package collector
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type FakeCollectorManager struct {
|
||||
|
2
vendor/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
2
vendor/github.com/google/cadvisor/collector/generic_collector.go
generated
vendored
@ -25,7 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type GenericCollector struct {
|
||||
|
2
vendor/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
2
vendor/github.com/google/cadvisor/collector/prometheus_collector.go
generated
vendored
@ -28,7 +28,7 @@ import (
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type PrometheusCollector struct {
|
||||
|
2
vendor/github.com/google/cadvisor/collector/types.go
generated
vendored
2
vendor/github.com/google/cadvisor/collector/types.go
generated
vendored
@ -17,7 +17,7 @@ package collector
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
// TODO(vmarmol): Export to a custom metrics type when that is available.
|
||||
|
5
vendor/github.com/google/cadvisor/container/common/fsHandler.go
generated
vendored
5
vendor/github.com/google/cadvisor/container/common/fsHandler.go
generated
vendored
@ -96,7 +96,12 @@ func (fh *realFsHandler) update() error {
|
||||
fh.usage.TotalUsageBytes = rootUsage.Bytes
|
||||
}
|
||||
if fh.extraDir != "" && extraErr == nil {
|
||||
if fh.rootfs != "" {
|
||||
fh.usage.TotalUsageBytes += extraUsage.Bytes
|
||||
} else {
|
||||
// rootfs is empty, totalUsageBytes use extra usage bytes
|
||||
fh.usage.TotalUsageBytes = extraUsage.Bytes
|
||||
}
|
||||
}
|
||||
|
||||
// Combine errors into a single error to return
|
||||
|
28
vendor/github.com/google/cadvisor/container/common/helpers.go
generated
vendored
28
vendor/github.com/google/cadvisor/container/common/helpers.go
generated
vendored
@ -24,14 +24,15 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/utils"
|
||||
"github.com/karrick/godirwalk"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/utils"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
@ -104,7 +105,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
}
|
||||
|
||||
// CPU.
|
||||
cpuRoot, ok := cgroupPaths["cpu"]
|
||||
cpuRoot, ok := getControllerPath(cgroupPaths, "cpu", cgroup2UnifiedMode)
|
||||
if ok {
|
||||
if utils.FileExists(cpuRoot) {
|
||||
if cgroup2UnifiedMode {
|
||||
@ -151,7 +152,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
|
||||
// Cpu Mask.
|
||||
// This will fail for non-unified hierarchies. We'll return the whole machine mask in that case.
|
||||
cpusetRoot, ok := cgroupPaths["cpuset"]
|
||||
cpusetRoot, ok := getControllerPath(cgroupPaths, "cpuset", cgroup2UnifiedMode)
|
||||
if ok {
|
||||
if utils.FileExists(cpusetRoot) {
|
||||
spec.HasCpu = true
|
||||
@ -166,7 +167,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
}
|
||||
|
||||
// Memory
|
||||
memoryRoot, ok := cgroupPaths["memory"]
|
||||
memoryRoot, ok := getControllerPath(cgroupPaths, "memory", cgroup2UnifiedMode)
|
||||
if ok {
|
||||
if cgroup2UnifiedMode {
|
||||
if utils.FileExists(path.Join(memoryRoot, "memory.max")) {
|
||||
@ -194,7 +195,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
}
|
||||
|
||||
// Processes, read it's value from pids path directly
|
||||
pidsRoot, ok := cgroupPaths["pids"]
|
||||
pidsRoot, ok := getControllerPath(cgroupPaths, "pids", cgroup2UnifiedMode)
|
||||
if ok {
|
||||
if utils.FileExists(pidsRoot) {
|
||||
spec.HasProcesses = true
|
||||
@ -216,6 +217,19 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func getControllerPath(cgroupPaths map[string]string, controllerName string, cgroup2UnifiedMode bool) (string, bool) {
|
||||
|
||||
ok := false
|
||||
path := ""
|
||||
|
||||
if cgroup2UnifiedMode {
|
||||
path, ok = cgroupPaths[""]
|
||||
} else {
|
||||
path, ok = cgroupPaths[controllerName]
|
||||
}
|
||||
return path, ok
|
||||
}
|
||||
|
||||
func readString(dirpath string, file string) string {
|
||||
cgroupFile := path.Join(dirpath, file)
|
||||
|
||||
|
6
vendor/github.com/google/cadvisor/container/containerd/client.go
generated
vendored
6
vendor/github.com/google/cadvisor/container/containerd/client.go
generated
vendored
@ -24,10 +24,10 @@ import (
|
||||
containersapi "github.com/containerd/containerd/api/services/containers/v1"
|
||||
tasksapi "github.com/containerd/containerd/api/services/tasks/v1"
|
||||
versionapi "github.com/containerd/containerd/api/services/version/v1"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/pkg/dialer"
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
"github.com/google/cadvisor/container/containerd/containers"
|
||||
"github.com/google/cadvisor/container/containerd/errdefs"
|
||||
"github.com/google/cadvisor/container/containerd/pkg/dialer"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/backoff"
|
||||
)
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
106
vendor/github.com/google/cadvisor/container/containerd/errdefs/errors.go
generated
vendored
Normal file
106
vendor/github.com/google/cadvisor/container/containerd/errdefs/errors.go
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
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 errdefs defines the common errors used throughout containerd
|
||||
// packages.
|
||||
//
|
||||
// Use with errors.Wrap and error.Wrapf to add context to an error.
|
||||
//
|
||||
// To detect an error class, use the IsXXX functions to tell whether an error
|
||||
// is of a certain type.
|
||||
//
|
||||
// The functions ToGRPC and FromGRPC can be used to map server-side and
|
||||
// client-side errors to the correct types.
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Definitions of common error types used throughout containerd. All containerd
|
||||
// errors returned by most packages will map into one of these errors classes.
|
||||
// Packages should return errors of these types when they want to instruct a
|
||||
// client to take a particular action.
|
||||
//
|
||||
// For the most part, we just try to provide local grpc errors. Most conditions
|
||||
// map very well to those defined by grpc.
|
||||
var (
|
||||
ErrUnknown = errors.New("unknown") // used internally to represent a missed mapping.
|
||||
ErrInvalidArgument = errors.New("invalid argument")
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrAlreadyExists = errors.New("already exists")
|
||||
ErrFailedPrecondition = errors.New("failed precondition")
|
||||
ErrUnavailable = errors.New("unavailable")
|
||||
ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented
|
||||
)
|
||||
|
||||
// IsInvalidArgument returns true if the error is due to an invalid argument
|
||||
func IsInvalidArgument(err error) bool {
|
||||
return errors.Is(err, ErrInvalidArgument)
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is due to a missing object
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Is(err, ErrNotFound)
|
||||
}
|
||||
|
||||
// IsAlreadyExists returns true if the error is due to an already existing
|
||||
// metadata item
|
||||
func IsAlreadyExists(err error) bool {
|
||||
return errors.Is(err, ErrAlreadyExists)
|
||||
}
|
||||
|
||||
// IsFailedPrecondition returns true if an operation could not proceed to the
|
||||
// lack of a particular condition
|
||||
func IsFailedPrecondition(err error) bool {
|
||||
return errors.Is(err, ErrFailedPrecondition)
|
||||
}
|
||||
|
||||
// IsUnavailable returns true if the error is due to a resource being unavailable
|
||||
func IsUnavailable(err error) bool {
|
||||
return errors.Is(err, ErrUnavailable)
|
||||
}
|
||||
|
||||
// IsNotImplemented returns true if the error is due to not being implemented
|
||||
func IsNotImplemented(err error) bool {
|
||||
return errors.Is(err, ErrNotImplemented)
|
||||
}
|
||||
|
||||
// IsCanceled returns true if the error is due to `context.Canceled`.
|
||||
func IsCanceled(err error) bool {
|
||||
return errors.Is(err, context.Canceled)
|
||||
}
|
||||
|
||||
// IsDeadlineExceeded returns true if the error is due to
|
||||
// `context.DeadlineExceeded`.
|
||||
func IsDeadlineExceeded(err error) bool {
|
||||
return errors.Is(err, context.DeadlineExceeded)
|
||||
}
|
160
vendor/github.com/google/cadvisor/container/containerd/errdefs/grpc.go
generated
vendored
Normal file
160
vendor/github.com/google/cadvisor/container/containerd/errdefs/grpc.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
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 errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// ToGRPC will attempt to map the backend containerd error into a grpc error,
|
||||
// using the original error message as a description.
|
||||
//
|
||||
// Further information may be extracted from certain errors depending on their
|
||||
// type.
|
||||
//
|
||||
// If the error is unmapped, the original error will be returned to be handled
|
||||
// by the regular grpc error handling stack.
|
||||
func ToGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if isGRPCError(err) {
|
||||
// error has already been mapped to grpc
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case IsInvalidArgument(err):
|
||||
return status.Errorf(codes.InvalidArgument, err.Error())
|
||||
case IsNotFound(err):
|
||||
return status.Errorf(codes.NotFound, err.Error())
|
||||
case IsAlreadyExists(err):
|
||||
return status.Errorf(codes.AlreadyExists, err.Error())
|
||||
case IsFailedPrecondition(err):
|
||||
return status.Errorf(codes.FailedPrecondition, err.Error())
|
||||
case IsUnavailable(err):
|
||||
return status.Errorf(codes.Unavailable, err.Error())
|
||||
case IsNotImplemented(err):
|
||||
return status.Errorf(codes.Unimplemented, err.Error())
|
||||
case IsCanceled(err):
|
||||
return status.Errorf(codes.Canceled, err.Error())
|
||||
case IsDeadlineExceeded(err):
|
||||
return status.Errorf(codes.DeadlineExceeded, err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
|
||||
// and combining it with the target error string.
|
||||
//
|
||||
// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
|
||||
func ToGRPCf(err error, format string, args ...interface{}) error {
|
||||
return ToGRPC(errors.Wrapf(err, format, args...))
|
||||
}
|
||||
|
||||
// FromGRPC returns the underlying error from a grpc service based on the grpc error code
|
||||
func FromGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cls error // divide these into error classes, becomes the cause
|
||||
|
||||
switch code(err) {
|
||||
case codes.InvalidArgument:
|
||||
cls = ErrInvalidArgument
|
||||
case codes.AlreadyExists:
|
||||
cls = ErrAlreadyExists
|
||||
case codes.NotFound:
|
||||
cls = ErrNotFound
|
||||
case codes.Unavailable:
|
||||
cls = ErrUnavailable
|
||||
case codes.FailedPrecondition:
|
||||
cls = ErrFailedPrecondition
|
||||
case codes.Unimplemented:
|
||||
cls = ErrNotImplemented
|
||||
case codes.Canceled:
|
||||
cls = context.Canceled
|
||||
case codes.DeadlineExceeded:
|
||||
cls = context.DeadlineExceeded
|
||||
default:
|
||||
cls = ErrUnknown
|
||||
}
|
||||
|
||||
msg := rebaseMessage(cls, err)
|
||||
if msg != "" {
|
||||
err = errors.Wrap(cls, msg)
|
||||
} else {
|
||||
err = errors.WithStack(cls)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// rebaseMessage removes the repeats for an error at the end of an error
|
||||
// string. This will happen when taking an error over grpc then remapping it.
|
||||
//
|
||||
// Effectively, we just remove the string of cls from the end of err if it
|
||||
// appears there.
|
||||
func rebaseMessage(cls error, err error) string {
|
||||
desc := errDesc(err)
|
||||
clss := cls.Error()
|
||||
if desc == clss {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimSuffix(desc, ": "+clss)
|
||||
}
|
||||
|
||||
func isGRPCError(err error) bool {
|
||||
_, ok := status.FromError(err)
|
||||
return ok
|
||||
}
|
||||
|
||||
func code(err error) codes.Code {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Code()
|
||||
}
|
||||
return codes.Unknown
|
||||
}
|
||||
|
||||
func errDesc(err error) string {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Message()
|
||||
}
|
||||
return err.Error()
|
||||
}
|
18
vendor/github.com/google/cadvisor/container/containerd/factory.go
generated
vendored
18
vendor/github.com/google/cadvisor/container/containerd/factory.go
generated
vendored
@ -34,6 +34,8 @@ import (
|
||||
var ArgContainerdEndpoint = flag.String("containerd", "/run/containerd/containerd.sock", "containerd endpoint")
|
||||
var ArgContainerdNamespace = flag.String("containerd-namespace", "k8s.io", "containerd namespace")
|
||||
|
||||
var containerdEnvMetadataWhiteList = flag.String("containerd_env_metadata_whitelist", "", "DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for containerd containers")
|
||||
|
||||
// The namespace under which containerd aliases are unique.
|
||||
const k8sContainerdNamespace = "containerd"
|
||||
|
||||
@ -46,7 +48,7 @@ type containerdFactory struct {
|
||||
client ContainerdClient
|
||||
version string
|
||||
// Information about the mounted cgroup subsystems.
|
||||
cgroupSubsystems libcontainer.CgroupSubsystems
|
||||
cgroupSubsystems map[string]string
|
||||
// Information about mounted filesystems.
|
||||
fsInfo fs.FsInfo
|
||||
includedMetrics container.MetricSet
|
||||
@ -56,21 +58,27 @@ func (f *containerdFactory) String() string {
|
||||
return k8sContainerdNamespace
|
||||
}
|
||||
|
||||
func (f *containerdFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
func (f *containerdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
client, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
metadataEnvs := []string{}
|
||||
containerdMetadataEnvAllowList := strings.Split(*containerdEnvMetadataWhiteList, ",")
|
||||
|
||||
// prefer using the unified metadataEnvAllowList
|
||||
if len(metadataEnvAllowList) != 0 {
|
||||
containerdMetadataEnvAllowList = metadataEnvAllowList
|
||||
}
|
||||
|
||||
return newContainerdContainerHandler(
|
||||
client,
|
||||
name,
|
||||
f.machineInfoFactory,
|
||||
f.fsInfo,
|
||||
&f.cgroupSubsystems,
|
||||
f.cgroupSubsystems,
|
||||
inHostNamespace,
|
||||
metadataEnvs,
|
||||
containerdMetadataEnvAllowList,
|
||||
f.includedMetrics,
|
||||
)
|
||||
}
|
||||
|
2
vendor/github.com/google/cadvisor/container/containerd/grpc.go
generated
vendored
2
vendor/github.com/google/cadvisor/container/containerd/grpc.go
generated
vendored
@ -16,7 +16,7 @@
|
||||
package containerd
|
||||
|
||||
import (
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/google/cadvisor/container/containerd/namespaces"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
28
vendor/github.com/google/cadvisor/container/containerd/handler.go
generated
vendored
28
vendor/github.com/google/cadvisor/container/containerd/handler.go
generated
vendored
@ -21,15 +21,17 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/google/cadvisor/container/containerd/errdefs"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/common"
|
||||
containerlibcontainer "github.com/google/cadvisor/container/libcontainer"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
type containerdContainerHandler struct {
|
||||
@ -58,13 +60,13 @@ func newContainerdContainerHandler(
|
||||
name string,
|
||||
machineInfoFactory info.MachineInfoFactory,
|
||||
fsInfo fs.FsInfo,
|
||||
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
|
||||
cgroupSubsystems map[string]string,
|
||||
inHostNamespace bool,
|
||||
metadataEnvs []string,
|
||||
metadataEnvAllowList []string,
|
||||
includedMetrics container.MetricSet,
|
||||
) (container.ContainerHandler, error) {
|
||||
// Create the cgroup paths.
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
|
||||
|
||||
// Generate the equivalent cgroup manager for this container.
|
||||
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
|
||||
@ -133,14 +135,22 @@ func newContainerdContainerHandler(
|
||||
}
|
||||
// Add the name and bare ID as aliases of the container.
|
||||
handler.image = cntr.Image
|
||||
|
||||
for _, exposedEnv := range metadataEnvAllowList {
|
||||
if exposedEnv == "" {
|
||||
// if no containerdEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == ""
|
||||
continue
|
||||
}
|
||||
|
||||
for _, envVar := range spec.Process.Env {
|
||||
if envVar != "" {
|
||||
splits := strings.SplitN(envVar, "=", 2)
|
||||
if len(splits) == 2 {
|
||||
if len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {
|
||||
handler.envs[splits[0]] = splits[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handler, nil
|
||||
}
|
||||
@ -207,7 +217,11 @@ func (h *containerdContainerHandler) ListContainers(listType container.ListType)
|
||||
}
|
||||
|
||||
func (h *containerdContainerHandler) GetCgroupPath(resource string) (string, error) {
|
||||
path, ok := h.cgroupPaths[resource]
|
||||
var res string
|
||||
if !cgroups.IsCgroup2UnifiedMode() {
|
||||
res = resource
|
||||
}
|
||||
path, ok := h.cgroupPaths[res]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
|
||||
}
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
@ -27,7 +40,7 @@ package identifiers
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/google/cadvisor/container/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
3
vendor/github.com/google/cadvisor/container/containerd/install/install.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/containerd/install/install.go
generated
vendored
@ -16,9 +16,10 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/containerd"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
@ -20,8 +33,8 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/identifiers"
|
||||
"github.com/google/cadvisor/container/containerd/errdefs"
|
||||
"github.com/google/cadvisor/container/containerd/identifiers"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -1,3 +1,17 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
@ -1,3 +1,16 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
16
vendor/github.com/google/cadvisor/container/crio/factory.go
generated
vendored
16
vendor/github.com/google/cadvisor/container/crio/factory.go
generated
vendored
@ -32,6 +32,9 @@ import (
|
||||
// The namespace under which crio aliases are unique.
|
||||
const CrioNamespace = "crio"
|
||||
|
||||
// The namespace systemd runs components under.
|
||||
const SystemdNamespace = "system-systemd"
|
||||
|
||||
// Regexp that identifies CRI-O cgroups
|
||||
var crioCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
|
||||
|
||||
@ -50,7 +53,7 @@ type crioFactory struct {
|
||||
storageDir string
|
||||
|
||||
// Information about the mounted cgroup subsystems.
|
||||
cgroupSubsystems libcontainer.CgroupSubsystems
|
||||
cgroupSubsystems map[string]string
|
||||
|
||||
// Information about mounted filesystems.
|
||||
fsInfo fs.FsInfo
|
||||
@ -64,13 +67,11 @@ func (f *crioFactory) String() string {
|
||||
return CrioNamespace
|
||||
}
|
||||
|
||||
func (f *crioFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
func (f *crioFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
client, err := Client()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// TODO are there any env vars we need to white list, if so, do it here...
|
||||
metadataEnvs := []string{}
|
||||
handler, err = newCrioContainerHandler(
|
||||
client,
|
||||
name,
|
||||
@ -78,9 +79,9 @@ func (f *crioFactory) NewContainerHandler(name string, inHostNamespace bool) (ha
|
||||
f.fsInfo,
|
||||
f.storageDriver,
|
||||
f.storageDir,
|
||||
&f.cgroupSubsystems,
|
||||
f.cgroupSubsystems,
|
||||
inHostNamespace,
|
||||
metadataEnvs,
|
||||
metadataEnvAllowList,
|
||||
f.includedMetrics,
|
||||
)
|
||||
return
|
||||
@ -116,6 +117,9 @@ func (f *crioFactory) CanHandleAndAccept(name string) (bool, bool, error) {
|
||||
if !strings.HasPrefix(path.Base(name), CrioNamespace) {
|
||||
return false, false, nil
|
||||
}
|
||||
if strings.HasPrefix(path.Base(name), SystemdNamespace) {
|
||||
return true, false, nil
|
||||
}
|
||||
// if the container is not associated with CRI-O, we can't handle it or accept it.
|
||||
if !isContainerName(name) {
|
||||
return false, false, nil
|
||||
|
17
vendor/github.com/google/cadvisor/container/crio/handler.go
generated
vendored
17
vendor/github.com/google/cadvisor/container/crio/handler.go
generated
vendored
@ -21,12 +21,13 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/common"
|
||||
containerlibcontainer "github.com/google/cadvisor/container/libcontainer"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
)
|
||||
|
||||
type crioContainerHandler struct {
|
||||
@ -83,13 +84,13 @@ func newCrioContainerHandler(
|
||||
fsInfo fs.FsInfo,
|
||||
storageDriver storageDriver,
|
||||
storageDir string,
|
||||
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
|
||||
cgroupSubsystems map[string]string,
|
||||
inHostNamespace bool,
|
||||
metadataEnvs []string,
|
||||
metadataEnvAllowList []string,
|
||||
includedMetrics container.MetricSet,
|
||||
) (container.ContainerHandler, error) {
|
||||
// Create the cgroup paths.
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
|
||||
|
||||
// Generate the equivalent cgroup manager for this container.
|
||||
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
|
||||
@ -186,7 +187,7 @@ func newCrioContainerHandler(
|
||||
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, storageLogDir, fsInfo)
|
||||
}
|
||||
// TODO for env vars we wanted to show from container.Config.Env from whitelist
|
||||
//for _, exposedEnv := range metadataEnvs {
|
||||
//for _, exposedEnv := range metadataEnvAllowList {
|
||||
//klog.V(4).Infof("TODO env whitelist: %v", exposedEnv)
|
||||
//}
|
||||
|
||||
@ -327,7 +328,11 @@ func (h *crioContainerHandler) ListContainers(listType container.ListType) ([]in
|
||||
}
|
||||
|
||||
func (h *crioContainerHandler) GetCgroupPath(resource string) (string, error) {
|
||||
path, ok := h.cgroupPaths[resource]
|
||||
var res string
|
||||
if !cgroups.IsCgroup2UnifiedMode() {
|
||||
res = resource
|
||||
}
|
||||
path, ok := h.cgroupPaths[res]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
|
||||
}
|
||||
|
3
vendor/github.com/google/cadvisor/container/crio/install/install.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/crio/install/install.go
generated
vendored
@ -16,9 +16,10 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/crio"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
3
vendor/github.com/google/cadvisor/container/crio/plugin.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/crio/plugin.go
generated
vendored
@ -15,11 +15,12 @@
|
||||
package crio
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
|
2
vendor/github.com/google/cadvisor/container/docker/docker.go
generated
vendored
2
vendor/github.com/google/cadvisor/container/docker/docker.go
generated
vendored
@ -25,7 +25,7 @@ import (
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/machine"
|
||||
)
|
||||
|
||||
|
20
vendor/github.com/google/cadvisor/container/docker/factory.go
generated
vendored
20
vendor/github.com/google/cadvisor/container/docker/factory.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/blang/semver"
|
||||
dockertypes "github.com/docker/docker/api/types"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
dockerutil "github.com/google/cadvisor/container/docker/utils"
|
||||
"github.com/google/cadvisor/container/libcontainer"
|
||||
@ -47,6 +48,8 @@ var ArgDockerCert = flag.String("docker-tls-cert", "cert.pem", "path to client c
|
||||
var ArgDockerKey = flag.String("docker-tls-key", "key.pem", "path to private key")
|
||||
var ArgDockerCA = flag.String("docker-tls-ca", "ca.pem", "path to trusted CA")
|
||||
|
||||
var dockerEnvMetadataWhiteList = flag.String("docker_env_metadata_whitelist", "", "DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for docker containers")
|
||||
|
||||
// The namespace under which Docker aliases are unique.
|
||||
const DockerNamespace = "docker"
|
||||
|
||||
@ -60,8 +63,6 @@ const rootDirRetryPeriod time.Duration = 1000 * time.Millisecond
|
||||
// --cgroup-parent have another prefix than 'docker'
|
||||
var dockerCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
|
||||
|
||||
var dockerEnvWhitelist = flag.String("docker_env_metadata_whitelist", "", "a comma-separated list of environment variable keys matched with specified prefix that needs to be collected for docker containers")
|
||||
|
||||
var (
|
||||
// Basepath to all container specific information that libcontainer stores.
|
||||
dockerRootDir string
|
||||
@ -115,7 +116,7 @@ type dockerFactory struct {
|
||||
client *docker.Client
|
||||
|
||||
// Information about the mounted cgroup subsystems.
|
||||
cgroupSubsystems libcontainer.CgroupSubsystems
|
||||
cgroupSubsystems map[string]string
|
||||
|
||||
// Information about mounted filesystems.
|
||||
fsInfo fs.FsInfo
|
||||
@ -136,13 +137,18 @@ func (f *dockerFactory) String() string {
|
||||
return DockerNamespace
|
||||
}
|
||||
|
||||
func (f *dockerFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
func (f *dockerFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
|
||||
client, err := Client()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
metadataEnvs := strings.Split(*dockerEnvWhitelist, ",")
|
||||
dockerMetadataEnvAllowList := strings.Split(*dockerEnvMetadataWhiteList, ",")
|
||||
|
||||
// prefer using the unified metadataEnvAllowList
|
||||
if len(metadataEnvAllowList) != 0 {
|
||||
dockerMetadataEnvAllowList = metadataEnvAllowList
|
||||
}
|
||||
|
||||
handler, err = newDockerContainerHandler(
|
||||
client,
|
||||
@ -151,9 +157,9 @@ func (f *dockerFactory) NewContainerHandler(name string, inHostNamespace bool) (
|
||||
f.fsInfo,
|
||||
f.storageDriver,
|
||||
f.storageDir,
|
||||
&f.cgroupSubsystems,
|
||||
f.cgroupSubsystems,
|
||||
inHostNamespace,
|
||||
metadataEnvs,
|
||||
dockerMetadataEnvAllowList,
|
||||
f.dockerVersion,
|
||||
f.includedMetrics,
|
||||
f.thinPoolName,
|
||||
|
17
vendor/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
17
vendor/github.com/google/cadvisor/container/docker/handler.go
generated
vendored
@ -31,6 +31,7 @@ import (
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/zfs"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
dockercontainer "github.com/docker/docker/api/types/container"
|
||||
docker "github.com/docker/docker/client"
|
||||
@ -121,9 +122,9 @@ func newDockerContainerHandler(
|
||||
fsInfo fs.FsInfo,
|
||||
storageDriver storageDriver,
|
||||
storageDir string,
|
||||
cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
|
||||
cgroupSubsystems map[string]string,
|
||||
inHostNamespace bool,
|
||||
metadataEnvs []string,
|
||||
metadataEnvAllowList []string,
|
||||
dockerVersion []int,
|
||||
includedMetrics container.MetricSet,
|
||||
thinPoolName string,
|
||||
@ -131,7 +132,7 @@ func newDockerContainerHandler(
|
||||
zfsWatcher *zfs.ZfsWatcher,
|
||||
) (container.ContainerHandler, error) {
|
||||
// Create the cgroup paths.
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
|
||||
|
||||
// Generate the equivalent cgroup manager for this container.
|
||||
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
|
||||
@ -249,9 +250,9 @@ func newDockerContainerHandler(
|
||||
}
|
||||
|
||||
// split env vars to get metadata map.
|
||||
for _, exposedEnv := range metadataEnvs {
|
||||
for _, exposedEnv := range metadataEnvAllowList {
|
||||
if exposedEnv == "" {
|
||||
// if no dockerEnvWhitelist provided, len(metadataEnvs) == 1, metadataEnvs[0] == ""
|
||||
// if no dockerEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == ""
|
||||
continue
|
||||
}
|
||||
|
||||
@ -484,7 +485,11 @@ func (h *dockerContainerHandler) ListContainers(listType container.ListType) ([]
|
||||
}
|
||||
|
||||
func (h *dockerContainerHandler) GetCgroupPath(resource string) (string, error) {
|
||||
path, ok := h.cgroupPaths[resource]
|
||||
var res string
|
||||
if !cgroups.IsCgroup2UnifiedMode() {
|
||||
res = resource
|
||||
}
|
||||
path, ok := h.cgroupPaths[res]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
|
||||
}
|
||||
|
3
vendor/github.com/google/cadvisor/container/docker/install/install.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/docker/install/install.go
generated
vendored
@ -16,9 +16,10 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
5
vendor/github.com/google/cadvisor/container/docker/plugin.go
generated
vendored
5
vendor/github.com/google/cadvisor/container/docker/plugin.go
generated
vendored
@ -17,12 +17,13 @@ package docker
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const dockerClientTimeout = 10 * time.Second
|
||||
|
77
vendor/github.com/google/cadvisor/container/factory.go
generated
vendored
77
vendor/github.com/google/cadvisor/container/factory.go
generated
vendored
@ -16,6 +16,8 @@ package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/google/cadvisor/fs"
|
||||
@ -27,7 +29,7 @@ import (
|
||||
|
||||
type ContainerHandlerFactory interface {
|
||||
// Create a new ContainerHandler using this factory. CanHandleAndAccept() must have returned true.
|
||||
NewContainerHandler(name string, inHostNamespace bool) (c ContainerHandler, err error)
|
||||
NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (c ContainerHandler, err error)
|
||||
|
||||
// Returns whether this factory can handle and accept the specified container.
|
||||
CanHandleAndAccept(name string) (handle bool, accept bool, err error)
|
||||
@ -64,6 +66,7 @@ const (
|
||||
CPUTopologyMetrics MetricKind = "cpu_topology"
|
||||
ResctrlMetrics MetricKind = "resctrl"
|
||||
CPUSetMetrics MetricKind = "cpuset"
|
||||
OOMMetrics MetricKind = "oom_event"
|
||||
)
|
||||
|
||||
// AllMetrics represents all kinds of metrics that cAdvisor supported.
|
||||
@ -89,6 +92,7 @@ var AllMetrics = MetricSet{
|
||||
CPUTopologyMetrics: struct{}{},
|
||||
ResctrlMetrics: struct{}{},
|
||||
CPUSetMetrics: struct{}{},
|
||||
OOMMetrics: struct{}{},
|
||||
}
|
||||
|
||||
func (mk MetricKind) String() string {
|
||||
@ -102,15 +106,50 @@ func (ms MetricSet) Has(mk MetricKind) bool {
|
||||
return exists
|
||||
}
|
||||
|
||||
func (ms MetricSet) Add(mk MetricKind) {
|
||||
func (ms MetricSet) add(mk MetricKind) {
|
||||
ms[mk] = struct{}{}
|
||||
}
|
||||
|
||||
func (ms MetricSet) String() string {
|
||||
values := make([]string, 0, len(ms))
|
||||
for metric := range ms {
|
||||
values = append(values, string(metric))
|
||||
}
|
||||
sort.Strings(values)
|
||||
return strings.Join(values, ",")
|
||||
}
|
||||
|
||||
// Not thread-safe, exported only for https://pkg.go.dev/flag#Value
|
||||
func (ms *MetricSet) Set(value string) error {
|
||||
*ms = MetricSet{}
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
for _, metric := range strings.Split(value, ",") {
|
||||
if AllMetrics.Has(MetricKind(metric)) {
|
||||
(*ms).add(MetricKind(metric))
|
||||
} else {
|
||||
return fmt.Errorf("unsupported metric %q specified", metric)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms MetricSet) Difference(ms1 MetricSet) MetricSet {
|
||||
result := MetricSet{}
|
||||
for kind := range ms {
|
||||
if !ms1.Has(kind) {
|
||||
result.Add(kind)
|
||||
result.add(kind)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (ms MetricSet) Append(ms1 MetricSet) MetricSet {
|
||||
result := ms
|
||||
for kind := range ms1 {
|
||||
if !ms.Has(kind) {
|
||||
result.add(kind)
|
||||
}
|
||||
}
|
||||
return result
|
||||
@ -198,12 +237,15 @@ func HasFactories() bool {
|
||||
}
|
||||
|
||||
// Create a new ContainerHandler for the specified container.
|
||||
func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, inHostNamespace bool) (ContainerHandler, bool, error) {
|
||||
func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, metadataEnvAllowList []string, inHostNamespace bool) (ContainerHandler, bool, error) {
|
||||
factoriesLock.RLock()
|
||||
defer factoriesLock.RUnlock()
|
||||
|
||||
// Create the ContainerHandler with the first factory that supports it.
|
||||
for _, factory := range factories[watchType] {
|
||||
// Note that since RawContainerHandler can support a wide range of paths,
|
||||
// it's evaluated last just to make sure if any other ContainerHandler
|
||||
// can support it.
|
||||
for _, factory := range GetReorderedFactoryList(watchType) {
|
||||
canHandle, canAccept, err := factory.CanHandleAndAccept(name)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Error trying to work out if we can handle %s: %v", name, err)
|
||||
@ -214,7 +256,7 @@ func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, in
|
||||
return nil, false, nil
|
||||
}
|
||||
klog.V(3).Infof("Using factory %q for container %q", factory, name)
|
||||
handle, err := factory.NewContainerHandler(name, inHostNamespace)
|
||||
handle, err := factory.NewContainerHandler(name, metadataEnvAllowList, inHostNamespace)
|
||||
return handle, canAccept, err
|
||||
}
|
||||
klog.V(4).Infof("Factory %q was unable to handle container %q", factory, name)
|
||||
@ -246,3 +288,26 @@ func DebugInfo() map[string][]string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GetReorderedFactoryList returns the list of ContainerHandlerFactory where the
|
||||
// RawContainerHandler is always the last element.
|
||||
func GetReorderedFactoryList(watchType watcher.ContainerWatchSource) []ContainerHandlerFactory {
|
||||
ContainerHandlerFactoryList := make([]ContainerHandlerFactory, 0, len(factories))
|
||||
|
||||
var rawFactory ContainerHandlerFactory
|
||||
for _, v := range factories[watchType] {
|
||||
if v != nil {
|
||||
if v.String() == "raw" {
|
||||
rawFactory = v
|
||||
continue
|
||||
}
|
||||
ContainerHandlerFactoryList = append(ContainerHandlerFactoryList, v)
|
||||
}
|
||||
}
|
||||
|
||||
if rawFactory != nil {
|
||||
ContainerHandlerFactoryList = append(ContainerHandlerFactoryList, rawFactory)
|
||||
}
|
||||
|
||||
return ContainerHandlerFactoryList
|
||||
}
|
||||
|
64
vendor/github.com/google/cadvisor/container/libcontainer/handler.go
generated
vendored
64
vendor/github.com/google/cadvisor/container/libcontainer/handler.go
generated
vendored
@ -54,7 +54,10 @@ type Handler struct {
|
||||
rootFs string
|
||||
pid int
|
||||
includedMetrics container.MetricSet
|
||||
// pidMetricsCache holds CPU scheduler stats for existing processes (map key is PID) between calls to schedulerStatsFromProcs.
|
||||
pidMetricsCache map[int]*info.CpuSchedstat
|
||||
// pidMetricsSaved holds accumulated CPU scheduler stats for processes that no longer exist.
|
||||
pidMetricsSaved info.CpuSchedstat
|
||||
cycles uint64
|
||||
}
|
||||
|
||||
@ -93,16 +96,11 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
|
||||
stats := newContainerStats(libcontainerStats, h.includedMetrics)
|
||||
|
||||
if h.includedMetrics.Has(container.ProcessSchedulerMetrics) {
|
||||
pids, err := h.cgroupManager.GetAllPids()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Could not get PIDs for container %d: %v", h.pid, err)
|
||||
} else {
|
||||
stats.Cpu.Schedstat, err = schedulerStatsFromProcs(h.rootFs, pids, h.pidMetricsCache)
|
||||
stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Unable to get Process Scheduler Stats: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if h.includedMetrics.Has(container.ReferencedMemoryMetrics) {
|
||||
h.cycles++
|
||||
@ -314,9 +312,14 @@ func processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info.
|
||||
return processStats, nil
|
||||
}
|
||||
|
||||
func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]*info.CpuSchedstat) (info.CpuSchedstat, error) {
|
||||
func (h *Handler) schedulerStatsFromProcs() (info.CpuSchedstat, error) {
|
||||
pids, err := h.cgroupManager.GetAllPids()
|
||||
if err != nil {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("Could not get PIDs for container %d: %w", h.pid, err)
|
||||
}
|
||||
alivePids := make(map[int]struct{}, len(pids))
|
||||
for _, pid := range pids {
|
||||
f, err := os.Open(path.Join(rootFs, "proc", strconv.Itoa(pid), "schedstat"))
|
||||
f, err := os.Open(path.Join(h.rootFs, "proc", strconv.Itoa(pid), "schedstat"))
|
||||
if err != nil {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("couldn't open scheduler statistics for process %d: %v", pid, err)
|
||||
}
|
||||
@ -325,14 +328,15 @@ func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]
|
||||
if err != nil {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("couldn't read scheduler statistics for process %d: %v", pid, err)
|
||||
}
|
||||
alivePids[pid] = struct{}{}
|
||||
rawMetrics := bytes.Split(bytes.TrimRight(contents, "\n"), []byte(" "))
|
||||
if len(rawMetrics) != 3 {
|
||||
return info.CpuSchedstat{}, fmt.Errorf("unexpected number of metrics in schedstat file for process %d", pid)
|
||||
}
|
||||
cacheEntry, ok := pidMetricsCache[pid]
|
||||
cacheEntry, ok := h.pidMetricsCache[pid]
|
||||
if !ok {
|
||||
cacheEntry = &info.CpuSchedstat{}
|
||||
pidMetricsCache[pid] = cacheEntry
|
||||
h.pidMetricsCache[pid] = cacheEntry
|
||||
}
|
||||
for i, rawMetric := range rawMetrics {
|
||||
metric, err := strconv.ParseUint(string(rawMetric), 10, 64)
|
||||
@ -349,11 +353,20 @@ func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]
|
||||
}
|
||||
}
|
||||
}
|
||||
schedstats := info.CpuSchedstat{}
|
||||
for _, v := range pidMetricsCache {
|
||||
schedstats := h.pidMetricsSaved // copy
|
||||
for p, v := range h.pidMetricsCache {
|
||||
schedstats.RunPeriods += v.RunPeriods
|
||||
schedstats.RunqueueTime += v.RunqueueTime
|
||||
schedstats.RunTime += v.RunTime
|
||||
if _, alive := alivePids[p]; !alive {
|
||||
// PID p is gone: accumulate its stats ...
|
||||
h.pidMetricsSaved.RunPeriods += v.RunPeriods
|
||||
h.pidMetricsSaved.RunqueueTime += v.RunqueueTime
|
||||
h.pidMetricsSaved.RunTime += v.RunTime
|
||||
// ... and remove its cache entry, to prevent
|
||||
// pidMetricsCache from growing.
|
||||
delete(h.pidMetricsCache, p)
|
||||
}
|
||||
}
|
||||
return schedstats, nil
|
||||
}
|
||||
@ -426,7 +439,7 @@ func clearReferencedBytes(pids []int, cycles uint64, resetInterval uint64) error
|
||||
if cycles%resetInterval == 0 {
|
||||
for _, pid := range pids {
|
||||
clearRefsFilePath := fmt.Sprintf(clearRefsFilePathPattern, pid)
|
||||
clerRefsFile, err := os.OpenFile(clearRefsFilePath, os.O_WRONLY, 0644)
|
||||
clerRefsFile, err := os.OpenFile(clearRefsFilePath, os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
// clear_refs file may not exist for all PIDs
|
||||
continue
|
||||
@ -455,9 +468,7 @@ func networkStatsFromProc(rootFs string, pid int) ([]info.InterfaceStats, error)
|
||||
return ifaceStats, nil
|
||||
}
|
||||
|
||||
var (
|
||||
ignoredDevicePrefixes = []string{"lo", "veth", "docker"}
|
||||
)
|
||||
var ignoredDevicePrefixes = []string{"lo", "veth", "docker"}
|
||||
|
||||
func isIgnoredDevice(ifName string) bool {
|
||||
for _, prefix := range ignoredDevicePrefixes {
|
||||
@ -615,11 +626,9 @@ func scanAdvancedTCPStats(advancedStats *info.TcpAdvancedStat, advancedTCPStatsF
|
||||
}
|
||||
|
||||
return scanner.Err()
|
||||
|
||||
}
|
||||
|
||||
func scanTCPStats(tcpStatsFile string) (info.TcpStat, error) {
|
||||
|
||||
var stats info.TcpStat
|
||||
|
||||
data, err := ioutil.ReadFile(tcpStatsFile)
|
||||
@ -779,14 +788,14 @@ func setCPUStats(s *cgroups.Stats, ret *info.ContainerStats, withPerCPU bool) {
|
||||
}
|
||||
|
||||
func setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) {
|
||||
ret.DiskIo.IoServiceBytes = DiskStatsCopy(s.BlkioStats.IoServiceBytesRecursive)
|
||||
ret.DiskIo.IoServiced = DiskStatsCopy(s.BlkioStats.IoServicedRecursive)
|
||||
ret.DiskIo.IoQueued = DiskStatsCopy(s.BlkioStats.IoQueuedRecursive)
|
||||
ret.DiskIo.Sectors = DiskStatsCopy(s.BlkioStats.SectorsRecursive)
|
||||
ret.DiskIo.IoServiceTime = DiskStatsCopy(s.BlkioStats.IoServiceTimeRecursive)
|
||||
ret.DiskIo.IoWaitTime = DiskStatsCopy(s.BlkioStats.IoWaitTimeRecursive)
|
||||
ret.DiskIo.IoMerged = DiskStatsCopy(s.BlkioStats.IoMergedRecursive)
|
||||
ret.DiskIo.IoTime = DiskStatsCopy(s.BlkioStats.IoTimeRecursive)
|
||||
ret.DiskIo.IoServiceBytes = diskStatsCopy(s.BlkioStats.IoServiceBytesRecursive)
|
||||
ret.DiskIo.IoServiced = diskStatsCopy(s.BlkioStats.IoServicedRecursive)
|
||||
ret.DiskIo.IoQueued = diskStatsCopy(s.BlkioStats.IoQueuedRecursive)
|
||||
ret.DiskIo.Sectors = diskStatsCopy(s.BlkioStats.SectorsRecursive)
|
||||
ret.DiskIo.IoServiceTime = diskStatsCopy(s.BlkioStats.IoServiceTimeRecursive)
|
||||
ret.DiskIo.IoWaitTime = diskStatsCopy(s.BlkioStats.IoWaitTimeRecursive)
|
||||
ret.DiskIo.IoMerged = diskStatsCopy(s.BlkioStats.IoMergedRecursive)
|
||||
ret.DiskIo.IoTime = diskStatsCopy(s.BlkioStats.IoTimeRecursive)
|
||||
}
|
||||
|
||||
func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
|
||||
@ -797,7 +806,7 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
ret.Memory.Cache = s.MemoryStats.Stats["file"]
|
||||
ret.Memory.RSS = s.MemoryStats.Stats["anon"]
|
||||
ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage
|
||||
ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage - s.MemoryStats.Usage.Usage
|
||||
ret.Memory.MappedFile = s.MemoryStats.Stats["file_mapped"]
|
||||
} else if s.MemoryStats.UseHierarchy {
|
||||
ret.Memory.Cache = s.MemoryStats.Stats["total_cache"]
|
||||
@ -896,7 +905,6 @@ func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) {
|
||||
ret.Processes.ThreadsCurrent = s.PidsStats.Current
|
||||
ret.Processes.ThreadsMax = s.PidsStats.Limit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats {
|
||||
|
131
vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
generated
vendored
131
vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
generated
vendored
@ -19,71 +19,49 @@ import (
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
|
||||
fs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||
fs2 "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
|
||||
configs "github.com/opencontainers/runc/libcontainer/configs"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type CgroupSubsystems struct {
|
||||
// Cgroup subsystem mounts.
|
||||
// e.g.: "/sys/fs/cgroup/cpu" -> ["cpu", "cpuacct"]
|
||||
Mounts []cgroups.Mount
|
||||
|
||||
// Cgroup subsystem to their mount location.
|
||||
// e.g.: "cpu" -> "/sys/fs/cgroup/cpu"
|
||||
MountPoints map[string]string
|
||||
// GetCgroupSubsystems returns information about the cgroup subsystems that are
|
||||
// of interest as a map of cgroup controllers to their mount points.
|
||||
// For example, "cpu" -> "/sys/fs/cgroup/cpu".
|
||||
//
|
||||
// The incudeMetrics arguments specifies which metrics are requested,
|
||||
// and is used to filter out some cgroups and their mounts. If nil,
|
||||
// all supported cgroup subsystems are included.
|
||||
//
|
||||
// For cgroup v2, includedMetrics argument is unused, the only map key is ""
|
||||
// (empty string), and the value is the unified cgroup mount point.
|
||||
func GetCgroupSubsystems(includedMetrics container.MetricSet) (map[string]string, error) {
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
return map[string]string{"": fs2.UnifiedMountpoint}, nil
|
||||
}
|
||||
|
||||
// Get information about the cgroup subsystems those we want
|
||||
func GetCgroupSubsystems(includedMetrics container.MetricSet) (CgroupSubsystems, error) {
|
||||
// Get all cgroup mounts.
|
||||
allCgroups, err := cgroups.GetCgroupMounts(true)
|
||||
if err != nil {
|
||||
return CgroupSubsystems{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disableCgroups := map[string]struct{}{}
|
||||
|
||||
//currently we only support disable blkio subsystem
|
||||
if !includedMetrics.Has(container.DiskIOMetrics) {
|
||||
disableCgroups["blkio"] = struct{}{}
|
||||
disableCgroups["io"] = struct{}{}
|
||||
}
|
||||
return getCgroupSubsystemsHelper(allCgroups, disableCgroups)
|
||||
return getCgroupSubsystemsHelper(allCgroups, includedMetrics)
|
||||
}
|
||||
|
||||
// Get information about all the cgroup subsystems.
|
||||
func GetAllCgroupSubsystems() (CgroupSubsystems, error) {
|
||||
// Get all cgroup mounts.
|
||||
allCgroups, err := cgroups.GetCgroupMounts(true)
|
||||
if err != nil {
|
||||
return CgroupSubsystems{}, err
|
||||
}
|
||||
|
||||
emptyDisableCgroups := map[string]struct{}{}
|
||||
return getCgroupSubsystemsHelper(allCgroups, emptyDisableCgroups)
|
||||
}
|
||||
|
||||
func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[string]struct{}) (CgroupSubsystems, error) {
|
||||
func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, includedMetrics container.MetricSet) (map[string]string, error) {
|
||||
if len(allCgroups) == 0 {
|
||||
return CgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts")
|
||||
return nil, fmt.Errorf("failed to find cgroup mounts")
|
||||
}
|
||||
|
||||
// Trim the mounts to only the subsystems we care about.
|
||||
supportedCgroups := make([]cgroups.Mount, 0, len(allCgroups))
|
||||
recordedMountpoints := make(map[string]struct{}, len(allCgroups))
|
||||
mountPoints := make(map[string]string, len(allCgroups))
|
||||
for _, mount := range allCgroups {
|
||||
for _, subsystem := range mount.Subsystems {
|
||||
if _, exists := disableCgroups[subsystem]; exists {
|
||||
continue
|
||||
}
|
||||
if _, ok := supportedSubsystems[subsystem]; !ok {
|
||||
// Unsupported subsystem
|
||||
if !needSubsys(subsystem, includedMetrics) {
|
||||
continue
|
||||
}
|
||||
if _, ok := mountPoints[subsystem]; ok {
|
||||
@ -91,36 +69,44 @@ func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[st
|
||||
klog.V(5).Infof("skipping %s, already using mount at %s", mount.Mountpoint, mountPoints[subsystem])
|
||||
continue
|
||||
}
|
||||
if _, ok := recordedMountpoints[mount.Mountpoint]; !ok {
|
||||
// avoid appending the same mount twice in e.g. `cpu,cpuacct` case
|
||||
supportedCgroups = append(supportedCgroups, mount)
|
||||
recordedMountpoints[mount.Mountpoint] = struct{}{}
|
||||
}
|
||||
mountPoints[subsystem] = mount.Mountpoint
|
||||
}
|
||||
}
|
||||
|
||||
return CgroupSubsystems{
|
||||
Mounts: supportedCgroups,
|
||||
MountPoints: mountPoints,
|
||||
}, nil
|
||||
return mountPoints, nil
|
||||
}
|
||||
|
||||
// Cgroup subsystems we support listing (should be the minimal set we need stats from).
|
||||
var supportedSubsystems map[string]struct{} = map[string]struct{}{
|
||||
"cpu": {},
|
||||
"cpuacct": {},
|
||||
"memory": {},
|
||||
"hugetlb": {},
|
||||
"pids": {},
|
||||
"cpuset": {},
|
||||
"blkio": {},
|
||||
"io": {},
|
||||
"devices": {},
|
||||
"perf_event": {},
|
||||
// A map of cgroup subsystems we support listing (should be the minimal set
|
||||
// we need stats from) to a respective MetricKind.
|
||||
var supportedSubsystems = map[string]container.MetricKind{
|
||||
"cpu": container.CpuUsageMetrics,
|
||||
"cpuacct": container.CpuUsageMetrics,
|
||||
"memory": container.MemoryUsageMetrics,
|
||||
"hugetlb": container.HugetlbUsageMetrics,
|
||||
"pids": container.ProcessMetrics,
|
||||
"cpuset": container.CPUSetMetrics,
|
||||
"blkio": container.DiskIOMetrics,
|
||||
"io": container.DiskIOMetrics,
|
||||
"devices": "",
|
||||
"perf_event": container.PerfMetrics,
|
||||
}
|
||||
|
||||
func DiskStatsCopy0(major, minor uint64) *info.PerDiskStats {
|
||||
// Check if this cgroup subsystem/controller is of use.
|
||||
func needSubsys(name string, metrics container.MetricSet) bool {
|
||||
// Check if supported.
|
||||
metric, supported := supportedSubsystems[name]
|
||||
if !supported {
|
||||
return false
|
||||
}
|
||||
// Check if needed.
|
||||
if metrics == nil || metric == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return metrics.Has(metric)
|
||||
}
|
||||
|
||||
func diskStatsCopy0(major, minor uint64) *info.PerDiskStats {
|
||||
disk := info.PerDiskStats{
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
@ -129,12 +115,12 @@ func DiskStatsCopy0(major, minor uint64) *info.PerDiskStats {
|
||||
return &disk
|
||||
}
|
||||
|
||||
type DiskKey struct {
|
||||
type diskKey struct {
|
||||
Major uint64
|
||||
Minor uint64
|
||||
}
|
||||
|
||||
func DiskStatsCopy1(diskStat map[DiskKey]*info.PerDiskStats) []info.PerDiskStats {
|
||||
func diskStatsCopy1(diskStat map[diskKey]*info.PerDiskStats) []info.PerDiskStats {
|
||||
i := 0
|
||||
stat := make([]info.PerDiskStats, len(diskStat))
|
||||
for _, disk := range diskStat {
|
||||
@ -144,21 +130,21 @@ func DiskStatsCopy1(diskStat map[DiskKey]*info.PerDiskStats) []info.PerDiskStats
|
||||
return stat
|
||||
}
|
||||
|
||||
func DiskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) {
|
||||
func diskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) {
|
||||
if len(blkioStats) == 0 {
|
||||
return
|
||||
}
|
||||
diskStat := make(map[DiskKey]*info.PerDiskStats)
|
||||
diskStat := make(map[diskKey]*info.PerDiskStats)
|
||||
for i := range blkioStats {
|
||||
major := blkioStats[i].Major
|
||||
minor := blkioStats[i].Minor
|
||||
key := DiskKey{
|
||||
key := diskKey{
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
}
|
||||
diskp, ok := diskStat[key]
|
||||
if !ok {
|
||||
diskp = DiskStatsCopy0(major, minor)
|
||||
diskp = diskStatsCopy0(major, minor)
|
||||
diskStat[key] = diskp
|
||||
}
|
||||
op := blkioStats[i].Op
|
||||
@ -167,12 +153,12 @@ func DiskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStat
|
||||
}
|
||||
diskp.Stats[op] = blkioStats[i].Value
|
||||
}
|
||||
return DiskStatsCopy1(diskStat)
|
||||
return diskStatsCopy1(diskStat)
|
||||
}
|
||||
|
||||
func NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, error) {
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
path := paths["cpu"]
|
||||
path := paths[""]
|
||||
return fs2.NewManager(nil, path, false)
|
||||
}
|
||||
|
||||
@ -180,5 +166,4 @@ func NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, er
|
||||
Name: name,
|
||||
}
|
||||
return fs.NewManager(&config, paths, false), nil
|
||||
|
||||
}
|
||||
|
16
vendor/github.com/google/cadvisor/container/raw/factory.go
generated
vendored
16
vendor/github.com/google/cadvisor/container/raw/factory.go
generated
vendored
@ -29,15 +29,17 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var dockerOnly = flag.Bool("docker_only", false, "Only report docker containers in addition to root stats")
|
||||
var disableRootCgroupStats = flag.Bool("disable_root_cgroup_stats", false, "Disable collecting root Cgroup stats")
|
||||
var (
|
||||
DockerOnly = flag.Bool("docker_only", false, "Only report docker containers in addition to root stats")
|
||||
disableRootCgroupStats = flag.Bool("disable_root_cgroup_stats", false, "Disable collecting root Cgroup stats")
|
||||
)
|
||||
|
||||
type rawFactory struct {
|
||||
// Factory for machine information.
|
||||
machineInfoFactory info.MachineInfoFactory
|
||||
|
||||
// Information about the cgroup subsystems.
|
||||
cgroupSubsystems *libcontainer.CgroupSubsystems
|
||||
cgroupSubsystems map[string]string
|
||||
|
||||
// Information about mounted filesystems.
|
||||
fsInfo fs.FsInfo
|
||||
@ -56,7 +58,7 @@ func (f *rawFactory) String() string {
|
||||
return "raw"
|
||||
}
|
||||
|
||||
func (f *rawFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
|
||||
func (f *rawFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {
|
||||
rootFs := "/"
|
||||
if !inHostNamespace {
|
||||
rootFs = "/rootfs"
|
||||
@ -69,7 +71,7 @@ func (f *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) {
|
||||
if name == "/" {
|
||||
return true, true, nil
|
||||
}
|
||||
if *dockerOnly && f.rawPrefixWhiteList[0] == "" {
|
||||
if *DockerOnly && f.rawPrefixWhiteList[0] == "" {
|
||||
return true, false, nil
|
||||
}
|
||||
for _, prefix := range f.rawPrefixWhiteList {
|
||||
@ -89,7 +91,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
}
|
||||
if len(cgroupSubsystems.Mounts) == 0 {
|
||||
if len(cgroupSubsystems) == 0 {
|
||||
return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
|
||||
}
|
||||
|
||||
@ -102,7 +104,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl
|
||||
factory := &rawFactory{
|
||||
machineInfoFactory: machineInfoFactory,
|
||||
fsInfo: fsInfo,
|
||||
cgroupSubsystems: &cgroupSubsystems,
|
||||
cgroupSubsystems: cgroupSubsystems,
|
||||
watcher: watcher,
|
||||
includedMetrics: includedMetrics,
|
||||
rawPrefixWhiteList: rawPrefixWhiteList,
|
||||
|
11
vendor/github.com/google/cadvisor/container/raw/handler.go
generated
vendored
11
vendor/github.com/google/cadvisor/container/raw/handler.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/machine"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -48,13 +49,13 @@ func isRootCgroup(name string) bool {
|
||||
return name == "/"
|
||||
}
|
||||
|
||||
func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
|
||||
func newRawContainerHandler(name string, cgroupSubsystems map[string]string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
|
||||
cHints, err := common.GetContainerHintsFromFile(*common.ArgContainerHints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
|
||||
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
|
||||
|
||||
cgroupManager, err := libcontainer.NewCgroupManager(name, cgroupPaths)
|
||||
if err != nil {
|
||||
@ -244,7 +245,11 @@ func (h *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||
}
|
||||
|
||||
func (h *rawContainerHandler) GetCgroupPath(resource string) (string, error) {
|
||||
path, ok := h.cgroupPaths[resource]
|
||||
var res string
|
||||
if !cgroups.IsCgroup2UnifiedMode() {
|
||||
res = resource
|
||||
}
|
||||
path, ok := h.cgroupPaths[res]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.name)
|
||||
}
|
||||
|
16
vendor/github.com/google/cadvisor/container/raw/watcher.go
generated
vendored
16
vendor/github.com/google/cadvisor/container/raw/watcher.go
generated
vendored
@ -23,10 +23,11 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
inotify "k8s.io/utils/inotify"
|
||||
|
||||
"github.com/google/cadvisor/container/common"
|
||||
"github.com/google/cadvisor/container/libcontainer"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
inotify "k8s.io/utils/inotify"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -35,8 +36,6 @@ type rawContainerWatcher struct {
|
||||
// Absolute path to the root of the cgroup hierarchies
|
||||
cgroupPaths map[string]string
|
||||
|
||||
cgroupSubsystems *libcontainer.CgroupSubsystems
|
||||
|
||||
// Inotify event watcher.
|
||||
watcher *common.InotifyWatcher
|
||||
|
||||
@ -45,11 +44,11 @@ type rawContainerWatcher struct {
|
||||
}
|
||||
|
||||
func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
|
||||
cgroupSubsystems, err := libcontainer.GetAllCgroupSubsystems()
|
||||
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
|
||||
}
|
||||
if len(cgroupSubsystems.Mounts) == 0 {
|
||||
if len(cgroupSubsystems) == 0 {
|
||||
return nil, fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
|
||||
}
|
||||
|
||||
@ -59,8 +58,7 @@ func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
|
||||
}
|
||||
|
||||
rawWatcher := &rawContainerWatcher{
|
||||
cgroupPaths: common.MakeCgroupPaths(cgroupSubsystems.MountPoints, "/"),
|
||||
cgroupSubsystems: &cgroupSubsystems,
|
||||
cgroupPaths: cgroupSubsystems,
|
||||
watcher: watcher,
|
||||
stopWatcher: make(chan error),
|
||||
}
|
||||
@ -195,8 +193,8 @@ func (w *rawContainerWatcher) processEvent(event *inotify.Event, events chan wat
|
||||
|
||||
// Derive the container name from the path name.
|
||||
var containerName string
|
||||
for _, mount := range w.cgroupSubsystems.Mounts {
|
||||
mountLocation := path.Clean(mount.Mountpoint) + "/"
|
||||
for _, mount := range w.cgroupPaths {
|
||||
mountLocation := path.Clean(mount) + "/"
|
||||
if strings.HasPrefix(event.Name, mountLocation) {
|
||||
containerName = event.Name[len(mountLocation)-1:]
|
||||
break
|
||||
|
2
vendor/github.com/google/cadvisor/container/systemd/factory.go
generated
vendored
2
vendor/github.com/google/cadvisor/container/systemd/factory.go
generated
vendored
@ -32,7 +32,7 @@ func (f *systemdFactory) String() string {
|
||||
return "systemd"
|
||||
}
|
||||
|
||||
func (f *systemdFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
|
||||
func (f *systemdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {
|
||||
return nil, fmt.Errorf("Not yet supported")
|
||||
}
|
||||
|
||||
|
3
vendor/github.com/google/cadvisor/container/systemd/install/install.go
generated
vendored
3
vendor/github.com/google/cadvisor/container/systemd/install/install.go
generated
vendored
@ -16,9 +16,10 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/systemd"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
29
vendor/github.com/google/cadvisor/fs/fs.go
generated
vendored
29
vendor/github.com/google/cadvisor/fs/fs.go
generated
vendored
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Provides Filesystem Stats
|
||||
@ -19,6 +20,7 @@ package fs
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -30,11 +32,12 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/google/cadvisor/devicemapper"
|
||||
"github.com/google/cadvisor/utils"
|
||||
zfs "github.com/mistifyio/go-zfs"
|
||||
mount "github.com/moby/sys/mountinfo"
|
||||
|
||||
"github.com/google/cadvisor/devicemapper"
|
||||
"github.com/google/cadvisor/utils"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
@ -56,6 +59,9 @@ const (
|
||||
// A pool for restricting the number of consecutive `du` and `find` tasks running.
|
||||
var pool = make(chan struct{}, maxConcurrentOps)
|
||||
|
||||
// ErrDeviceNotInPartitionsMap is the error resulting if a device could not be found in the partitions map.
|
||||
var ErrDeviceNotInPartitionsMap = errors.New("could not find device in cached partitions map")
|
||||
|
||||
func init() {
|
||||
for i := 0; i < maxConcurrentOps; i++ {
|
||||
releaseToken()
|
||||
@ -279,6 +285,7 @@ func (i *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) {
|
||||
|
||||
// addDockerImagesLabel attempts to determine which device contains the mount for docker images.
|
||||
func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info) {
|
||||
if context.Docker.Driver != "" {
|
||||
dockerDev, dockerPartition, err := i.getDockerDeviceMapperInfo(context.Docker)
|
||||
if err != nil {
|
||||
klog.Warningf("Could not get Docker devicemapper device: %v", err)
|
||||
@ -290,6 +297,7 @@ func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info)
|
||||
i.updateContainerImagesPath(LabelDockerImages, mounts, getDockerImagePaths(context))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (i *RealFsInfo) addCrioImagesLabel(context Context, mounts []*mount.Info) {
|
||||
if context.Crio.Root != "" {
|
||||
@ -582,15 +590,20 @@ func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
|
||||
}
|
||||
|
||||
mnt, found := i.mountInfoFromDir(dir)
|
||||
if found && mnt.FSType == "btrfs" && mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") {
|
||||
major, minor, err := getBtrfsMajorMinorIds(mnt)
|
||||
if found && strings.HasPrefix(mnt.Source, "/dev/") {
|
||||
major, minor := mnt.Major, mnt.Minor
|
||||
|
||||
if mnt.FSType == "btrfs" && major == 0 {
|
||||
major, minor, err = getBtrfsMajorMinorIds(mnt)
|
||||
if err != nil {
|
||||
klog.Warningf("%s", err)
|
||||
} else {
|
||||
klog.Warningf("Unable to get btrfs mountpoint IDs: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &DeviceInfo{mnt.Source, uint(major), uint(minor)}, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
|
||||
|
||||
return nil, fmt.Errorf("with major: %d, minor: %d: %w", major, minor, ErrDeviceNotInPartitionsMap)
|
||||
}
|
||||
|
||||
func GetDirUsage(dir string) (UsageInfo, error) {
|
||||
|
2
vendor/github.com/google/cadvisor/info/v1/container.go
generated
vendored
2
vendor/github.com/google/cadvisor/info/v1/container.go
generated
vendored
@ -963,6 +963,8 @@ type ContainerStats struct {
|
||||
Resctrl ResctrlStats `json:"resctrl,omitempty"`
|
||||
|
||||
CpuSet CPUSetStats `json:"cpuset,omitempty"`
|
||||
|
||||
OOMEvents uint64 `json:"oom_events,omitempty"`
|
||||
}
|
||||
|
||||
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
|
||||
|
7
vendor/github.com/google/cadvisor/info/v1/machine.go
generated
vendored
7
vendor/github.com/google/cadvisor/info/v1/machine.go
generated
vendored
@ -50,10 +50,13 @@ type Core struct {
|
||||
Id int `json:"core_id"`
|
||||
Threads []int `json:"thread_ids"`
|
||||
Caches []Cache `json:"caches"`
|
||||
UncoreCaches []Cache `json:"uncore_caches"`
|
||||
SocketID int `json:"socket_id"`
|
||||
}
|
||||
|
||||
type Cache struct {
|
||||
// Id of memory cache
|
||||
Id int `json:"id"`
|
||||
// Size of memory cache in bytes.
|
||||
Size uint64 `json:"size"`
|
||||
// Type of memory cache: data, instruction, or unified.
|
||||
@ -175,6 +178,9 @@ type MachineInfo struct {
|
||||
// The time of this information point.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
|
||||
// Vendor id of CPU.
|
||||
CPUVendorID string `json:"vendor_id"`
|
||||
|
||||
// The number of cores in this machine.
|
||||
NumCores int `json:"num_cores"`
|
||||
|
||||
@ -246,6 +252,7 @@ func (m *MachineInfo) Clone() *MachineInfo {
|
||||
}
|
||||
}
|
||||
copy := MachineInfo{
|
||||
CPUVendorID: m.CPUVendorID,
|
||||
Timestamp: m.Timestamp,
|
||||
NumCores: m.NumCores,
|
||||
NumPhysicalCores: m.NumPhysicalCores,
|
||||
|
2
vendor/github.com/google/cadvisor/info/v2/container.go
generated
vendored
2
vendor/github.com/google/cadvisor/info/v2/container.go
generated
vendored
@ -263,7 +263,7 @@ type FsInfo struct {
|
||||
}
|
||||
|
||||
type RequestOptions struct {
|
||||
// Type of container identifier specified - "name", "dockerid", dockeralias"
|
||||
// Type of container identifier specified - TypeName (default) or TypeDocker
|
||||
IdType string `json:"type"`
|
||||
// Number of stats to return
|
||||
Count int `json:"count"`
|
||||
|
3
vendor/github.com/google/cadvisor/info/v2/conversion.go
generated
vendored
3
vendor/github.com/google/cadvisor/info/v2/conversion.go
generated
vendored
@ -18,8 +18,9 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
|
||||
|
2
vendor/github.com/google/cadvisor/info/v2/machine.go
generated
vendored
2
vendor/github.com/google/cadvisor/info/v2/machine.go
generated
vendored
@ -18,7 +18,7 @@ import (
|
||||
// TODO(rjnagal): Move structs from v1.
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type Attributes struct {
|
||||
|
1
vendor/github.com/google/cadvisor/machine/info.go
generated
vendored
1
vendor/github.com/google/cadvisor/machine/info.go
generated
vendored
@ -121,6 +121,7 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
|
||||
|
||||
machineInfo := &info.MachineInfo{
|
||||
Timestamp: time.Now(),
|
||||
CPUVendorID: GetCPUVendorID(cpuinfo),
|
||||
NumCores: numCores,
|
||||
NumPhysicalCores: GetPhysicalCores(cpuinfo),
|
||||
NumSockets: GetSockets(cpuinfo),
|
||||
|
17
vendor/github.com/google/cadvisor/machine/machine.go
generated
vendored
17
vendor/github.com/google/cadvisor/machine/machine.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
// s390/s390x changes
|
||||
"runtime"
|
||||
"strconv"
|
||||
@ -43,6 +44,7 @@ var (
|
||||
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|CPU MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
|
||||
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
|
||||
swapCapacityRegexp = regexp.MustCompile(`SwapTotal:\s*([0-9]+) kB`)
|
||||
vendorIDRegexp = regexp.MustCompile(`vendor_id\s*:\s*(\w+)`)
|
||||
|
||||
cpuBusPath = "/sys/bus/cpu/devices/"
|
||||
isMemoryController = regexp.MustCompile("mc[0-9]+")
|
||||
@ -54,6 +56,21 @@ var (
|
||||
const memTypeFileName = "dimm_mem_type"
|
||||
const sizeFileName = "size"
|
||||
|
||||
// GetCPUVendorID returns "vendor_id" reading /proc/cpuinfo file.
|
||||
func GetCPUVendorID(procInfo []byte) string {
|
||||
vendorID := ""
|
||||
|
||||
matches := vendorIDRegexp.FindSubmatch(procInfo)
|
||||
if len(matches) != 2 {
|
||||
klog.Warning("Cannot read vendor id correctly, set empty.")
|
||||
return vendorID
|
||||
}
|
||||
|
||||
vendorID = string(matches[1])
|
||||
|
||||
return vendorID
|
||||
}
|
||||
|
||||
// GetPhysicalCores returns number of CPU cores reading /proc/cpuinfo file or if needed information from sysfs cpu path
|
||||
func GetPhysicalCores(procInfo []byte) int {
|
||||
numCores := getUniqueMatchesCount(string(procInfo), coreRegExp)
|
||||
|
1
vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
generated
vendored
1
vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
generated
vendored
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build freebsd || darwin || linux
|
||||
// +build freebsd darwin linux
|
||||
|
||||
package machine
|
||||
|
9
vendor/github.com/google/cadvisor/manager/container.go
generated
vendored
9
vendor/github.com/google/cadvisor/manager/container.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/cache/memory"
|
||||
@ -102,6 +103,8 @@ type containerData struct {
|
||||
|
||||
// resctrlCollector updates stats for resctrl controller.
|
||||
resctrlCollector stats.Collector
|
||||
|
||||
oomEvents uint64
|
||||
}
|
||||
|
||||
// jitter returns a time.Duration between duration and duration + maxFactor * duration,
|
||||
@ -127,6 +130,7 @@ func (cd *containerData) Stop() error {
|
||||
}
|
||||
close(cd.stop)
|
||||
cd.perfCollector.Destroy()
|
||||
cd.resctrlCollector.Destroy()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -668,6 +672,9 @@ func (cd *containerData) updateStats() error {
|
||||
klog.V(2).Infof("Failed to add summary stats for %q: %v", cd.info.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
stats.OOMEvents = atomic.LoadUint64(&cd.oomEvents)
|
||||
|
||||
var customStatsErr error
|
||||
cm := cd.collectorManager.(*collector.GenericCollectorManager)
|
||||
if len(cm.Collectors) > 0 {
|
||||
@ -721,7 +728,7 @@ func (cd *containerData) updateStats() error {
|
||||
return perfStatsErr
|
||||
}
|
||||
if resctrlStatsErr != nil {
|
||||
klog.Errorf("error occurred while collecting resctrl stats for container %s: %s", cInfo.Name, err)
|
||||
klog.Errorf("error occurred while collecting resctrl stats for container %s: %s", cInfo.Name, resctrlStatsErr)
|
||||
return resctrlStatsErr
|
||||
}
|
||||
return customStatsErr
|
||||
|
102
vendor/github.com/google/cadvisor/manager/manager.go
generated
vendored
102
vendor/github.com/google/cadvisor/manager/manager.go
generated
vendored
@ -24,18 +24,18 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/accelerators"
|
||||
"github.com/google/cadvisor/cache/memory"
|
||||
"github.com/google/cadvisor/collector"
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
"github.com/google/cadvisor/container/raw"
|
||||
"github.com/google/cadvisor/events"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/info/v2"
|
||||
v2 "github.com/google/cadvisor/info/v2"
|
||||
"github.com/google/cadvisor/machine"
|
||||
"github.com/google/cadvisor/nvm"
|
||||
"github.com/google/cadvisor/perf"
|
||||
@ -47,8 +47,6 @@ import (
|
||||
"github.com/google/cadvisor/watcher"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/clock"
|
||||
@ -61,6 +59,14 @@ var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h",
|
||||
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
|
||||
var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)")
|
||||
|
||||
// The namespace under which Docker aliases are unique.
|
||||
const DockerNamespace = "docker"
|
||||
|
||||
var HousekeepingConfigFlags = HouskeepingConfig{
|
||||
flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings"),
|
||||
flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic"),
|
||||
}
|
||||
|
||||
// The Manager interface defines operations for starting a manager and getting
|
||||
// container and machine information.
|
||||
type Manager interface {
|
||||
@ -129,12 +135,6 @@ type Manager interface {
|
||||
|
||||
CloseEventChannel(watchID int)
|
||||
|
||||
// Get status information about docker.
|
||||
DockerInfo() (info.DockerStatus, error)
|
||||
|
||||
// Get details about interesting docker images.
|
||||
DockerImages() ([]info.DockerImage, error)
|
||||
|
||||
// Returns debugging information. Map of lines per category.
|
||||
DebugInfo() map[string][]string
|
||||
}
|
||||
@ -146,7 +146,7 @@ type HouskeepingConfig = struct {
|
||||
}
|
||||
|
||||
// New takes a memory storage and returns a new manager.
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig HouskeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string, perfEventsFile string) (Manager, error) {
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig HouskeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList, containerEnvMetadataWhiteList []string, perfEventsFile string, resctrlInterval time.Duration) (Manager, error) {
|
||||
if memoryCache == nil {
|
||||
return nil, fmt.Errorf("manager requires memory storage")
|
||||
}
|
||||
@ -203,6 +203,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig
|
||||
collectorHTTPClient: collectorHTTPClient,
|
||||
nvidiaManager: accelerators.NewNvidiaManager(includedMetricsSet),
|
||||
rawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,
|
||||
containerEnvMetadataWhiteList: containerEnvMetadataWhiteList,
|
||||
}
|
||||
|
||||
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
|
||||
@ -217,7 +218,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newManager.resctrlManager, err = resctrl.NewManager(selfContainer)
|
||||
newManager.resctrlManager, err = resctrl.NewManager(resctrlInterval, resctrl.Setup, machineInfo.CPUVendorID, inHostNamespace)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Cannot gather resctrl metrics: %v", err)
|
||||
}
|
||||
@ -262,9 +263,11 @@ type manager struct {
|
||||
collectorHTTPClient *http.Client
|
||||
nvidiaManager stats.Manager
|
||||
perfManager stats.Manager
|
||||
resctrlManager stats.Manager
|
||||
resctrlManager resctrl.Manager
|
||||
// List of raw container cgroup path prefix whitelist.
|
||||
rawContainerCgroupPathPrefixWhiteList []string
|
||||
// List of container env prefix whitelist, the matched container envs would be collected into metrics as extra labels.
|
||||
containerEnvMetadataWhiteList []string
|
||||
}
|
||||
|
||||
// Start the container manager.
|
||||
@ -327,7 +330,7 @@ func (m *manager) Start() error {
|
||||
|
||||
func (m *manager) Stop() error {
|
||||
defer m.nvidiaManager.Destroy()
|
||||
defer m.destroyPerfCollectors()
|
||||
defer m.destroyCollectors()
|
||||
// Stop and wait on all quit channels.
|
||||
for i, c := range m.quitChannels {
|
||||
// Send the exit signal and wait on the thread to exit (by closing the channel).
|
||||
@ -345,9 +348,10 @@ func (m *manager) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) destroyPerfCollectors() {
|
||||
func (m *manager) destroyCollectors() {
|
||||
for _, container := range m.containers {
|
||||
container.perfCollector.Destroy()
|
||||
container.resctrlCollector.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,7 +594,7 @@ func (m *manager) getAllDockerContainers() map[string]*containerData {
|
||||
|
||||
// Get containers in the Docker namespace.
|
||||
for name, cont := range m.containers {
|
||||
if name.Namespace == docker.DockerNamespace {
|
||||
if name.Namespace == DockerNamespace {
|
||||
containers[cont.info.Name] = cont
|
||||
}
|
||||
}
|
||||
@ -622,14 +626,14 @@ func (m *manager) getDockerContainer(containerName string) (*containerData, erro
|
||||
|
||||
// Check for the container in the Docker container namespace.
|
||||
cont, ok := m.containers[namespacedContainerName{
|
||||
Namespace: docker.DockerNamespace,
|
||||
Namespace: DockerNamespace,
|
||||
Name: containerName,
|
||||
}]
|
||||
|
||||
// Look for container by short prefix name if no exact match found.
|
||||
if !ok {
|
||||
for contName, c := range m.containers {
|
||||
if contName.Namespace == docker.DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
|
||||
if contName.Namespace == DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
|
||||
if cont == nil {
|
||||
cont = c
|
||||
} else {
|
||||
@ -692,6 +696,10 @@ func (m *manager) GetRequestedContainersInfo(containerName string, options v2.Re
|
||||
for name, data := range containers {
|
||||
info, err := m.containerDataToContainerInfo(data, &query)
|
||||
if err != nil {
|
||||
if err == memory.ErrDataNotFound {
|
||||
klog.Warningf("Error getting data for container %s because of race condition", name)
|
||||
continue
|
||||
}
|
||||
errs.append(name, "containerDataToContainerInfo", err)
|
||||
}
|
||||
containersMap[name] = info
|
||||
@ -908,7 +916,7 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
|
||||
return nil
|
||||
}
|
||||
|
||||
handler, accept, err := container.NewContainerHandler(containerName, watchSource, m.inHostNamespace)
|
||||
handler, accept, err := container.NewContainerHandler(containerName, watchSource, m.containerEnvMetadataWhiteList, m.inHostNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -928,13 +936,7 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
|
||||
return err
|
||||
}
|
||||
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
perfCgroupPath := path.Join(fs2.UnifiedMountpoint, containerName)
|
||||
cont.perfCollector, err = m.perfManager.GetCollector(perfCgroupPath)
|
||||
if err != nil {
|
||||
klog.Errorf("Perf event metrics will not be available for container %q: %v", containerName, err)
|
||||
}
|
||||
} else {
|
||||
if !cgroups.IsCgroup2UnifiedMode() {
|
||||
devicesCgroupPath, err := handler.GetCgroupPath("devices")
|
||||
if err != nil {
|
||||
klog.Warningf("Error getting devices cgroup path: %v", err)
|
||||
@ -944,6 +946,8 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
|
||||
klog.V(4).Infof("GPU metrics may be unavailable/incomplete for container %s: %s", cont.info.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if m.includedMetrics.Has(container.PerfMetrics) {
|
||||
perfCgroupPath, err := handler.GetCgroupPath("perf_event")
|
||||
if err != nil {
|
||||
klog.Warningf("Error getting perf_event cgroup path: %q", err)
|
||||
@ -956,16 +960,13 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
|
||||
}
|
||||
|
||||
if m.includedMetrics.Has(container.ResctrlMetrics) {
|
||||
resctrlPath, err := intelrdt.GetIntelRdtPath(containerName)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Error getting resctrl path: %q", err)
|
||||
} else {
|
||||
cont.resctrlCollector, err = m.resctrlManager.GetCollector(resctrlPath)
|
||||
cont.resctrlCollector, err = m.resctrlManager.GetCollector(containerName, func() ([]string, error) {
|
||||
return cont.getContainerPids(m.inHostNamespace)
|
||||
}, len(m.machineInfo.Topology))
|
||||
if err != nil {
|
||||
klog.V(4).Infof("resctrl metrics will not be available for container %s: %s", cont.info.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add collectors
|
||||
labels := handler.GetContainerLabels()
|
||||
@ -1005,7 +1006,6 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the container's housekeeping.
|
||||
return cont.Start()
|
||||
}
|
||||
@ -1237,6 +1237,24 @@ func (m *manager) watchForNewOoms() error {
|
||||
if err != nil {
|
||||
klog.Errorf("failed to add OOM kill event for %q: %v", oomInstance.ContainerName, err)
|
||||
}
|
||||
|
||||
// Count OOM events for later collection by prometheus
|
||||
request := v2.RequestOptions{
|
||||
IdType: v2.TypeName,
|
||||
Count: 1,
|
||||
}
|
||||
conts, err := m.getRequestedContainers(oomInstance.ContainerName, request)
|
||||
if err != nil {
|
||||
klog.V(2).Infof("failed getting container info for %q: %v", oomInstance.ContainerName, err)
|
||||
continue
|
||||
}
|
||||
if len(conts) != 1 {
|
||||
klog.V(2).Info("Expected the request to match only one container")
|
||||
continue
|
||||
}
|
||||
for _, cont := range conts {
|
||||
atomic.AddUint64(&cont.oomEvents, 1)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
@ -1304,14 +1322,6 @@ func parseEventsStoragePolicy() events.StoragePolicy {
|
||||
return policy
|
||||
}
|
||||
|
||||
func (m *manager) DockerImages() ([]info.DockerImage, error) {
|
||||
return docker.Images()
|
||||
}
|
||||
|
||||
func (m *manager) DockerInfo() (info.DockerStatus, error) {
|
||||
return docker.Status()
|
||||
}
|
||||
|
||||
func (m *manager) DebugInfo() map[string][]string {
|
||||
debugInfo := container.DebugInfo()
|
||||
|
||||
@ -1368,20 +1378,10 @@ func getVersionInfo() (*info.VersionInfo, error) {
|
||||
|
||||
kernelVersion := machine.KernelVersion()
|
||||
osVersion := machine.ContainerOsVersion()
|
||||
dockerVersion, err := docker.VersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dockerAPIVersion, err := docker.APIVersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info.VersionInfo{
|
||||
KernelVersion: kernelVersion,
|
||||
ContainerOsVersion: osVersion,
|
||||
DockerVersion: dockerVersion,
|
||||
DockerAPIVersion: dockerAPIVersion,
|
||||
CadvisorVersion: version.Info["version"],
|
||||
CadvisorRevision: version.Info["revision"],
|
||||
}, nil
|
||||
|
16
vendor/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
16
vendor/github.com/google/cadvisor/metrics/prometheus.go
generated
vendored
@ -1757,6 +1757,17 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri
|
||||
},
|
||||
}...)
|
||||
}
|
||||
if includedMetrics.Has(container.OOMMetrics) {
|
||||
c.containerMetrics = append(c.containerMetrics, containerMetric{
|
||||
name: "container_oom_events_total",
|
||||
help: "Count of out of memory events observed for the container",
|
||||
valueType: prometheus.CounterValue,
|
||||
getValues: func(s *info.ContainerStats) metricValues {
|
||||
return metricValues{{value: float64(s.OOMEvents), timestamp: s.Timestamp}}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@ -1825,7 +1836,7 @@ func DefaultContainerLabels(container *info.ContainerInfo) map[string]string {
|
||||
}
|
||||
|
||||
// BaseContainerLabels returns a ContainerLabelsFunc that exports the container
|
||||
// name, first alias, image name as well as white listed label values.
|
||||
// name, first alias, image name as well as all its white listed env and label values.
|
||||
func BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo) map[string]string {
|
||||
whiteListMap := make(map[string]struct{}, len(whiteList))
|
||||
for _, k := range whiteList {
|
||||
@ -1845,6 +1856,9 @@ func BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo)
|
||||
set[ContainerLabelPrefix+k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range container.Spec.Envs {
|
||||
set[ContainerEnvPrefix+k] = v
|
||||
}
|
||||
return set
|
||||
}
|
||||
}
|
||||
|
11
vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
generated
vendored
11
vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
generated
vendored
@ -17,9 +17,10 @@ package metrics
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@ -334,6 +335,14 @@ func getCaches(machineInfo *info.MachineInfo) metricValues {
|
||||
timestamp: machineInfo.Timestamp,
|
||||
})
|
||||
}
|
||||
for _, cache := range core.UncoreCaches {
|
||||
mValues = append(mValues,
|
||||
metricValue{
|
||||
value: float64(cache.Size),
|
||||
labels: []string{nodeID, coreID, cache.Type, strconv.Itoa(cache.Level)},
|
||||
timestamp: machineInfo.Timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, cache := range node.Caches {
|
||||
|
4
vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
generated
vendored
4
vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build libipmctl && cgo
|
||||
// +build libipmctl,cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
@ -21,9 +22,10 @@ package nvm
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"sync"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
|
4
vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go
generated
vendored
4
vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !libipmctl || !cgo
|
||||
// +build !libipmctl !cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
@ -17,8 +18,9 @@
|
||||
package nvm
|
||||
|
||||
import (
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
// GetInfo returns information specific for non-volatile memory modules.
|
||||
|
100
vendor/github.com/google/cadvisor/perf/collector_libpfm.go
generated
vendored
100
vendor/github.com/google/cadvisor/perf/collector_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build libpfm && cgo
|
||||
// +build libpfm,cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
@ -47,6 +48,10 @@ type collector struct {
|
||||
onlineCPUs []int
|
||||
eventToCustomEvent map[Event]*CustomEvent
|
||||
uncore stats.Collector
|
||||
|
||||
// Handle for mocking purposes.
|
||||
perfEventOpen func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
|
||||
ioctlSetInt func(fd int, req uint, value int) error
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@ -76,7 +81,7 @@ func init() {
|
||||
}
|
||||
|
||||
func newCollector(cgroupPath string, events PerfEvents, onlineCPUs []int, cpuToSocket map[int]int) *collector {
|
||||
collector := &collector{cgroupPath: cgroupPath, events: events, onlineCPUs: onlineCPUs, cpuFiles: map[int]group{}, uncore: NewUncoreCollector(cgroupPath, events, cpuToSocket)}
|
||||
collector := &collector{cgroupPath: cgroupPath, events: events, onlineCPUs: onlineCPUs, cpuFiles: map[int]group{}, uncore: NewUncoreCollector(cgroupPath, events, cpuToSocket), perfEventOpen: unix.PerfEventOpen, ioctlSetInt: unix.IoctlSetInt}
|
||||
mapEventsToCustomEvents(collector)
|
||||
return collector
|
||||
}
|
||||
@ -185,44 +190,30 @@ func (c *collector) setup() error {
|
||||
c.cpuFilesLock.Lock()
|
||||
defer c.cpuFilesLock.Unlock()
|
||||
cgroupFd := int(cgroup.Fd())
|
||||
for i, group := range c.events.Core.Events {
|
||||
groupIndex := 0
|
||||
for _, group := range c.events.Core.Events {
|
||||
// CPUs file descriptors of group leader needed for perf_event_open.
|
||||
leaderFileDescriptors := make(map[int]int, len(c.onlineCPUs))
|
||||
for _, cpu := range c.onlineCPUs {
|
||||
leaderFileDescriptors[cpu] = groupLeaderFileDescriptor
|
||||
}
|
||||
|
||||
for j, event := range group.events {
|
||||
// First element is group leader.
|
||||
isGroupLeader := j == 0
|
||||
customEvent, ok := c.eventToCustomEvent[event]
|
||||
if ok {
|
||||
config := c.createConfigFromRawEvent(customEvent)
|
||||
leaderFileDescriptors, err = c.registerEvent(eventInfo{string(customEvent.Name), config, cgroupFd, i, isGroupLeader}, leaderFileDescriptors)
|
||||
leaderFileDescriptors, err := c.createLeaderFileDescriptors(group.events, cgroupFd, groupIndex, leaderFileDescriptors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
klog.Errorf("Cannot count perf event group %v: %v", group.events, err)
|
||||
c.deleteGroup(groupIndex)
|
||||
continue
|
||||
} else {
|
||||
config, err := c.createConfigFromEvent(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
leaderFileDescriptors, err = c.registerEvent(eventInfo{string(event), config, cgroupFd, i, isGroupLeader}, leaderFileDescriptors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Clean memory allocated by C code.
|
||||
C.free(unsafe.Pointer(config))
|
||||
}
|
||||
groupIndex++
|
||||
}
|
||||
|
||||
// Group is prepared so we should reset and enable counting.
|
||||
for _, fd := range leaderFileDescriptors {
|
||||
err = unix.IoctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)
|
||||
err = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = unix.IoctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)
|
||||
err = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -232,6 +223,35 @@ func (c *collector) setup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) createLeaderFileDescriptors(events []Event, cgroupFd int, groupIndex int, leaderFileDescriptors map[int]int) (map[int]int, error) {
|
||||
for j, event := range events {
|
||||
// First element is group leader.
|
||||
isGroupLeader := j == 0
|
||||
customEvent, ok := c.eventToCustomEvent[event]
|
||||
var err error
|
||||
if ok {
|
||||
config := c.createConfigFromRawEvent(customEvent)
|
||||
leaderFileDescriptors, err = c.registerEvent(eventInfo{string(customEvent.Name), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot register perf event: %v", err)
|
||||
}
|
||||
} else {
|
||||
config, err := c.createConfigFromEvent(event)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create config from perf event: %v", err)
|
||||
|
||||
}
|
||||
leaderFileDescriptors, err = c.registerEvent(eventInfo{string(event), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot register perf event: %v", err)
|
||||
}
|
||||
// Clean memory allocated by C code.
|
||||
C.free(unsafe.Pointer(config))
|
||||
}
|
||||
}
|
||||
return leaderFileDescriptors, nil
|
||||
}
|
||||
|
||||
func readPerfEventAttr(name string, pfmGetOsEventEncoding func(string, unsafe.Pointer) error) (*unix.PerfEventAttr, error) {
|
||||
perfEventAttrMemory := C.malloc(C.ulong(unsafe.Sizeof(unix.PerfEventAttr{})))
|
||||
// Fill memory with 0 values.
|
||||
@ -279,13 +299,13 @@ func (c *collector) registerEvent(event eventInfo, leaderFileDescriptors map[int
|
||||
setAttributes(event.config, event.isGroupLeader)
|
||||
|
||||
for _, cpu := range c.onlineCPUs {
|
||||
fd, err := unix.PerfEventOpen(event.config, pid, cpu, leaderFileDescriptors[cpu], flags)
|
||||
fd, err := c.perfEventOpen(event.config, pid, cpu, leaderFileDescriptors[cpu], flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up perf event %#v failed: %q", event.config, err)
|
||||
return leaderFileDescriptors, fmt.Errorf("setting up perf event %#v failed: %q", event.config, err)
|
||||
}
|
||||
perfFile := os.NewFile(uintptr(fd), event.name)
|
||||
if perfFile == nil {
|
||||
return nil, fmt.Errorf("unable to create os.File from file descriptor %#v", fd)
|
||||
return leaderFileDescriptors, fmt.Errorf("unable to create os.File from file descriptor %#v", fd)
|
||||
}
|
||||
|
||||
c.addEventFile(event.groupIndex, event.name, cpu, perfFile)
|
||||
@ -333,6 +353,19 @@ func (c *collector) addEventFile(index int, name string, cpu int, perfFile *os.F
|
||||
}
|
||||
}
|
||||
|
||||
func (c *collector) deleteGroup(index int) {
|
||||
for name, files := range c.cpuFiles[index].cpuFiles {
|
||||
for cpu, file := range files {
|
||||
klog.V(5).Infof("Closing perf event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
klog.Warningf("Unable to close perf event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(c.cpuFiles, index)
|
||||
}
|
||||
|
||||
func createPerfEventAttr(event CustomEvent) *unix.PerfEventAttr {
|
||||
length := len(event.Config)
|
||||
|
||||
@ -369,17 +402,8 @@ func (c *collector) Destroy() {
|
||||
c.cpuFilesLock.Lock()
|
||||
defer c.cpuFilesLock.Unlock()
|
||||
|
||||
for _, group := range c.cpuFiles {
|
||||
for name, files := range group.cpuFiles {
|
||||
for cpu, file := range files {
|
||||
klog.V(5).Infof("Closing perf_event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
klog.Warningf("Unable to close perf_event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
|
||||
}
|
||||
}
|
||||
delete(group.cpuFiles, name)
|
||||
}
|
||||
for i := range c.cpuFiles {
|
||||
c.deleteGroup(i)
|
||||
}
|
||||
}
|
||||
|
||||
|
1
vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go
generated
vendored
1
vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !libpfm || !cgo
|
||||
// +build !libpfm !cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
|
5
vendor/github.com/google/cadvisor/perf/manager_libpfm.go
generated
vendored
5
vendor/github.com/google/cadvisor/perf/manager_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build libpfm && cgo
|
||||
// +build libpfm,cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
@ -48,6 +49,10 @@ func NewManager(configFile string, topology []info.Node) (stats.Manager, error)
|
||||
return nil, fmt.Errorf("unable to parse configuration file %q: %w", configFile, err)
|
||||
}
|
||||
|
||||
if len(config.Core.Events) == 0 && len(config.Uncore.Events) == 0 {
|
||||
return nil, fmt.Errorf("there is no events in config file %q", configFile)
|
||||
}
|
||||
|
||||
onlineCPUs := sysinfo.GetOnlineCPUs(topology)
|
||||
|
||||
cpuToSocket := make(map[int]int)
|
||||
|
1
vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go
generated
vendored
1
vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !libpfm || !cgo
|
||||
// +build !libpfm !cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
|
1
vendor/github.com/google/cadvisor/perf/types_libpfm.go
generated
vendored
1
vendor/github.com/google/cadvisor/perf/types_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build libpfm && cgo
|
||||
// +build libpfm,cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
|
73
vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
generated
vendored
73
vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build libpfm && cgo
|
||||
// +build libpfm,cgo
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
@ -158,6 +159,28 @@ func NewUncoreCollector(cgroupPath string, events PerfEvents, cpuToSocket map[in
|
||||
return collector
|
||||
}
|
||||
|
||||
func (c *uncoreCollector) createLeaderFileDescriptors(events []Event, groupIndex int, groupPMUs map[Event]uncorePMUs,
|
||||
leaderFileDescriptors map[string]map[uint32]int) (map[string]map[uint32]int, error) {
|
||||
var err error
|
||||
for _, event := range events {
|
||||
eventName, _ := parseEventName(string(event))
|
||||
customEvent, ok := c.eventToCustomEvent[event]
|
||||
if ok {
|
||||
err = c.setupRawEvent(customEvent, groupPMUs[event], groupIndex, leaderFileDescriptors)
|
||||
} else {
|
||||
err = c.setupEvent(eventName, groupPMUs[event], groupIndex, leaderFileDescriptors)
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
c.deleteGroup(groupIndex)
|
||||
return nil, fmt.Errorf("cannot create config from perf event: %v", err)
|
||||
}
|
||||
return leaderFileDescriptors, nil
|
||||
}
|
||||
|
||||
func (c *uncoreCollector) setup(events PerfEvents, devicesPath string) error {
|
||||
readUncorePMUs, err := getUncorePMUs(devicesPath)
|
||||
if err != nil {
|
||||
@ -190,21 +213,11 @@ func (c *uncoreCollector) setup(events PerfEvents, devicesPath string) error {
|
||||
leaderFileDescriptors[pmu.name][cpu] = groupLeaderFileDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
for _, event := range group.events {
|
||||
eventName, _ := parseEventName(string(event))
|
||||
customEvent, ok := c.eventToCustomEvent[event]
|
||||
if ok {
|
||||
err = c.setupRawEvent(customEvent, groupPMUs[event], i, leaderFileDescriptors)
|
||||
} else {
|
||||
err = c.setupEvent(eventName, groupPMUs[event], i, leaderFileDescriptors)
|
||||
}
|
||||
|
||||
leaderFileDescriptors, err = c.createLeaderFileDescriptors(group.events, i, groupPMUs, leaderFileDescriptors)
|
||||
if err != nil {
|
||||
return err
|
||||
klog.Error(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Group is prepared so we should reset and enable counting.
|
||||
for _, pmuCPUs := range leaderFileDescriptors {
|
||||
for _, fd := range pmuCPUs {
|
||||
@ -320,20 +333,8 @@ func (c *uncoreCollector) Destroy() {
|
||||
c.cpuFilesLock.Lock()
|
||||
defer c.cpuFilesLock.Unlock()
|
||||
|
||||
for groupIndex, groupPMUs := range c.cpuFiles {
|
||||
for pmu, group := range groupPMUs {
|
||||
for name, cpus := range group.cpuFiles {
|
||||
for cpu, file := range cpus {
|
||||
klog.V(5).Infof("Closing uncore perf_event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
klog.Warningf("Unable to close perf_event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
|
||||
}
|
||||
}
|
||||
delete(group.cpuFiles, name)
|
||||
}
|
||||
delete(groupPMUs, pmu)
|
||||
}
|
||||
for groupIndex := range c.cpuFiles {
|
||||
c.deleteGroup(groupIndex)
|
||||
delete(c.cpuFiles, groupIndex)
|
||||
}
|
||||
}
|
||||
@ -475,6 +476,24 @@ func (c *uncoreCollector) setupRawEvent(event *CustomEvent, pmus uncorePMUs, gro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *uncoreCollector) deleteGroup(groupIndex int) {
|
||||
groupPMUs := c.cpuFiles[groupIndex]
|
||||
for pmu, group := range groupPMUs {
|
||||
for name, cpus := range group.cpuFiles {
|
||||
for cpu, file := range cpus {
|
||||
klog.V(5).Infof("Closing uncore perf event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
|
||||
err := file.Close()
|
||||
if err != nil {
|
||||
klog.Warningf("Unable to close perf event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
|
||||
}
|
||||
}
|
||||
delete(group.cpuFiles, name)
|
||||
}
|
||||
delete(groupPMUs, pmu)
|
||||
}
|
||||
delete(c.cpuFiles, groupIndex)
|
||||
}
|
||||
|
||||
func readPerfUncoreStat(file readerCloser, group group, cpu int, pmu string, cpuToSocket map[int]int) ([]info.PerfUncoreStat, error) {
|
||||
values, err := getPerfValues(file, group)
|
||||
if err != nil {
|
||||
|
141
vendor/github.com/google/cadvisor/resctrl/collector.go
generated
vendored
141
vendor/github.com/google/cadvisor/resctrl/collector.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -18,44 +19,114 @@
|
||||
package resctrl
|
||||
|
||||
import (
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/stats"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
const noInterval = 0
|
||||
|
||||
type collector struct {
|
||||
resctrl intelrdt.Manager
|
||||
stats.NoopDestroy
|
||||
id string
|
||||
interval time.Duration
|
||||
getContainerPids func() ([]string, error)
|
||||
resctrlPath string
|
||||
running bool
|
||||
destroyed bool
|
||||
numberOfNUMANodes int
|
||||
vendorID string
|
||||
mu sync.Mutex
|
||||
inHostNamespace bool
|
||||
}
|
||||
|
||||
func newCollector(id string, resctrlPath string) *collector {
|
||||
collector := &collector{
|
||||
resctrl: intelrdt.NewManager(
|
||||
&configs.Config{
|
||||
IntelRdt: &configs.IntelRdt{},
|
||||
},
|
||||
id,
|
||||
resctrlPath,
|
||||
),
|
||||
func newCollector(id string, getContainerPids func() ([]string, error), interval time.Duration, numberOfNUMANodes int, vendorID string, inHostNamespace bool) *collector {
|
||||
return &collector{id: id, interval: interval, getContainerPids: getContainerPids, numberOfNUMANodes: numberOfNUMANodes,
|
||||
vendorID: vendorID, mu: sync.Mutex{}, inHostNamespace: inHostNamespace}
|
||||
}
|
||||
|
||||
return collector
|
||||
func (c *collector) setup() error {
|
||||
var err error
|
||||
c.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
|
||||
|
||||
if c.interval != noInterval {
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to setup container %q resctrl collector: %s \n Trying again in next intervals.", c.id, err)
|
||||
} else {
|
||||
c.running = true
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(c.interval)
|
||||
c.mu.Lock()
|
||||
if c.destroyed {
|
||||
break
|
||||
}
|
||||
klog.V(5).Infof("Trying to check %q containers control group.", c.id)
|
||||
if c.running {
|
||||
err = c.checkMonitoringGroup()
|
||||
if err != nil {
|
||||
c.running = false
|
||||
klog.Errorf("Failed to check %q resctrl collector control group: %s \n Trying again in next intervals.", c.id, err)
|
||||
}
|
||||
} else {
|
||||
c.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
|
||||
if err != nil {
|
||||
c.running = false
|
||||
klog.Errorf("Failed to setup container %q resctrl collector: %s \n Trying again in next intervals.", c.id, err)
|
||||
}
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
// There is no interval set, if setup fail, stop.
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setup container %q resctrl collector: %w", c.id, err)
|
||||
}
|
||||
c.running = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) checkMonitoringGroup() error {
|
||||
newPath, err := prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't obtain mon_group path: %v", err)
|
||||
}
|
||||
|
||||
// Check if container moved between control groups.
|
||||
if newPath != c.resctrlPath {
|
||||
err = c.clear()
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't clear previous monitoring group: %w", err)
|
||||
}
|
||||
c.resctrlPath = newPath
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) UpdateStats(stats *info.ContainerStats) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.running {
|
||||
stats.Resctrl = info.ResctrlStats{}
|
||||
|
||||
resctrlStats, err := c.resctrl.GetStats()
|
||||
resctrlStats, err := getIntelRDTStatsFrom(c.resctrlPath, c.vendorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
numberOfNUMANodes := len(*resctrlStats.MBMStats)
|
||||
|
||||
stats.Resctrl.MemoryBandwidth = make([]info.MemoryBandwidthStats, 0, numberOfNUMANodes)
|
||||
stats.Resctrl.Cache = make([]info.CacheStats, 0, numberOfNUMANodes)
|
||||
stats.Resctrl.MemoryBandwidth = make([]info.MemoryBandwidthStats, 0, c.numberOfNUMANodes)
|
||||
stats.Resctrl.Cache = make([]info.CacheStats, 0, c.numberOfNUMANodes)
|
||||
|
||||
for _, numaNodeStats := range *resctrlStats.MBMStats {
|
||||
stats.Resctrl.MemoryBandwidth = append(stats.Resctrl.MemoryBandwidth,
|
||||
@ -69,6 +140,32 @@ func (c *collector) UpdateStats(stats *info.ContainerStats) error {
|
||||
stats.Resctrl.Cache = append(stats.Resctrl.Cache,
|
||||
info.CacheStats{LLCOccupancy: numaNodeStats.LLCOccupancy})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collector) Destroy() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.running = false
|
||||
err := c.clear()
|
||||
if err != nil {
|
||||
klog.Errorf("trying to destroy %q resctrl collector but: %v", c.id, err)
|
||||
}
|
||||
c.destroyed = true
|
||||
}
|
||||
|
||||
func (c *collector) clear() error {
|
||||
// Not allowed to remove root or undefined resctrl directory.
|
||||
if c.id != rootContainer && c.resctrlPath != "" {
|
||||
// Remove only own prepared mon group.
|
||||
if strings.HasPrefix(filepath.Base(c.resctrlPath), monGroupPrefix) {
|
||||
err := os.RemoveAll(c.resctrlPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't clear mon_group: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
61
vendor/github.com/google/cadvisor/resctrl/manager.go
generated
vendored
61
vendor/github.com/google/cadvisor/resctrl/manager.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright 2020 Google Inc. All Rights Reserved.
|
||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -18,31 +19,61 @@
|
||||
package resctrl
|
||||
|
||||
import (
|
||||
"os"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/container/raw"
|
||||
"github.com/google/cadvisor/stats"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
)
|
||||
|
||||
type manager struct {
|
||||
id string
|
||||
stats.NoopDestroy
|
||||
type Manager interface {
|
||||
Destroy()
|
||||
GetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error)
|
||||
}
|
||||
|
||||
func (m manager) GetCollector(resctrlPath string) (stats.Collector, error) {
|
||||
if _, err := os.Stat(resctrlPath); err != nil {
|
||||
type manager struct {
|
||||
stats.NoopDestroy
|
||||
interval time.Duration
|
||||
vendorID string
|
||||
inHostNamespace bool
|
||||
}
|
||||
|
||||
func (m *manager) GetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error) {
|
||||
collector := newCollector(containerName, getContainerPids, m.interval, numberOfNUMANodes, m.vendorID, m.inHostNamespace)
|
||||
err := collector.setup()
|
||||
if err != nil {
|
||||
return &stats.NoopCollector{}, err
|
||||
}
|
||||
collector := newCollector(m.id, resctrlPath)
|
||||
|
||||
return collector, nil
|
||||
}
|
||||
|
||||
func NewManager(id string) (stats.Manager, error) {
|
||||
|
||||
if intelrdt.IsMBMEnabled() || intelrdt.IsCMTEnabled() {
|
||||
return &manager{id: id}, nil
|
||||
func NewManager(interval time.Duration, setup func() error, vendorID string, inHostNamespace bool) (Manager, error) {
|
||||
err := setup()
|
||||
if err != nil {
|
||||
return &NoopManager{}, err
|
||||
}
|
||||
|
||||
return &stats.NoopManager{}, nil
|
||||
if !isResctrlInitialized {
|
||||
return &NoopManager{}, errors.New("the resctrl isn't initialized")
|
||||
}
|
||||
if !(enabledCMT || enabledMBM) {
|
||||
return &NoopManager{}, errors.New("there are no monitoring features available")
|
||||
}
|
||||
|
||||
if !*raw.DockerOnly {
|
||||
klog.Warning("--docker_only should be set when collecting Resctrl metrics! See the runtime docs.")
|
||||
}
|
||||
|
||||
return &manager{interval: interval, vendorID: vendorID, inHostNamespace: inHostNamespace}, nil
|
||||
}
|
||||
|
||||
type NoopManager struct {
|
||||
stats.NoopDestroy
|
||||
}
|
||||
|
||||
func (np *NoopManager) GetCollector(_ string, _ func() ([]string, error), _ int) (stats.Collector, error) {
|
||||
return &stats.NoopCollector{}, nil
|
||||
}
|
||||
|
366
vendor/github.com/google/cadvisor/resctrl/utils.go
generated
vendored
Normal file
366
vendor/github.com/google/cadvisor/resctrl/utils.go
generated
vendored
Normal file
@ -0,0 +1,366 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Utilities.
|
||||
package resctrl
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
)
|
||||
|
||||
const (
|
||||
cpuCgroup = "cpu"
|
||||
rootContainer = "/"
|
||||
monitoringGroupDir = "mon_groups"
|
||||
processTask = "task"
|
||||
cpusFileName = "cpus"
|
||||
cpusListFileName = "cpus_list"
|
||||
schemataFileName = "schemata"
|
||||
tasksFileName = "tasks"
|
||||
infoDirName = "info"
|
||||
monDataDirName = "mon_data"
|
||||
monGroupsDirName = "mon_groups"
|
||||
noPidsPassedError = "there are no pids passed"
|
||||
noContainerNameError = "there are no container name passed"
|
||||
noControlGroupFoundError = "couldn't find control group matching container"
|
||||
llcOccupancyFileName = "llc_occupancy"
|
||||
mbmLocalBytesFileName = "mbm_local_bytes"
|
||||
mbmTotalBytesFileName = "mbm_total_bytes"
|
||||
containerPrefix = '/'
|
||||
minContainerNameLen = 2 // "/<container_name>" e.g. "/a"
|
||||
unavailable = "Unavailable"
|
||||
monGroupPrefix = "cadvisor"
|
||||
)
|
||||
|
||||
var (
|
||||
rootResctrl = ""
|
||||
pidsPath = ""
|
||||
processPath = "/proc"
|
||||
enabledMBM = false
|
||||
enabledCMT = false
|
||||
isResctrlInitialized = false
|
||||
groupDirectories = map[string]struct{}{
|
||||
cpusFileName: {},
|
||||
cpusListFileName: {},
|
||||
infoDirName: {},
|
||||
monDataDirName: {},
|
||||
monGroupsDirName: {},
|
||||
schemataFileName: {},
|
||||
tasksFileName: {},
|
||||
}
|
||||
)
|
||||
|
||||
func Setup() error {
|
||||
var err error
|
||||
rootResctrl, err = intelrdt.GetIntelRdtPath(rootContainer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to initialize resctrl: %v", err)
|
||||
}
|
||||
|
||||
if cgroups.IsCgroup2UnifiedMode() {
|
||||
pidsPath = fs2.UnifiedMountpoint
|
||||
} else {
|
||||
pidsPath = filepath.Join(fs2.UnifiedMountpoint, cpuCgroup)
|
||||
}
|
||||
|
||||
enabledMBM = intelrdt.IsMBMEnabled()
|
||||
enabledCMT = intelrdt.IsCMTEnabled()
|
||||
|
||||
isResctrlInitialized = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareMonitoringGroup(containerName string, getContainerPids func() ([]string, error), inHostNamespace bool) (string, error) {
|
||||
if containerName == rootContainer {
|
||||
return rootResctrl, nil
|
||||
}
|
||||
|
||||
pids, err := getContainerPids()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(pids) == 0 {
|
||||
return "", fmt.Errorf("couldn't obtain %q container pids: there is no pids in cgroup", containerName)
|
||||
}
|
||||
|
||||
// Firstly, find the control group to which the container belongs.
|
||||
// Consider the root group.
|
||||
controlGroupPath, err := findGroup(rootResctrl, pids, true, false)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%q %q: %q", noControlGroupFoundError, containerName, err)
|
||||
}
|
||||
if controlGroupPath == "" {
|
||||
return "", fmt.Errorf("%q %q", noControlGroupFoundError, containerName)
|
||||
}
|
||||
|
||||
// Check if there is any monitoring group.
|
||||
monGroupPath, err := findGroup(filepath.Join(controlGroupPath, monGroupsDirName), pids, false, true)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("couldn't find monitoring group matching %q container: %v", containerName, err)
|
||||
}
|
||||
|
||||
// Prepare new one if not exists.
|
||||
if monGroupPath == "" {
|
||||
// Remove leading prefix.
|
||||
// e.g. /my/container -> my/container
|
||||
if len(containerName) >= minContainerNameLen && containerName[0] == containerPrefix {
|
||||
containerName = containerName[1:]
|
||||
}
|
||||
|
||||
// Add own prefix and use `-` instead `/`.
|
||||
// e.g. my/container -> cadvisor-my-container
|
||||
properContainerName := fmt.Sprintf("%s-%s", monGroupPrefix, strings.Replace(containerName, "/", "-", -1))
|
||||
monGroupPath = filepath.Join(controlGroupPath, monitoringGroupDir, properContainerName)
|
||||
|
||||
err = os.MkdirAll(monGroupPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("couldn't create monitoring group directory for %q container: %w", containerName, err)
|
||||
}
|
||||
|
||||
if !inHostNamespace {
|
||||
processPath = "/rootfs/proc"
|
||||
}
|
||||
|
||||
for _, pid := range pids {
|
||||
processThreads, err := getAllProcessThreads(filepath.Join(processPath, pid, processTask))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, thread := range processThreads {
|
||||
err = intelrdt.WriteIntelRdtTasks(monGroupPath, thread)
|
||||
if err != nil {
|
||||
secondError := os.Remove(monGroupPath)
|
||||
if secondError != nil {
|
||||
return "", fmt.Errorf(
|
||||
"coudn't assign pids to %q container monitoring group: %w \n couldn't clear %q monitoring group: %v",
|
||||
containerName, err, containerName, secondError)
|
||||
}
|
||||
return "", fmt.Errorf("coudn't assign pids to %q container monitoring group: %w", containerName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return monGroupPath, nil
|
||||
}
|
||||
|
||||
func getPids(containerName string) ([]int, error) {
|
||||
if len(containerName) == 0 {
|
||||
// No container name passed.
|
||||
return nil, fmt.Errorf(noContainerNameError)
|
||||
}
|
||||
pids, err := cgroups.GetAllPids(filepath.Join(pidsPath, containerName))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't obtain pids for %q container: %v", containerName, err)
|
||||
}
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
// getAllProcessThreads obtains all available processes from directory.
|
||||
// e.g. ls /proc/4215/task/ -> 4215, 4216, 4217, 4218
|
||||
// func will return [4215, 4216, 4217, 4218].
|
||||
func getAllProcessThreads(path string) ([]int, error) {
|
||||
processThreads := make([]int, 0)
|
||||
|
||||
threadDirs, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return processThreads, err
|
||||
}
|
||||
|
||||
for _, dir := range threadDirs {
|
||||
pid, err := strconv.Atoi(dir.Name())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse %q dir: %v", dir.Name(), err)
|
||||
}
|
||||
processThreads = append(processThreads, pid)
|
||||
}
|
||||
|
||||
return processThreads, nil
|
||||
}
|
||||
|
||||
// findGroup returns the path of a control/monitoring group in which the pids are.
|
||||
func findGroup(group string, pids []string, includeGroup bool, exclusive bool) (string, error) {
|
||||
if len(pids) == 0 {
|
||||
return "", fmt.Errorf(noPidsPassedError)
|
||||
}
|
||||
|
||||
availablePaths := make([]string, 0)
|
||||
if includeGroup {
|
||||
availablePaths = append(availablePaths, group)
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(group)
|
||||
for _, file := range files {
|
||||
if _, ok := groupDirectories[file.Name()]; !ok {
|
||||
availablePaths = append(availablePaths, filepath.Join(group, file.Name()))
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("couldn't obtain groups paths: %w", err)
|
||||
}
|
||||
|
||||
for _, path := range availablePaths {
|
||||
groupFound, err := arePIDsInGroup(path, pids, exclusive)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if groupFound {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// arePIDsInGroup returns true if all of the pids are within control group.
|
||||
func arePIDsInGroup(path string, pids []string, exclusive bool) (bool, error) {
|
||||
if len(pids) == 0 {
|
||||
return false, fmt.Errorf("couldn't obtain pids from %q path: %v", path, noPidsPassedError)
|
||||
}
|
||||
|
||||
tasks, err := readTasksFile(filepath.Join(path, tasksFileName))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
any := false
|
||||
for _, pid := range pids {
|
||||
_, ok := tasks[pid]
|
||||
if !ok {
|
||||
// There are missing pids within group.
|
||||
if any {
|
||||
return false, fmt.Errorf("there should be all pids in group")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
any = true
|
||||
}
|
||||
|
||||
// Check if there should be only passed pids in group.
|
||||
if exclusive {
|
||||
if len(tasks) != len(pids) {
|
||||
return false, fmt.Errorf("group should have container pids only")
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// readTasksFile returns pids map from given tasks path.
|
||||
func readTasksFile(tasksPath string) (map[string]struct{}, error) {
|
||||
tasks := make(map[string]struct{})
|
||||
|
||||
tasksFile, err := os.Open(tasksPath)
|
||||
if err != nil {
|
||||
return tasks, fmt.Errorf("couldn't read tasks file from %q path: %w", tasksPath, err)
|
||||
}
|
||||
defer tasksFile.Close()
|
||||
|
||||
scanner := bufio.NewScanner(tasksFile)
|
||||
for scanner.Scan() {
|
||||
tasks[scanner.Text()] = struct{}{}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return tasks, fmt.Errorf("couldn't obtain pids from %q path: %w", tasksPath, err)
|
||||
}
|
||||
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
func readStatFrom(path string, vendorID string) (uint64, error) {
|
||||
context, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
contextString := string(bytes.TrimSpace(context))
|
||||
|
||||
if contextString == unavailable {
|
||||
err := fmt.Errorf("\"Unavailable\" value from file %q", path)
|
||||
if vendorID == "AuthenticAMD" {
|
||||
kernelBugzillaLink := "https://bugzilla.kernel.org/show_bug.cgi?id=213311"
|
||||
err = fmt.Errorf("%v, possible bug: %q", err, kernelBugzillaLink)
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
stat, err := strconv.ParseUint(contextString, 10, 64)
|
||||
if err != nil {
|
||||
return stat, fmt.Errorf("unable to parse %q as a uint from file %q", string(context), path)
|
||||
}
|
||||
|
||||
return stat, nil
|
||||
}
|
||||
|
||||
func getIntelRDTStatsFrom(path string, vendorID string) (intelrdt.Stats, error) {
|
||||
stats := intelrdt.Stats{}
|
||||
|
||||
statsDirectories, err := filepath.Glob(filepath.Join(path, monDataDirName, "*"))
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
|
||||
if len(statsDirectories) == 0 {
|
||||
return stats, fmt.Errorf("there is no mon_data stats directories: %q", path)
|
||||
}
|
||||
|
||||
var cmtStats []intelrdt.CMTNumaNodeStats
|
||||
var mbmStats []intelrdt.MBMNumaNodeStats
|
||||
|
||||
for _, dir := range statsDirectories {
|
||||
if enabledCMT {
|
||||
llcOccupancy, err := readStatFrom(filepath.Join(dir, llcOccupancyFileName), vendorID)
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
cmtStats = append(cmtStats, intelrdt.CMTNumaNodeStats{LLCOccupancy: llcOccupancy})
|
||||
}
|
||||
if enabledMBM {
|
||||
mbmTotalBytes, err := readStatFrom(filepath.Join(dir, mbmTotalBytesFileName), vendorID)
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
mbmLocalBytes, err := readStatFrom(filepath.Join(dir, mbmLocalBytesFileName), vendorID)
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
mbmStats = append(mbmStats, intelrdt.MBMNumaNodeStats{
|
||||
MBMTotalBytes: mbmTotalBytes,
|
||||
MBMLocalBytes: mbmLocalBytes,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
stats.CMTStats = &cmtStats
|
||||
stats.MBMStats = &mbmStats
|
||||
|
||||
return stats, nil
|
||||
}
|
3
vendor/github.com/google/cadvisor/stats/noop.go
generated
vendored
3
vendor/github.com/google/cadvisor/stats/noop.go
generated
vendored
@ -16,8 +16,9 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type NoopManager struct {
|
||||
|
2
vendor/github.com/google/cadvisor/summary/summary.go
generated
vendored
2
vendor/github.com/google/cadvisor/summary/summary.go
generated
vendored
@ -25,7 +25,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
v1 "github.com/google/cadvisor/info/v1"
|
||||
info "github.com/google/cadvisor/info/v2"
|
||||
)
|
||||
|
||||
|
3
vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
generated
vendored
3
vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
generated
vendored
@ -17,8 +17,9 @@
|
||||
package cloudinfo
|
||||
|
||||
import (
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
type CloudInfo interface {
|
||||
|
3
vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go
generated
vendored
3
vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go
generated
vendored
@ -19,8 +19,9 @@ import (
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
|
||||
"github.com/google/cadvisor/utils/cpuload/netlink"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/google/cadvisor/utils/cpuload/netlink"
|
||||
)
|
||||
|
||||
type CpuLoadReader interface {
|
||||
|
3
vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go
generated
vendored
3
vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go
generated
vendored
@ -21,8 +21,9 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
|
21
vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
generated
vendored
21
vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
generated
vendored
@ -64,6 +64,8 @@ var (
|
||||
)
|
||||
|
||||
type CacheInfo struct {
|
||||
// cache id
|
||||
Id int
|
||||
// size in bytes
|
||||
Size uint64
|
||||
// cache type - instruction, data, unified
|
||||
@ -292,14 +294,24 @@ func getCPUCount(cache string) (count int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (fs *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) {
|
||||
cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, id, name)
|
||||
out, err := ioutil.ReadFile(path.Join(cachePath, "/size"))
|
||||
func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
|
||||
cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, cpu, name)
|
||||
out, err := ioutil.ReadFile(path.Join(cachePath, "/id"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
var id int
|
||||
n, err := fmt.Sscanf(string(out), "%d", &id)
|
||||
if err != nil || n != 1 {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
|
||||
out, err = ioutil.ReadFile(path.Join(cachePath, "/size"))
|
||||
if err != nil {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
var size uint64
|
||||
n, err := fmt.Sscanf(string(out), "%dK", &size)
|
||||
n, err = fmt.Sscanf(string(out), "%dK", &size)
|
||||
if err != nil || n != 1 {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
@ -325,6 +337,7 @@ func (fs *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) {
|
||||
return CacheInfo{}, err
|
||||
}
|
||||
return CacheInfo{
|
||||
Id: id,
|
||||
Size: size,
|
||||
Level: level,
|
||||
Type: cacheType,
|
||||
|
1
vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go
generated
vendored
1
vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !x86
|
||||
// +build !x86
|
||||
|
||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||
|
1
vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go
generated
vendored
1
vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build x86
|
||||
// +build x86
|
||||
|
||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||
|
18
vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
generated
vendored
18
vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
generated
vendored
@ -332,12 +332,14 @@ func addCacheInfo(sysFs sysfs.SysFs, node *info.Node) error {
|
||||
|
||||
for _, cache := range caches {
|
||||
c := info.Cache{
|
||||
Id: cache.Id,
|
||||
Size: cache.Size,
|
||||
Level: cache.Level,
|
||||
Type: cache.Type,
|
||||
}
|
||||
if cache.Cpus == numThreadsPerNode && cache.Level > cacheLevel2 {
|
||||
// Add a node-level cache.
|
||||
if cache.Level > cacheLevel2 {
|
||||
if cache.Cpus == numThreadsPerNode {
|
||||
// Add a node level cache.
|
||||
cacheFound := false
|
||||
for _, nodeCache := range node.Caches {
|
||||
if nodeCache == c {
|
||||
@ -347,6 +349,18 @@ func addCacheInfo(sysFs sysfs.SysFs, node *info.Node) error {
|
||||
if !cacheFound {
|
||||
node.Caches = append(node.Caches, c)
|
||||
}
|
||||
} else {
|
||||
// Add uncore cache, for architecture in which l3 cache only shared among some cores.
|
||||
uncoreCacheFound := false
|
||||
for _, uncoreCache := range node.Cores[coreID].UncoreCaches {
|
||||
if uncoreCache == c {
|
||||
uncoreCacheFound = true
|
||||
}
|
||||
}
|
||||
if !uncoreCacheFound {
|
||||
node.Cores[coreID].UncoreCaches = append(node.Cores[coreID].UncoreCaches, c)
|
||||
}
|
||||
}
|
||||
} else if cache.Cpus == numThreadsPerCore {
|
||||
// Add core level cache
|
||||
node.Cores[coreID].Caches = append(node.Cores[coreID].Caches, c)
|
||||
|
22
vendor/modules.txt
vendored
22
vendor/modules.txt
vendored
@ -179,18 +179,14 @@ github.com/container-storage-interface/spec/lib/go/csi
|
||||
github.com/containerd/cgroups/stats/v1
|
||||
# github.com/containerd/console v1.0.2 => github.com/containerd/console v1.0.2
|
||||
github.com/containerd/console
|
||||
# github.com/containerd/containerd v1.4.9 => github.com/containerd/containerd v1.4.9
|
||||
# github.com/containerd/containerd v1.4.11 => github.com/containerd/containerd v1.4.11
|
||||
github.com/containerd/containerd/api/services/containers/v1
|
||||
github.com/containerd/containerd/api/services/tasks/v1
|
||||
github.com/containerd/containerd/api/services/version/v1
|
||||
github.com/containerd/containerd/api/types
|
||||
github.com/containerd/containerd/api/types/task
|
||||
github.com/containerd/containerd/containers
|
||||
github.com/containerd/containerd/errdefs
|
||||
github.com/containerd/containerd/identifiers
|
||||
github.com/containerd/containerd/log
|
||||
github.com/containerd/containerd/namespaces
|
||||
github.com/containerd/containerd/pkg/dialer
|
||||
github.com/containerd/containerd/platforms
|
||||
# github.com/containerd/ttrpc v1.0.2 => github.com/containerd/ttrpc v1.0.2
|
||||
github.com/containerd/ttrpc
|
||||
@ -236,7 +232,7 @@ github.com/daviddengcn/go-colortext
|
||||
github.com/docker/distribution/digestset
|
||||
github.com/docker/distribution/reference
|
||||
github.com/docker/distribution/registry/api/errcode
|
||||
# github.com/docker/docker v20.10.2+incompatible => github.com/docker/docker v20.10.2+incompatible
|
||||
# github.com/docker/docker v20.10.7+incompatible => github.com/docker/docker v20.10.7+incompatible
|
||||
## explicit
|
||||
github.com/docker/docker/api
|
||||
github.com/docker/docker/api/types
|
||||
@ -362,7 +358,7 @@ github.com/golang/protobuf/ptypes/timestamp
|
||||
github.com/golang/protobuf/ptypes/wrappers
|
||||
# github.com/google/btree v1.0.1 => github.com/google/btree v1.0.1
|
||||
github.com/google/btree
|
||||
# github.com/google/cadvisor v0.39.2 => github.com/google/cadvisor v0.39.2
|
||||
# github.com/google/cadvisor v0.43.0 => github.com/google/cadvisor v0.43.0
|
||||
## explicit
|
||||
github.com/google/cadvisor/accelerators
|
||||
github.com/google/cadvisor/cache/memory
|
||||
@ -371,7 +367,12 @@ github.com/google/cadvisor/collector
|
||||
github.com/google/cadvisor/container
|
||||
github.com/google/cadvisor/container/common
|
||||
github.com/google/cadvisor/container/containerd
|
||||
github.com/google/cadvisor/container/containerd/containers
|
||||
github.com/google/cadvisor/container/containerd/errdefs
|
||||
github.com/google/cadvisor/container/containerd/identifiers
|
||||
github.com/google/cadvisor/container/containerd/install
|
||||
github.com/google/cadvisor/container/containerd/namespaces
|
||||
github.com/google/cadvisor/container/containerd/pkg/dialer
|
||||
github.com/google/cadvisor/container/crio
|
||||
github.com/google/cadvisor/container/crio/install
|
||||
github.com/google/cadvisor/container/docker
|
||||
@ -733,6 +734,7 @@ github.com/tmc/grpc-websocket-proxy/wsproxy
|
||||
github.com/vishvananda/netlink
|
||||
github.com/vishvananda/netlink/nl
|
||||
# github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae => github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
|
||||
## explicit
|
||||
github.com/vishvananda/netns
|
||||
# github.com/vmware/govmomi v0.20.3 => github.com/vmware/govmomi v0.20.3
|
||||
## explicit
|
||||
@ -2474,7 +2476,7 @@ sigs.k8s.io/yaml
|
||||
# github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.5.0
|
||||
# github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1
|
||||
# github.com/containerd/console => github.com/containerd/console v1.0.2
|
||||
# github.com/containerd/containerd => github.com/containerd/containerd v1.4.9
|
||||
# github.com/containerd/containerd => github.com/containerd/containerd v1.4.11
|
||||
# github.com/containerd/continuity => github.com/containerd/continuity v0.1.0
|
||||
# github.com/containerd/fifo => github.com/containerd/fifo v1.0.0
|
||||
# github.com/containerd/go-runc => github.com/containerd/go-runc v1.0.0
|
||||
@ -2493,7 +2495,7 @@ sigs.k8s.io/yaml
|
||||
# github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd
|
||||
# github.com/dnaeon/go-vcr => github.com/dnaeon/go-vcr v1.0.1
|
||||
# github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
|
||||
# github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible
|
||||
# github.com/docker/docker => github.com/docker/docker v20.10.7+incompatible
|
||||
# github.com/docker/go-connections => github.com/docker/go-connections v0.4.0
|
||||
# github.com/docker/go-units => github.com/docker/go-units v0.4.0
|
||||
# github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
@ -2538,7 +2540,7 @@ sigs.k8s.io/yaml
|
||||
# github.com/golang/protobuf => github.com/golang/protobuf v1.5.2
|
||||
# github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e
|
||||
# github.com/google/btree => github.com/google/btree v1.0.1
|
||||
# github.com/google/cadvisor => github.com/google/cadvisor v0.39.2
|
||||
# github.com/google/cadvisor => github.com/google/cadvisor v0.43.0
|
||||
# github.com/google/go-cmp => github.com/google/go-cmp v0.5.5
|
||||
# github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
|
||||
# github.com/google/martian/v3 => github.com/google/martian/v3 v3.1.0
|
||||
|
Loading…
Reference in New Issue
Block a user