diff --git a/go.mod b/go.mod
index 10e370e..fce3093 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/common v0.69.0
github.com/prometheus/exporter-toolkit v0.16.0
- github.com/prometheus/procfs v0.20.1
+ github.com/prometheus/procfs v0.21.1
github.com/stretchr/testify v1.11.1
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc
golang.org/x/sys v0.46.0
@@ -44,7 +44,7 @@ require (
golang.org/x/crypto v0.51.0 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
- golang.org/x/sync v0.20.0 // indirect
+ golang.org/x/sync v0.21.0 // indirect
golang.org/x/text v0.37.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
diff --git a/go.sum b/go.sum
index e1401bf..aaa7b91 100644
--- a/go.sum
+++ b/go.sum
@@ -62,8 +62,8 @@ github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85Cu
github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y=
github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s=
github.com/prometheus/exporter-toolkit v0.16.0/go.mod h1:d1EL8Z9674xQe/iWhwP2wDyCEoBPbXVeqDbqAUsgJWY=
-github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
-github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
+github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
+github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 h1:GfSdC6wKfTGcgCS7BtzF5694Amne1pGCSTY252WhlEY=
@@ -96,8 +96,8 @@ golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
-golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
-golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
+golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common
index cce3ef1..a7c5f55 100644
--- a/vendor/github.com/prometheus/procfs/Makefile.common
+++ b/vendor/github.com/prometheus/procfs/Makefile.common
@@ -55,13 +55,13 @@ ifneq ($(shell command -v gotestsum 2> /dev/null),)
endif
endif
-PROMU_VERSION ?= 0.18.0
+PROMU_VERSION ?= 0.20.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?=
-GOLANGCI_LINT_VERSION ?= v2.10.1
+GOLANGCI_LINT_VERSION ?= v2.11.4
GOLANGCI_FMT_OPTS ?=
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different.
@@ -90,8 +90,8 @@ ifdef DOCKERFILE_PATH
$(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile)
endif
-DOCKER_ARCHS ?= amd64
-DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*)
+DOCKER_ARCHS ?= amd64 arm64 armv7 ppc64le riscv64 s390x
+DOCKERFILE_VARIANTS ?= $(wildcard Dockerfile Dockerfile.*)
# Function to extract variant from Dockerfile label.
# Returns the variant name from io.prometheus.image.variant label, or "default" if not found.
@@ -109,24 +109,6 @@ endif
# Build variant:dockerfile pairs for shell iteration.
DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df))
-# Shell helper to check whether a dockerfile/arch pair is excluded.
-define dockerfile_arch_is_excluded
-case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \
- *" $$dockerfile:$(1) "*) true ;; \
- *) false ;; \
-esac
-endef
-
-# Shell helper to check whether a registry/arch pair is excluded.
-# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io)
-define registry_arch_is_excluded
-registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \
-case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \
- *" $$registry:$(1) "*) true ;; \
- *) false ;; \
-esac
-endef
-
BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS))
@@ -268,10 +250,6 @@ $(BUILD_DOCKER_ARCHS): common-docker-%:
@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
dockerfile=$${variant#*:}; \
variant_name=$${variant%%:*}; \
- if $(call dockerfile_arch_is_excluded,$*); then \
- echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
distroless_arch="$*"; \
if [ "$*" = "armv7" ]; then \
distroless_arch="arm"; \
@@ -306,14 +284,6 @@ $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
dockerfile=$${variant#*:}; \
variant_name=$${variant%%:*}; \
- if $(call dockerfile_arch_is_excluded,$*); then \
- echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$*); then \
- echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
echo "Pushing $$variant_name variant for linux-$*"; \
docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
@@ -341,14 +311,6 @@ $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
@for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
dockerfile=$${variant#*:}; \
variant_name=$${variant%%:*}; \
- if $(call dockerfile_arch_is_excluded,$*); then \
- echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$*); then \
- echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
echo "Tagging $$variant_name variant for linux-$* as latest"; \
docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \
@@ -370,14 +332,6 @@ common-docker-manifest:
echo "Creating manifest for $$variant_name variant"; \
refs=""; \
for arch in $(DOCKER_ARCHS); do \
- if $(call dockerfile_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
done; \
if [ -z "$$refs" ]; then \
@@ -391,14 +345,6 @@ common-docker-manifest:
echo "Creating default variant ($$variant_name) manifest"; \
refs=""; \
for arch in $(DOCKER_ARCHS); do \
- if $(call dockerfile_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
done; \
if [ -z "$$refs" ]; then \
@@ -413,14 +359,6 @@ common-docker-manifest:
echo "Creating manifest for $$variant_name variant version tag"; \
refs=""; \
for arch in $(DOCKER_ARCHS); do \
- if $(call dockerfile_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
done; \
if [ -z "$$refs" ]; then \
@@ -434,14 +372,6 @@ common-docker-manifest:
echo "Creating default variant version tag manifest"; \
refs=""; \
for arch in $(DOCKER_ARCHS); do \
- if $(call dockerfile_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
- if $(call registry_arch_is_excluded,$$arch); then \
- echo " Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
- continue; \
- fi; \
refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \
done; \
if [ -z "$$refs" ]; then \
@@ -495,9 +425,3 @@ $(1)_precheck:
exit 1; \
fi
endef
-
-govulncheck: install-govulncheck
- govulncheck ./...
-
-install-govulncheck:
- command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest
diff --git a/vendor/github.com/prometheus/procfs/README.md b/vendor/github.com/prometheus/procfs/README.md
index 0718239..3635240 100644
--- a/vendor/github.com/prometheus/procfs/README.md
+++ b/vendor/github.com/prometheus/procfs/README.md
@@ -7,7 +7,7 @@ metrics from the pseudo-filesystems /proc and /sys.
backwards-incompatible ways without warnings. Use it at your own risk.
[](https://pkg.go.dev/github.com/prometheus/procfs)
-[](https://circleci.com/gh/prometheus/procfs/tree/master)
+[](https://github.com/prometheus/procfs/actions/workflows/ci.yml)
[](https://goreportcard.com/report/github.com/prometheus/procfs)
## Usage
diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md
index fed02d8..5e6f976 100644
--- a/vendor/github.com/prometheus/procfs/SECURITY.md
+++ b/vendor/github.com/prometheus/procfs/SECURITY.md
@@ -3,4 +3,4 @@
The Prometheus security policy, including how to report vulnerabilities, can be
found here:
-
+[https://prometheus.io/docs/operating/security/](https://prometheus.io/docs/operating/security/)
diff --git a/vendor/github.com/prometheus/procfs/crypto.go b/vendor/github.com/prometheus/procfs/crypto.go
index e4a5876..d93b712 100644
--- a/vendor/github.com/prometheus/procfs/crypto.go
+++ b/vendor/github.com/prometheus/procfs/crypto.go
@@ -48,11 +48,13 @@ type Crypto struct {
Walksize *uint64
}
+var cryptoFile = "crypto"
+
// Crypto parses an crypto-file (/proc/crypto) and returns a slice of
// structs containing the relevant info. More information available here:
// https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html
func (fs FS) Crypto() ([]Crypto, error) {
- path := fs.proc.Path("crypto")
+ path := fs.proc.Path(cryptoFile)
b, err := util.ReadFileNoStat(path)
if err != nil {
return nil, fmt.Errorf("%w: Cannot read file %v: %w", ErrFileRead, b, err)
@@ -82,6 +84,10 @@ func parseCrypto(r io.Reader) ([]Crypto, error) {
continue
}
+ if len(out) == 0 {
+ return nil, fmt.Errorf("%w: parsed invalid line before name parsed: %q", ErrFileParse, text)
+ }
+
kv := strings.Split(text, ":")
if len(kv) != 2 {
return nil, fmt.Errorf("%w: Cannot parse line: %q", ErrFileParse, text)
diff --git a/vendor/github.com/prometheus/procfs/mountinfo.go b/vendor/github.com/prometheus/procfs/mountinfo.go
index 9414a12..8594ae7 100644
--- a/vendor/github.com/prometheus/procfs/mountinfo.go
+++ b/vendor/github.com/prometheus/procfs/mountinfo.go
@@ -17,10 +17,10 @@ import (
"bufio"
"bytes"
"fmt"
+ "io"
+ "os"
"strconv"
"strings"
-
- "github.com/prometheus/procfs/internal/util"
)
// A MountInfo is a type that describes the details, options
@@ -160,9 +160,19 @@ func mountOptionsParser(mountOptions string) map[string]string {
return opts
}
+// readMountInfo reads a full mountinfo file (no 1 MiB cap, unlike util.ReadFileNoStat).
+func readMountInfo(path string) ([]byte, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return io.ReadAll(f)
+}
+
// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
func GetMounts() ([]*MountInfo, error) {
- data, err := util.ReadFileNoStat("/proc/self/mountinfo")
+ data, err := readMountInfo("/proc/self/mountinfo")
if err != nil {
return nil, err
}
@@ -171,7 +181,7 @@ func GetMounts() ([]*MountInfo, error) {
// GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`.
func GetProcMounts(pid int) ([]*MountInfo, error) {
- data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid))
+ data, err := readMountInfo(fmt.Sprintf("/proc/%d/mountinfo", pid))
if err != nil {
return nil, err
}
@@ -180,7 +190,7 @@ func GetProcMounts(pid int) ([]*MountInfo, error) {
// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
func (fs FS) GetMounts() ([]*MountInfo, error) {
- data, err := util.ReadFileNoStat(fs.proc.Path("self/mountinfo"))
+ data, err := readMountInfo(fs.proc.Path("self/mountinfo"))
if err != nil {
return nil, err
}
@@ -189,7 +199,7 @@ func (fs FS) GetMounts() ([]*MountInfo, error) {
// GetProcMounts retrieves mountinfo information from a processes' `/proc//mountinfo`.
func (fs FS) GetProcMounts(pid int) ([]*MountInfo, error) {
- data, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid)))
+ data, err := readMountInfo(fs.proc.Path(fmt.Sprintf("%d/mountinfo", pid)))
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/prometheus/procfs/net_wireless.go b/vendor/github.com/prometheus/procfs/net_wireless.go
index 69d0794..f74dd3b 100644
--- a/vendor/github.com/prometheus/procfs/net_wireless.go
+++ b/vendor/github.com/prometheus/procfs/net_wireless.go
@@ -114,47 +114,47 @@ func parseWireless(r io.Reader) ([]*Wireless, error) {
qlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], "."))
if err != nil {
- return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, qlink, err)
+ return nil, fmt.Errorf("%w: parse Quality:link as integer %q: %w", ErrFileParse, stats[1], err)
}
qlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], "."))
if err != nil {
- return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, qlevel, err)
+ return nil, fmt.Errorf("%w: Quality:level as integer %q: %w", ErrFileParse, stats[2], err)
}
qnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], "."))
if err != nil {
- return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, qnoise, err)
+ return nil, fmt.Errorf("%w: Quality:noise as integer %q: %w", ErrFileParse, stats[3], err)
}
dnwid, err := strconv.Atoi(stats[4])
if err != nil {
- return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, dnwid, err)
+ return nil, fmt.Errorf("%w: Discarded:nwid as integer %q: %w", ErrFileParse, stats[4], err)
}
dcrypt, err := strconv.Atoi(stats[5])
if err != nil {
- return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, dcrypt, err)
+ return nil, fmt.Errorf("%w: Discarded:crypt as integer %q: %w", ErrFileParse, stats[5], err)
}
dfrag, err := strconv.Atoi(stats[6])
if err != nil {
- return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, dfrag, err)
+ return nil, fmt.Errorf("%w: Discarded:frag as integer %q: %w", ErrFileParse, stats[6], err)
}
dretry, err := strconv.Atoi(stats[7])
if err != nil {
- return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, dretry, err)
+ return nil, fmt.Errorf("%w: Discarded:retry as integer %q: %w", ErrFileParse, stats[7], err)
}
dmisc, err := strconv.Atoi(stats[8])
if err != nil {
- return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, dmisc, err)
+ return nil, fmt.Errorf("%w: Discarded:misc as integer %q: %w", ErrFileParse, stats[8], err)
}
mbeacon, err := strconv.Atoi(stats[9])
if err != nil {
- return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, mbeacon, err)
+ return nil, fmt.Errorf("%w: Missed:beacon as integer %q: %w", ErrFileParse, stats[9], err)
}
w := &Wireless{
diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go
index 535c08d..7e8a122 100644
--- a/vendor/github.com/prometheus/procfs/proc_cgroup.go
+++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go
@@ -60,7 +60,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) {
}
cgroup.HierarchyID, err = strconv.Atoi(fields[0])
if err != nil {
- return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, cgroup.HierarchyID)
+ return nil, fmt.Errorf("%w: hierarchy ID: %q", ErrFileParse, fields[0])
}
if fields[1] != "" {
ssNames := strings.Split(fields[1], ",")
diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go b/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go
index 7b46e02..a7844f1 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/class_fibrechannel.go
@@ -154,6 +154,9 @@ func parseFibreChannelStatistics(hostPath string) (*FibreChannelCounters, error)
path := filepath.Join(hostPath, "statistics")
files, err := os.ReadDir(path)
if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ return &counters, nil
+ }
return nil, err
}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_mei.go b/vendor/github.com/prometheus/procfs/sysfs/class_mei.go
new file mode 100644
index 0000000..93eee22
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/sysfs/class_mei.go
@@ -0,0 +1,117 @@
+// Copyright The Prometheus 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.
+
+//go:build linux
+
+package sysfs
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/prometheus/procfs/internal/util"
+)
+
+const meiClassPath = "class/mei"
+
+type MEIDev struct {
+ Dev *string
+ DevState *string
+ FWStatus *string
+ FWVersion *string
+ HBMVersion *string
+ HBMVersionDrv *string
+ Kind *string
+ Trc *string
+ TxQueueLimit *string
+}
+
+type MEIClass map[string]MEIDev
+
+// MEIClass returns Management Engine Interface (MEI) information read from /sys/class/mei/.
+func (fs FS) MEIClass() (*MEIClass, error) {
+ path := fs.sys.Path(meiClassPath)
+
+ subdirs, err := os.ReadDir(path)
+ if err != nil {
+ return nil, fmt.Errorf("failed to list MEI devices at %q: %w", path, err)
+ }
+
+ mei := make(MEIClass, len(subdirs))
+ for _, d := range subdirs {
+ dev, err := fs.parseMEI(d.Name())
+ if err != nil {
+ return nil, err
+ }
+
+ mei[d.Name()] = dev
+ }
+
+ return &mei, nil
+}
+
+func (fs FS) parseMEI(meiDev string) (MEIDev, error) {
+ path := fs.sys.Path(meiClassPath, meiDev)
+
+ var mei MEIDev
+
+ files, err := os.ReadDir(path)
+ if err != nil {
+ return mei, fmt.Errorf("failed to read directory %q: %w", path, err)
+ }
+
+ for _, f := range files {
+ if !f.Type().IsRegular() {
+ continue
+ }
+
+ name := f.Name()
+ if name == "uevent" {
+ continue
+ }
+
+ filename := filepath.Join(path, name)
+ value, err := util.SysReadFile(filename)
+ if err != nil {
+ if os.IsPermission(err) {
+ continue
+ }
+
+ return mei, fmt.Errorf("failed to read file %q: %w", filename, err)
+ }
+
+ switch name {
+ case "dev":
+ mei.Dev = &value
+ case "dev_state":
+ mei.DevState = &value
+ case "fw_status":
+ mei.FWStatus = &value
+ case "fw_ver":
+ mei.FWVersion = &value
+ case "hbm_ver":
+ mei.HBMVersion = &value
+ case "hbm_ver_drv":
+ mei.HBMVersionDrv = &value
+ case "kind":
+ mei.Kind = &value
+ case "trc":
+ mei.Trc = &value
+ case "tx_queue_limit":
+ mei.TxQueueLimit = &value
+ }
+ }
+
+ return mei, nil
+}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go b/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go
index 7c4abb0..7c3638a 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/class_nvme.go
@@ -27,7 +27,7 @@ import (
const nvmeClassPath = "class/nvme"
-var nvmeNamespacePattern = regexp.MustCompile(`nvme\d+c\d+n(\d+)`)
+var nvmeNamespacePattern = regexp.MustCompile(`nvme\d+n(\d+)`)
// NVMeNamespace contains info from files in /sys/class/nvme//.
type NVMeNamespace struct {
diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go b/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go
new file mode 100644
index 0000000..c222609
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/sysfs/class_nvme_subsystem.go
@@ -0,0 +1,158 @@
+// Copyright The Prometheus 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.
+
+//go:build linux
+
+package sysfs
+
+import (
+ "fmt"
+ "os"
+ "regexp"
+ "strings"
+
+ "github.com/prometheus/procfs/internal/util"
+)
+
+const nvmeSubsystemClassPath = "class/nvme-subsystem"
+
+var (
+ nvmeSubsystemControllerRE = regexp.MustCompile(`^nvme\d+$`)
+ nvmeNamespaceRE = regexp.MustCompile(`^nvme\d+n\d+$`)
+)
+
+// NVMeSubsystem contains info from /sys/class/nvme-subsystem//.
+type NVMeSubsystem struct {
+ // Name is the subsystem directory name, e.g. "nvme-subsys0".
+ Name string
+ // NQN is the NVMe Qualified Name from subsysnqn.
+ NQN string
+ // Model is the subsystem model string.
+ Model string
+ // Serial is the subsystem serial number.
+ Serial string
+ // IOPolicy is the multipath I/O policy, e.g. "numa", "round-robin".
+ IOPolicy string
+ // Controllers lists the NVMe controllers under this subsystem.
+ Controllers []NVMeSubsystemController
+ // Namespaces lists the NVMe namespace block devices (e.g. "nvme0n1")
+ // that belong to this subsystem.
+ Namespaces []string
+}
+
+// NVMeSubsystemController contains info about a single NVMe controller
+// within an NVMe subsystem.
+type NVMeSubsystemController struct {
+ // Name is the controller directory name, e.g. "nvme0".
+ Name string
+ // State is the controller state, e.g. "live", "connecting", "dead".
+ State string
+ // Transport is the transport type, e.g. "tcp", "fc", "rdma".
+ Transport string
+ // Address is the controller address string.
+ Address string
+}
+
+// NVMeSubsystemClass is a collection of NVMe subsystems from
+// /sys/class/nvme-subsystem.
+type NVMeSubsystemClass []NVMeSubsystem
+
+// NVMeSubsystemClass returns info for all NVMe subsystems read from
+// /sys/class/nvme-subsystem.
+func (fs FS) NVMeSubsystemClass() (NVMeSubsystemClass, error) {
+ path := fs.sys.Path(nvmeSubsystemClassPath)
+
+ entries, err := os.ReadDir(path)
+ if err != nil {
+ return nil, err
+ }
+
+ var subsystems NVMeSubsystemClass
+ for _, entry := range entries {
+ if !strings.HasPrefix(entry.Name(), "nvme-subsys") {
+ continue
+ }
+ subsys, err := fs.parseNVMeSubsystem(entry.Name())
+ if err != nil {
+ return nil, err
+ }
+ subsystems = append(subsystems, *subsys)
+ }
+
+ return subsystems, nil
+}
+
+func (fs FS) parseNVMeSubsystem(name string) (*NVMeSubsystem, error) {
+ path := fs.sys.Path(nvmeSubsystemClassPath, name)
+ subsys := &NVMeSubsystem{Name: name}
+
+ for _, attr := range [...]struct {
+ file string
+ dest *string
+ }{
+ {"subsysnqn", &subsys.NQN},
+ {"model", &subsys.Model},
+ {"serial", &subsys.Serial},
+ {"iopolicy", &subsys.IOPolicy},
+ } {
+ val, err := util.SysReadFile(fs.sys.Path(nvmeSubsystemClassPath, name, attr.file))
+ if err != nil {
+ return nil, fmt.Errorf("failed to read %s for %s: %w", attr.file, name, err)
+ }
+ *attr.dest = val
+ }
+
+ entries, err := os.ReadDir(path)
+ if err != nil {
+ return nil, fmt.Errorf("failed to list controllers for %s: %w", name, err)
+ }
+
+ seen := make(map[string]bool)
+ for _, entry := range entries {
+ eName := entry.Name()
+ if nvmeSubsystemControllerRE.MatchString(eName) {
+ ctrl, err := fs.parseNVMeSubsystemController(name, eName)
+ if err != nil {
+ return nil, err
+ }
+ subsys.Controllers = append(subsys.Controllers, *ctrl)
+ }
+ if nvmeNamespaceRE.MatchString(eName) && !seen[eName] {
+ seen[eName] = true
+ subsys.Namespaces = append(subsys.Namespaces, eName)
+ }
+ }
+
+ return subsys, nil
+}
+
+func (fs FS) parseNVMeSubsystemController(subsysName, ctrlName string) (*NVMeSubsystemController, error) {
+ ctrl := &NVMeSubsystemController{Name: ctrlName}
+
+ for _, attr := range [...]struct {
+ file string
+ dest *string
+ }{
+ {"state", &ctrl.State},
+ {"transport", &ctrl.Transport},
+ {"address", &ctrl.Address},
+ } {
+ val, err := util.SysReadFile(fs.sys.Path(nvmeSubsystemClassPath, subsysName, ctrlName, attr.file))
+ if err != nil {
+ return nil, fmt.Errorf("failed to read %s for %s/%s: %w", attr.file, subsysName, ctrlName, err)
+ }
+ *attr.dest = val
+ }
+
+ return ctrl, nil
+}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go b/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go
index db83286..8372f13 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/class_thermal.go
@@ -17,12 +17,10 @@ package sysfs
import (
"errors"
+ "fmt"
"os"
"path/filepath"
"strings"
- "syscall"
-
- fsp "io/fs"
"github.com/prometheus/procfs/internal/util"
)
@@ -37,6 +35,9 @@ type ClassThermalZoneStats struct {
Policy string // One of the various thermal governors used for a particular zone.
Mode *bool // Optional: One of the predefined values in [enabled, disabled].
Passive *uint64 // Optional: millidegrees Celsius. (0 for disabled, > 1000 for enabled+value)
+
+ // ReadError contains any errors returned when gathering data.
+ ReadErrors error
}
// ClassThermalZoneStats returns Thermal Zone metrics for all zones.
@@ -48,39 +49,33 @@ func (fs FS) ClassThermalZoneStats() ([]ClassThermalZoneStats, error) {
stats := make([]ClassThermalZoneStats, 0, len(zones))
for _, zone := range zones {
- zoneStats, err := parseClassThermalZone(zone)
- if err != nil {
- if errors.Is(err, syscall.ENODATA) || errors.As(err, new(*fsp.PathError)) || errors.Is(err, syscall.EAGAIN) ||
- errors.Is(err, syscall.EINVAL) {
- continue
- }
- return nil, err
- }
+ zoneStats := parseClassThermalZone(zone)
zoneStats.Name = strings.TrimPrefix(filepath.Base(zone), "thermal_zone")
stats = append(stats, zoneStats)
}
return stats, nil
}
-func parseClassThermalZone(zone string) (ClassThermalZoneStats, error) {
+func parseClassThermalZone(zone string) ClassThermalZoneStats {
+ var errs []error
// Required attributes.
zoneType, err := util.SysReadFile(filepath.Join(zone, "type"))
if err != nil {
- return ClassThermalZoneStats{}, err
+ errs = append(errs, fmt.Errorf("error reading type: %w", err))
}
zonePolicy, err := util.SysReadFile(filepath.Join(zone, "policy"))
if err != nil {
- return ClassThermalZoneStats{}, err
+ errs = append(errs, fmt.Errorf("error reading policy: %w", err))
}
zoneTemp, err := util.SysReadIntFromFile(filepath.Join(zone, "temp"))
- if err != nil {
- return ClassThermalZoneStats{}, err
+ if err != nil && !errors.Is(err, os.ErrInvalid) {
+ errs = append(errs, fmt.Errorf("error reading temp: %w", err))
}
// Optional attributes.
mode, err := util.SysReadFile(filepath.Join(zone, "mode"))
if err != nil && !os.IsNotExist(err) && !os.IsPermission(err) {
- return ClassThermalZoneStats{}, err
+ errs = append(errs, fmt.Errorf("error reading mode: %w", err))
}
zoneMode := util.ParseBool(mode)
@@ -90,16 +85,17 @@ func parseClassThermalZone(zone string) (ClassThermalZoneStats, error) {
case os.IsNotExist(err), os.IsPermission(err):
zonePassive = nil
case err != nil:
- return ClassThermalZoneStats{}, err
+ errs = append(errs, fmt.Errorf("error reading passive: %w", err))
default:
zonePassive = &passive
}
return ClassThermalZoneStats{
- Type: zoneType,
- Policy: zonePolicy,
- Temp: zoneTemp,
- Mode: zoneMode,
- Passive: zonePassive,
- }, nil
+ Type: zoneType,
+ Policy: zonePolicy,
+ Temp: zoneTemp,
+ Mode: zoneMode,
+ Passive: zonePassive,
+ ReadErrors: errors.Join(errs...),
+ }
}
diff --git a/vendor/github.com/prometheus/procfs/sysfs/mdraid.go b/vendor/github.com/prometheus/procfs/sysfs/mdraid.go
index 139c7eb..d706d21 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/mdraid.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/mdraid.go
@@ -17,7 +17,9 @@ package sysfs
import (
"fmt"
+ "os"
"path/filepath"
+ "strconv"
"strings"
"github.com/prometheus/procfs/internal/util"
@@ -26,10 +28,10 @@ import (
// Mdraid holds info parsed from relevant files in the /sys/block/md*/md directory.
type Mdraid struct {
Device string // Kernel device name of array.
- Level string // mdraid level.
+ Level string // mdraid level. Empty if level file is unreadable.
ArrayState string // State of the array.
MetadataVersion string // mdraid metadata version.
- Disks uint64 // Number of devices in a fully functional array.
+ Disks *uint64 // Number of devices in a fully functional array. Nil when unavailable (e.g. container/imsm/ddf, empty level, or empty raid_disks).
Components []MdraidComponent // mdraid component devices.
UUID string // UUID of the array.
@@ -81,10 +83,38 @@ func (fs FS) Mdraids() ([]Mdraid, error) {
return mdraids, err
}
- if val, err := util.ReadUintFromFile(filepath.Join(path, "raid_disks")); err == nil {
- md.Disks = val
- } else {
- return mdraids, err
+ // Parse raid_disks:
+ // - Container types (container/imsm/ddf) have no physical disks assigned.
+ // - Empty level file means we can't determine the array type, skip parsing.
+ // - During reshape/grow, raid_disks may contain "current (previous)" (e.g. "11 (10)").
+ // - Normal case is a plain integer.
+ switch md.Level {
+ case "container", "imsm", "ddf":
+ // No disks for container-type arrays, Disks remains nil.
+ case "":
+ // Empty level file, cannot determine disk count, Disks remains nil.
+ default:
+ data, err := os.ReadFile(filepath.Join(path, "raid_disks"))
+ if err != nil {
+ return mdraids, fmt.Errorf("reading raid_disks for %s: %w", md.Device, err)
+ }
+ content := strings.TrimSpace(string(data))
+ if content == "" {
+ // Empty file, Disks remains nil.
+ break
+ }
+
+ // Try normal integer parse first.
+ if val, parseErr := strconv.ParseUint(content, 10, 64); parseErr == nil {
+ md.Disks = &val
+ } else if idx := strings.Index(content, " "); idx > 0 {
+ // Reshape format: "current (previous)", extract the first number.
+ if val, parseErr := strconv.ParseUint(content[:idx], 10, 64); parseErr == nil {
+ md.Disks = &val
+ }
+ // If parsing fails, Disks remains nil (reshape in progress, count may be inaccurate).
+ }
+ // If neither format matches, Disks remains nil.
}
if val, err := util.SysReadFile(filepath.Join(path, "uuid")); err == nil {
diff --git a/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go b/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go
index 1db7e0c..12c5b0b 100644
--- a/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go
+++ b/vendor/github.com/prometheus/procfs/sysfs/system_cpu.go
@@ -53,6 +53,7 @@ type CPUThermalThrottle struct {
type SystemCPUCpufreqStats struct {
Name string
CpuinfoCurrentFrequency *uint64
+ CpuinfoAverageFrequency *uint64
CpuinfoMinimumFrequency *uint64
CpuinfoMaximumFrequency *uint64
CpuinfoTransitionLatency *uint64
@@ -269,6 +270,7 @@ func (fs FS) SystemCpufreq() ([]SystemCPUCpufreqStats, error) {
func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) {
uintFiles := []string{
"cpuinfo_cur_freq",
+ "cpuinfo_avg_freq",
"cpuinfo_max_freq",
"cpuinfo_min_freq",
"cpuinfo_transition_latency",
@@ -380,12 +382,13 @@ func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) {
return &SystemCPUCpufreqStats{
CpuinfoCurrentFrequency: uintOut[0],
- CpuinfoMaximumFrequency: uintOut[1],
- CpuinfoMinimumFrequency: uintOut[2],
- CpuinfoTransitionLatency: uintOut[3],
- ScalingCurrentFrequency: uintOut[4],
- ScalingMaximumFrequency: uintOut[5],
- ScalingMinimumFrequency: uintOut[6],
+ CpuinfoAverageFrequency: uintOut[1],
+ CpuinfoMaximumFrequency: uintOut[2],
+ CpuinfoMinimumFrequency: uintOut[3],
+ CpuinfoTransitionLatency: uintOut[4],
+ ScalingCurrentFrequency: uintOut[5],
+ ScalingMaximumFrequency: uintOut[6],
+ ScalingMinimumFrequency: uintOut[7],
AvailableGovernors: stringOut[0],
Driver: stringOut[1],
Governor: stringOut[2],
diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go
index f69fd75..c261a8e 100644
--- a/vendor/golang.org/x/sync/errgroup/errgroup.go
+++ b/vendor/golang.org/x/sync/errgroup/errgroup.go
@@ -109,7 +109,7 @@ func (g *Group) TryGo(f func() error) bool {
if g.sem != nil {
select {
case g.sem <- token{}:
- // Note: this allows barging iff channels in general allow barging.
+ // Note: this allows barging if and only if channels in general allow barging.
default:
return false
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b5d8cf4..f95cadc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -92,7 +92,7 @@ github.com/prometheus/common/version
## explicit; go 1.25.0
github.com/prometheus/exporter-toolkit/web
github.com/prometheus/exporter-toolkit/web/kingpinflag
-# github.com/prometheus/procfs v0.20.1
+# github.com/prometheus/procfs v0.21.1
## explicit; go 1.25.0
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
@@ -150,7 +150,7 @@ golang.org/x/net/trace
golang.org/x/oauth2
golang.org/x/oauth2/clientcredentials
golang.org/x/oauth2/internal
-# golang.org/x/sync v0.20.0
+# golang.org/x/sync v0.21.0
## explicit; go 1.25.0
golang.org/x/sync/errgroup
# golang.org/x/sys v0.46.0