diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b4cebad1f..10c20f4c28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,8 +20,8 @@ env: E2E_SETUP_KIND: yes E2E_SETUP_KUBECTL: yes SUDO: sudo - GO_VERSION: "^1.21" - GOLANGCI_LINT_VERSION: "v1.54.2" + GO_VERSION: "^1.22" + GOLANGCI_LINT_VERSION: "v1.56.2" jobs: ci-go-lint: diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml index 58ad384559..ff311c5552 100644 --- a/.github/workflows/govulncheck.yml +++ b/.github/workflows/govulncheck.yml @@ -6,7 +6,7 @@ on: - cron: '0 0 * * 1' env: - GO_VERSION: "^1.21" + GO_VERSION: "^1.22" permissions: contents: read diff --git a/.golangci.yml b/.golangci.yml index d7acc58f39..edbd40a820 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,5 @@ run: - deadline: 5m + deadline: 10m linters: disable-all: true diff --git a/Dockerfile b/Dockerfile index 798ac7e656..d8899a7ae3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG GOVERSION=1.21 +ARG GOVERSION=1.22 ARG GOARCH FROM golang:${GOVERSION} as builder ARG GOARCH diff --git a/Makefile b/Makefile index 71f36595b9..b0d92fd5ab 100644 --- a/Makefile +++ b/Makefile @@ -15,13 +15,13 @@ GIT_COMMIT ?= $(shell git rev-parse --short HEAD) OS ?= $(shell uname -s | tr A-Z a-z) ALL_ARCH = amd64 arm arm64 ppc64le s390x PKG = github.com/prometheus/common -PROMETHEUS_VERSION = 2.46.0 -GO_VERSION = 1.21.8 +PROMETHEUS_VERSION = 2.51.1 +GO_VERSION = 1.22.2 IMAGE = $(REGISTRY)/kube-state-metrics MULTI_ARCH_IMG = $(IMAGE)-$(ARCH) USER ?= $(shell id -u -n) HOST ?= $(shell hostname) -MARKDOWNLINT_CLI2_VERSION = 0.9.2 +MARKDOWNLINT_CLI2_VERSION = 0.13.0 export DOCKER_CLI_EXPERIMENTAL=enabled diff --git a/docs/metrics/workload/pod-metrics.md b/docs/metrics/workload/pod-metrics.md index d4fc5ccab3..8b8ed9116a 100644 --- a/docs/metrics/workload/pod-metrics.md +++ b/docs/metrics/workload/pod-metrics.md @@ -25,9 +25,9 @@ | kube_pod_container_status_last_terminated_exitcode | Gauge | Describes the exit code for the last container in terminated state. | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_status_last_terminated_timestamp | Gauge | Last terminated time for a pod container in unix timestamp. | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_status_ready | Gauge | Describes whether the containers readiness check succeeded | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | - | -| kube_pod_status_initialized_time | Gauge | Time when the pod is initialized. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | -| kube_pod_status_ready_time | Gauge | Time when pod passed readiness probes. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | -| kube_pod_status_container_ready_time | Gauge | Time when the container of the pod entered Ready state. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | +| kube_pod_status_initialized_time | Gauge | Time when the pod is initialized. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | +| kube_pod_status_ready_time | Gauge | Time when pod passed readiness probes. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | +| kube_pod_status_container_ready_time | Gauge | Time when the container of the pod entered Ready state. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_status_restarts_total | Counter | The number of container restarts per container | | `container`=<container-name>
`namespace`=<pod-namespace>
`pod`=<pod-name>
`uid`=<pod-uid> | STABLE | - | | kube_pod_container_resource_requests | Gauge | The number of requested request resource by a container. It is recommended to use the `kube_pod_resource_requests` metric exposed by kube-scheduler instead, as it is more precise. | `cpu`=<core>
`memory`=<bytes> | `resource`=<resource-name>
`unit`=<resource-unit>
`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`node`=< node-name>
`uid`=<pod-uid> | EXPERIMENTAL | - | | kube_pod_container_resource_limits | Gauge | The number of requested limit resource by a container. It is recommended to use the `kube_pod_resource_limits` metric exposed by kube-scheduler instead, as it is more precise. | `cpu`=<core>
`memory`=<bytes> | `resource`=<resource-name>
`unit`=<resource-unit>
`container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`node`=< node-name>
`uid`=<pod-uid> | EXPERIMENTAL | - | diff --git a/internal/store/clusterrole.go b/internal/store/clusterrole.go index 86642ab229..127d513a7f 100644 --- a/internal/store/clusterrole.go +++ b/internal/store/clusterrole.go @@ -91,7 +91,7 @@ func clusterRoleMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ metric.Gauge, basemetrics.ALPHA, "", - wrapClusterRoleFunc(func(r *rbacv1.ClusterRole) *metric.Family { + wrapClusterRoleFunc(func(_ *rbacv1.ClusterRole) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{{ LabelKeys: []string{}, diff --git a/internal/store/configmap.go b/internal/store/configmap.go index 90e6029ac3..dff11ea513 100644 --- a/internal/store/configmap.go +++ b/internal/store/configmap.go @@ -87,7 +87,7 @@ func configMapMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g metric.Gauge, basemetrics.STABLE, "", - wrapConfigMapFunc(func(c *v1.ConfigMap) *metric.Family { + wrapConfigMapFunc(func(_ *v1.ConfigMap) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{{ LabelKeys: []string{}, diff --git a/internal/store/endpoint.go b/internal/store/endpoint.go index fb527eeb63..482eb98e2c 100644 --- a/internal/store/endpoint.go +++ b/internal/store/endpoint.go @@ -48,7 +48,7 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge metric.Gauge, basemetrics.STABLE, "", - wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { + wrapEndpointFunc(func(_ *v1.Endpoints) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/job.go b/internal/store/job.go index d778212bbd..6e0e97b218 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -94,7 +94,7 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, basemetrics.STABLE, "", - wrapJobFunc(func(j *v1batch.Job) *metric.Family { + wrapJobFunc(func(_ *v1batch.Job) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/mutatingwebhookconfiguration.go b/internal/store/mutatingwebhookconfiguration.go index c09df4773f..394fd8483e 100644 --- a/internal/store/mutatingwebhookconfiguration.go +++ b/internal/store/mutatingwebhookconfiguration.go @@ -41,7 +41,7 @@ var ( metric.Gauge, basemetrics.ALPHA, "", - wrapMutatingWebhookConfigurationFunc(func(mwc *admissionregistrationv1.MutatingWebhookConfiguration) *metric.Family { + wrapMutatingWebhookConfigurationFunc(func(_ *admissionregistrationv1.MutatingWebhookConfiguration) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/role.go b/internal/store/role.go index 3d2e801607..02bfb0d338 100644 --- a/internal/store/role.go +++ b/internal/store/role.go @@ -91,7 +91,7 @@ func roleMetricFamilies(allowAnnotationsList, allowLabelsList []string) []genera metric.Gauge, basemetrics.ALPHA, "", - wrapRoleFunc(func(r *rbacv1.Role) *metric.Family { + wrapRoleFunc(func(_ *rbacv1.Role) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{{ LabelKeys: []string{}, diff --git a/internal/store/secret.go b/internal/store/secret.go index 79b9f7afae..36d115c034 100644 --- a/internal/store/secret.go +++ b/internal/store/secret.go @@ -48,7 +48,7 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene metric.Gauge, basemetrics.STABLE, "", - wrapSecretFunc(func(s *v1.Secret) *metric.Family { + wrapSecretFunc(func(_ *v1.Secret) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/validatingwebhookconfiguration.go b/internal/store/validatingwebhookconfiguration.go index 5084e8dd3e..c740598c29 100644 --- a/internal/store/validatingwebhookconfiguration.go +++ b/internal/store/validatingwebhookconfiguration.go @@ -41,7 +41,7 @@ var ( metric.Gauge, basemetrics.ALPHA, "", - wrapValidatingWebhookConfigurationFunc(func(vwc *admissionregistrationv1.ValidatingWebhookConfiguration) *metric.Family { + wrapValidatingWebhookConfigurationFunc(func(_ *admissionregistrationv1.ValidatingWebhookConfiguration) *metric.Family { return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/main.go b/main.go index 5bdfaecaf8..da948a1982 100644 --- a/main.go +++ b/main.go @@ -27,7 +27,7 @@ import ( func main() { opts := options.NewOptions() cmd := options.InitCommand - cmd.Run = func(cmd *cobra.Command, args []string) { + cmd.Run = func(_ *cobra.Command, _ []string) { internal.RunKubeStateMetricsWrapper(opts) } opts.AddFlags(cmd) diff --git a/pkg/app/server.go b/pkg/app/server.go index 27d00c0f92..aa5b2c916c 100644 --- a/pkg/app/server.go +++ b/pkg/app/server.go @@ -403,7 +403,7 @@ func buildMetricsServer(m *metricshandler.MetricsHandler, durationObserver prome mux.Handle(metricsPath, promhttp.InstrumentHandlerDuration(durationObserver, m)) // Add healthzPath - mux.HandleFunc(healthzPath, func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(healthzPath, func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(http.StatusText(http.StatusOK))) }) diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go index 88bf39d49e..f7d33bac85 100644 --- a/pkg/app/server_test.go +++ b/pkg/app/server_test.go @@ -100,7 +100,7 @@ func BenchmarkKubeStateMetrics(b *testing.B) { // This test is not suitable to be compared in terms of time, as it includes // a one second wait. Use for memory allocation comparisons, profiling, ... handler := metricshandler.New(&options.Options{}, kubeClient, builder, false) - b.Run("GenerateMetrics", func(b *testing.B) { + b.Run("GenerateMetrics", func(_ *testing.B) { handler.ConfigureSharding(ctx, 0, 1) // Wait for caches to fill diff --git a/pkg/metrics_store/metrics_store_test.go b/pkg/metrics_store/metrics_store_test.go index b32e1bcb38..dbde02b98a 100644 --- a/pkg/metrics_store/metrics_store_test.go +++ b/pkg/metrics_store/metrics_store_test.go @@ -41,7 +41,7 @@ func (f *metricFamily) ByteSlice() []byte { } func TestObjectsSameNameDifferentNamespaces(t *testing.T) { - serviceIDS := []string{"a", "b"} + serviceIDs := []string{"a", "b"} genFunc := func(obj interface{}) []metric.FamilyInterface { o, err := meta.Accessor(obj) @@ -65,7 +65,7 @@ func TestObjectsSameNameDifferentNamespaces(t *testing.T) { ms := NewMetricsStore([]string{"Information about service."}, genFunc) - for _, id := range serviceIDS { + for _, id := range serviceIDs { s := v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "service", @@ -88,7 +88,7 @@ func TestObjectsSameNameDifferentNamespaces(t *testing.T) { } m := w.String() - for _, id := range serviceIDS { + for _, id := range serviceIDs { if !strings.Contains(m, fmt.Sprintf("uid=\"%v\"", id)) { t.Fatalf("expected to find metric with uid %v", id) } diff --git a/pkg/metrics_store/metrics_writer_test.go b/pkg/metrics_store/metrics_writer_test.go index b7d2907b0f..d32cc45cf9 100644 --- a/pkg/metrics_store/metrics_writer_test.go +++ b/pkg/metrics_store/metrics_writer_test.go @@ -238,7 +238,7 @@ func TestWriteAllWithMultipleStores(t *testing.T) { // TestWriteAllWithEmptyStores checks that nothing is printed if no metrics exist for metric families. func TestWriteAllWithEmptyStores(t *testing.T) { - genFunc := func(obj interface{}) []metric.FamilyInterface { + genFunc := func(_ interface{}) []metric.FamilyInterface { mf1 := metric.Family{ Name: "kube_service_info_1", Metrics: []*metric.Metric{}, diff --git a/pkg/options/options.go b/pkg/options/options.go index c89ef63f43..09adf8939a 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -83,7 +83,7 @@ func NewOptions() *Options { func (o *Options) AddFlags(cmd *cobra.Command) { o.cmd = cmd - completionCommand.SetHelpFunc(func(cmd *cobra.Command, args []string) { + completionCommand.SetHelpFunc(func(_ *cobra.Command, _ []string) { if shellPath, ok := os.LookupEnv("SHELL"); ok { shell := shellPath[strings.LastIndex(shellPath, "/")+1:] fmt.Println(FetchLoadInstructions(shell)) @@ -97,7 +97,7 @@ func (o *Options) AddFlags(cmd *cobra.Command) { versionCommand := &cobra.Command{ Use: "version", Short: "Print version information.", - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { fmt.Printf("%s\n", version.Print("kube-state-metrics")) klog.FlushAndExit(klog.ExitFlushTimeout, 0) }, diff --git a/tests/e2e/discovery_test.go b/tests/e2e/discovery_test.go index 63f0878ff6..d34c932daf 100644 --- a/tests/e2e/discovery_test.go +++ b/tests/e2e/discovery_test.go @@ -97,7 +97,7 @@ func TestVariableVKsDiscoveryAndResolution(t *testing.T) { klog.InfoS("started KSM") // Wait for port 8080 to come up. - err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(_ context.Context) (bool, error) { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { return false, nil @@ -140,7 +140,7 @@ func TestVariableVKsDiscoveryAndResolution(t *testing.T) { // Wait for the metric to be available. ch := make(chan bool, 1) klog.InfoS("waiting for metrics to become available") - err = wait.PollUntilContextTimeout(context.TODO(), discovery.Interval, PopulateTimeout, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), discovery.Interval, PopulateTimeout, true, func(_ context.Context) (bool, error) { out, err := exec.Command("curl", "localhost:8080/metrics").Output() if err != nil { return false, err diff --git a/tests/e2e/hot-reload-kubeconfig_test.go b/tests/e2e/hot-reload-kubeconfig_test.go index 560801dd9b..050f2f6e94 100644 --- a/tests/e2e/hot-reload-kubeconfig_test.go +++ b/tests/e2e/hot-reload-kubeconfig_test.go @@ -74,7 +74,7 @@ func TestKubeConfigHotReload(t *testing.T) { go internal.RunKubeStateMetricsWrapper(opts) // Wait for port 8080 to come up. - err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(_ context.Context) (bool, error) { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { return false, nil @@ -108,7 +108,7 @@ func TestKubeConfigHotReload(t *testing.T) { // Wait for port 8080 to come up. ch := make(chan bool, 1) - err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(_ context.Context) (bool, error) { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { return false, nil diff --git a/tests/e2e/hot-reload_test.go b/tests/e2e/hot-reload_test.go index b1c88c8714..c416605e52 100644 --- a/tests/e2e/hot-reload_test.go +++ b/tests/e2e/hot-reload_test.go @@ -65,7 +65,7 @@ func TestConfigHotReload(t *testing.T) { go internal.RunKubeStateMetricsWrapper(opts) // Wait for port 8080 to come up. - err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(_ context.Context) (bool, error) { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { return false, nil @@ -89,7 +89,7 @@ func TestConfigHotReload(t *testing.T) { // Wait for port 8080 to come up. ch := make(chan bool, 1) - err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 20*time.Second, true, func(_ context.Context) (bool, error) { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { return false, nil diff --git a/tests/e2e/main_test.go b/tests/e2e/main_test.go index d06256fa85..72d3f1db03 100644 --- a/tests/e2e/main_test.go +++ b/tests/e2e/main_test.go @@ -154,7 +154,7 @@ func getLabelsDocumentation() (map[string][]string, error) { // Match wildcard patterns for dynamic labels such as label_CRONJOB_LABEL patternRe := regexp.MustCompile(`_[A-Z_]+`) - err := filepath.WalkDir("../../docs", func(p string, d fs.DirEntry, err error) error { + err := filepath.WalkDir("../../docs", func(p string, d fs.DirEntry, _ error) error { if d.IsDir() || !fileRe.MatchString(d.Name()) { // Ignore the entry