Repository: kubernetes-sigs/node-feature-discovery
Pull request #1860 (2024-08-30 15:03:34)

nfd-worker: Add an option to disable setting the owner references
In some cases it's desirable to control automatic garbage collection of NodeFeature object.

Add an option to disable setting the owner references to Pod for NodeFeature object.

Closes: #1817

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/node-feature-discovery/pull/1860#" title="Author self-approved">ozhuraki</a>*
**Once this PR has been reviewed and has the lgtm label**, please assign [arangogutierrez](https://github.com/arangogutierrez) for approval. For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fnode-feature-discovery).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/node-feature-discovery/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["arangogutierrez"]} -->
k8s-ci-robot: Hi @ozhuraki. Thanks for your PR.

I'm waiting for a [kubernetes-sigs](https://github.com/orgs/kubernetes-sigs/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://git.k8s.io/community/community-membership.md#member) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fnode-feature-discovery).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>

netlify[bot]: ### <span aria-hidden="true">👷</span> Deploy Preview for *kubernetes-sigs-nfd* processing.


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | f825f8642d6808472d259882f1dd02f975cdc675 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/kubernetes-sigs-nfd/deploys/66d1df483254be000899b5d8 |
k8s-ci-robot: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
marquiz: /ok-to-test
ozhuraki: @marquiz 
Thanks! Updated, please take a look
ozhuraki: @marquiz
Thanks! Updated, please take a look
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/node-feature-discovery/pull/1860#pullrequestreview-2362509572" title="Approved">marquiz</a>*, *<a href="https://github.com/kubernetes-sigs/node-feature-discovery/pull/1860#" title="Author self-approved">ozhuraki</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fnode-feature-discovery).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/node-feature-discovery/blob/master/OWNERS)~~ [marquiz]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
ozhuraki: @fmuyassarov

Apologies for a delay. Thanks, updated, please take a look

marquiz: /remove-approve
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/node-feature-discovery/pull/1860#" title="Author self-approved">ozhuraki</a>*
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from [arangogutierrez](https://github.com/arangogutierrez). For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fnode-feature-discovery).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/node-feature-discovery/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["arangogutierrez"]} -->
ozhuraki: @marquiz

Thanks, updated. Please take a look

ozhuraki: @marquiz

Thanks, updated. Please take a look


Patch:
diff --git a/api/nfd/go.mod b/api/nfd/go.mod
index 41e7f972c..9e9c29f09 100644
--- a/api/nfd/go.mod
+++ b/api/nfd/go.mod
@@ -5,8 +5,8 @@ go 1.22.2
 require (
 	github.com/gogo/protobuf v1.3.2
 	github.com/stretchr/testify v1.8.4
-	k8s.io/api v0.30.7
-	k8s.io/apimachinery v0.30.7
+	k8s.io/api v0.30.3
+	k8s.io/apimachinery v0.30.3
 )
 
 require (
diff --git a/api/nfd/go.sum b/api/nfd/go.sum
index c016e091b..6247ab35c 100644
--- a/api/nfd/go.sum
+++ b/api/nfd/go.sum
@@ -75,10 +75,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.30.7 h1:wB2eHI+IptVYsz5WsAQpI6+Dqi3+11wEWBqIh4fh980=
-k8s.io/api v0.30.7/go.mod h1:bR0EwbmhYmJvUoeza7ZzBUmYCrVXccQ9JOdfv0BxhH0=
-k8s.io/apimachinery v0.30.7 h1:CoQFxvzPFKwU1eJGN/8LgM3ZJBC3hKgvwGqRrL43uIY=
-k8s.io/apimachinery v0.30.7/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
+k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
+k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
+k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
+k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
 k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
 k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
diff --git a/cmd/nfd-worker/main.go b/cmd/nfd-worker/main.go
index fe589f546..e60b2348c 100644
--- a/cmd/nfd-worker/main.go
+++ b/cmd/nfd-worker/main.go
@@ -94,6 +94,8 @@ func parseArgs(flags *flag.FlagSet, osArgs ...string) *worker.Args {
 			args.Overrides.FeatureSources = overrides.FeatureSources
 		case "label-sources":
 			args.Overrides.LabelSources = overrides.LabelSources
+		case "no-owner-refs":
+			args.Overrides.NoOwnerRefs = overrides.NoOwnerRefs
 		}
 	})
 
@@ -126,6 +128,8 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
 	}
 	overrides.NoPublish = flagset.Bool("no-publish", false,
 		"Do not publish discovered features, disable connection to nfd-master and don't create NodeFeature object.")
+	overrides.NoOwnerRefs = flagset.Bool("no-owner-refs", false,
+		"Do not set owner references for NodeFeature object.")
 	flagset.Var(overrides.FeatureSources, "feature-sources",
 		"Comma separated list of feature sources. Special value 'all' enables all sources. "+
 			"Prefix the source name with '-' to disable it.")
diff --git a/deployment/components/worker-config/nfd-worker.conf.example b/deployment/components/worker-config/nfd-worker.conf.example
index c608a72da..ff9125153 100644
--- a/deployment/components/worker-config/nfd-worker.conf.example
+++ b/deployment/components/worker-config/nfd-worker.conf.example
@@ -1,6 +1,7 @@
 #core:
 #  labelWhiteList:
 #  noPublish: false
+#  noOwnerRefs: false
 #  sleepInterval: 60s
 #  featureSources: [all]
 #  labelSources: [all]
diff --git a/deployment/helm/node-feature-discovery/values.yaml b/deployment/helm/node-feature-discovery/values.yaml
index 6ae8da521..1c2dadb1b 100644
--- a/deployment/helm/node-feature-discovery/values.yaml
+++ b/deployment/helm/node-feature-discovery/values.yaml
@@ -177,6 +177,7 @@ worker:
     #core:
     #  labelWhiteList:
     #  noPublish: false
+    #  noOwnerRefs: false
     #  sleepInterval: 60s
     #  featureSources: [all]
     #  labelSources: [all]
diff --git a/docs/deployment/metrics.md b/docs/deployment/metrics.md
index d0edd59a7..61d3baaca 100644
--- a/docs/deployment/metrics.md
+++ b/docs/deployment/metrics.md
@@ -13,25 +13,24 @@ By default NFD Master and Worker expose metrics on port 8081.
 
 The exposed metrics are
 
-| Metric                                                   | Type      | Description                                                                |
-| -------------------------------------------------------- | --------- | -------------------------------------------------------------------------- |
-| `nfd_master_build_info`                                  | Gauge     | Version from which nfd-master was built                                    |
-| `nfd_worker_build_info`                                  | Gauge     | Version from which nfd-worker was built                                    |
-| `nfd_gc_build_info`                                      | Gauge     | Version from which nfd-gc was built                                        |
-| `nfd_topology_updater_build_info`                        | Gauge     | Version from which nfd-topology-updater was built                          |
-| `nfd_master_node_update_requests_total`                  | Counter   | Number of node update requests received by the master over gRPC            |
-| `nfd_master_node_updates_total`                          | Counter   | Number of nodes updated                                                    |
-| `nfd_master_node_feature_group_update_requests_total`    | Counter   | Number of cluster feature update requests processed by the master          |
-| `nfd_master_node_update_failures_total`                  | Counter   | Number of nodes update failures                                            |
-| `nfd_master_node_labels_rejected_total`                  | Counter   | Number of nodes labels rejected by nfd-master                              |
-| `nfd_master_node_extendedresources_rejected_total`       | Counter   | Number of nodes extended resources rejected by nfd-master                  |
-| `nfd_master_node_taints_rejected_total`                  | Counter   | Number of nodes taints rejected by nfd-master                              |
-| `nfd_master_nodefeaturerule_processing_duration_seconds` | Histogram | Time taken to process NodeFeatureRule objects                              |
-| `nfd_master_nodefeaturerule_processing_errors_total`     | Counter   | Number or errors encountered while processing NodeFeatureRule objects      |
-| `nfd_worker_feature_discovery_duration_seconds`          | Histogram | Time taken to discover features on a node                                  |
-| `nfd_topology_updater_scan_errors_total`                 | Counter   | Number of errors in scanning resource allocation of pods.                  |
-| `nfd_gc_objects_deleted_total`                           | Counter   | Number of NodeFeature and NodeResourceTopology objects garbage collected.  |
-| `nfd_gc_object_delete_failures_total`                    | Counter   | Number of errors in deleting NodeFeature and NodeResourceTopology objects. |
+| Metric                                            | Type      | Description                                             |
+| ------------------------------------------------- | --------- | ------------------------------------------------------- |
+| `nfd_master_build_info`                           | Gauge     | Version from which nfd-master was built                 |
+| `nfd_worker_build_info`                           | Gauge     | Version from which nfd-worker was built                 |
+| `nfd_gc_build_info`                               | Gauge     | Version from which nfd-gc was built                     |
+| `nfd_topology_updater_build_info`                 | Gauge     | Version from which nfd-topology-updater was built        |
+| `nfd_node_update_requests_total`                  | Counter   | Number of node update requests received by the master over gRPC |
+| `nfd_node_updates_total`                          | Counter   | Number of nodes updated                                 |
+| `nfd_node_update_failures_total`                  | Counter   | Number of nodes update failures                          |
+| `nfd_node_labels_rejected_total`                  | Counter   | Number of nodes labels rejected by nfd-master            |
+| `nfd_node_extendedresources_rejected_total`       | Counter   | Number of nodes extended resources rejected by nfd-master |
+| `nfd_node_taints_rejected_total`                  | Counter   | Number of nodes taints rejected by nfd-master            |
+| `nfd_nodefeaturerule_processing_duration_seconds` | Histogram | Time taken to process NodeFeatureRule objects            |
+| `nfd_nodefeaturerule_processing_errors_total`     | Counter   | Number or errors encountered while processing NodeFeatureRule objects |
+| `nfd_feature_discovery_duration_seconds`          | Histogram | Time taken to discover features on a node                |
+| `nfd_topology_updater_scan_errors_total`          | Counter   | Number of errors in scanning resource allocation of pods. |
+| `nfd_gc_objects_deleted_total`                    | Counter   | Number of NodeFeature and NodeResourceTopology objects garbage collected. |
+| `nfd_gc_object_delete_failures_total`             | Counter   | Number of errors in deleting NodeFeature and NodeResourceTopology objects. |
 
 ## Kustomize
 
diff --git a/docs/reference/worker-commandline-reference.md b/docs/reference/worker-commandline-reference.md
index 95ed1a4c6..6d281e154 100644
--- a/docs/reference/worker-commandline-reference.md
+++ b/docs/reference/worker-commandline-reference.md
@@ -162,6 +162,23 @@ Example:
 nfd-worker -no-publish
 ```
 
+### -no-owner-refs
+
+The `-no-owner-refs` flag disables setting the owner references to Pod
+of the NodeFeature object.
+
+> **NOTE:** This flag takes precedence over the
+> [`core.noOwnerRefs`](worker-configuration-reference.md#corenoownerrefs)
+> configuration file option.
+
+Default: *false*
+
+Example:
+
+```bash
+nfd-worker -no-owner-refs
+```
+
 ### -oneshot
 
 The `-oneshot` flag causes nfd-worker to exit after one pass of feature
diff --git a/docs/reference/worker-configuration-reference.md b/docs/reference/worker-configuration-reference.md
index c8a900799..e51353ee0 100644
--- a/docs/reference/worker-configuration-reference.md
+++ b/docs/reference/worker-configuration-reference.md
@@ -149,6 +149,24 @@ core:
   noPublish: true
 ```
 
+### core.noOwnerRefs
+
+Setting `core.noOwnerRefs` to `true` disables setting the owner references
+of the NodeFeature object created by the nfd-worker.
+
+> **NOTE:** Overridden by the
+> [`-no-owner-refs`](worker-commandline-reference.md#-no-owner-refs)
+> command line flag (if specified).
+
+Default: `false`
+
+Example:
+
+```yaml
+core:
+  noOwnerRefs: true
+```
+
 ### core.klog
 
 The following options specify the logger configuration.
diff --git a/docs/usage/features.md b/docs/usage/features.md
index 897db43f9..93ffb2f4b 100644
--- a/docs/usage/features.md
+++ b/docs/usage/features.md
@@ -87,7 +87,6 @@ configuration options for details.
 | AMXBF16            | Advanced Matrix Extension, tile multiplication operations on BFLOAT16 numbers |
 | AMXINT8            | Advanced Matrix Extension, tile multiplication operations on 8-bit integers |
 | AMXFP16            | Advanced Matrix Extension, tile multiplication operations on FP16 numbers |
-| AMXFP8             | Advanced Matrix Extension, tile multiplication operations on FP8 numbers |
 | AMXTILE            | Advanced Matrix Extension, base tile architecture support |
 | AVX512BF16         | AVX-512 BFLOAT16 instructions |
 | AVX512BITALG       | AVX-512 bit Algorithms |
diff --git a/examples/grafana-dashboard.json b/examples/grafana-dashboard.json
index e9cd95dec..d086a138a 100644
--- a/examples/grafana-dashboard.json
+++ b/examples/grafana-dashboard.json
@@ -391,7 +391,7 @@
           },
           "disableTextWrap": false,
           "editorMode": "builder",
-          "expr": "nfd_master_node_updates_total",
+          "expr": "nfd_node_updates_total",
           "fullMetaSearch": false,
           "hide": false,
           "includeNullMetadata": true,
@@ -586,7 +586,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "nfd_master_node_update_failures_total",
+          "expr": "nfd_node_update_failures_total",
           "legendFormat": "total",
           "range": true,
           "refId": "A"
@@ -679,7 +679,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "nfd_master_nodefeaturerule_processing_errors_total",
+          "expr": "nfd_nodefeaturerule_processing_errors_total",
           "hide": false,
           "legendFormat": "total",
           "range": true,
@@ -940,7 +940,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "sum by(le) (nfd_worker_feature_discovery_duration_seconds_bucket)",
+          "expr": "sum by(le) (nfd_feature_discovery_duration_seconds_bucket)",
           "format": "heatmap",
           "legendFormat": "__auto",
           "range": true,
@@ -1007,7 +1007,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "sum by(le) (nfd_master_nodefeaturerule_processing_duration_seconds_bucket)",
+          "expr": "sum by(le) (nfd_nodefeaturerule_processing_duration_seconds_bucket)",
           "format": "heatmap",
           "legendFormat": "__auto",
           "range": true,
@@ -1101,7 +1101,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "nfd_master_node_labels_rejected_total",
+          "expr": "nfd_node_labels_rejected_total",
           "legendFormat": "total",
           "range": true,
           "refId": "A"
@@ -1194,7 +1194,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "nfd_master_node_extendedresources_rejected_total",
+          "expr": "nfd_node_extendedresources_rejected_total",
           "hide": false,
           "legendFormat": "total",
           "range": true,
@@ -1288,7 +1288,7 @@
             "uid": "prometheus"
           },
           "editorMode": "builder",
-          "expr": "nfd_master_node_taints_rejected_total",
+          "expr": "nfd_node_taints_rejected_total",
           "hide": false,
           "legendFormat": "total",
           "range": true,
diff --git a/go.mod b/go.mod
index 5ea1ba42a..ebc06c934 100644
--- a/go.mod
+++ b/go.mod
@@ -10,29 +10,29 @@ require (
 	github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.1.2
 	github.com/k8stopologyawareschedwg/podfingerprint v0.2.2
 	github.com/klauspost/cpuid/v2 v2.2.9
-	github.com/onsi/ginkgo/v2 v2.22.0
+	github.com/onsi/ginkgo/v2 v2.21.0
 	github.com/onsi/gomega v1.35.1
 	github.com/opencontainers/runc v1.2.2
 	github.com/prometheus/client_golang v1.19.1
 	github.com/smartystreets/goconvey v1.8.1
 	github.com/spf13/cobra v1.8.1
-	github.com/stretchr/testify v1.10.0
+	github.com/stretchr/testify v1.9.0
 	github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
 	golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
 	golang.org/x/net v0.31.0
 	golang.org/x/time v0.8.0
 	google.golang.org/grpc v1.68.0
-	k8s.io/api v0.31.3
-	k8s.io/apiextensions-apiserver v0.31.3
-	k8s.io/apimachinery v0.31.3
-	k8s.io/client-go v0.31.3
-	k8s.io/code-generator v0.31.3
-	k8s.io/component-base v0.31.3
+	k8s.io/api v0.31.2
+	k8s.io/apiextensions-apiserver v0.31.2
+	k8s.io/apimachinery v0.31.2
+	k8s.io/client-go v0.31.2
+	k8s.io/code-generator v0.31.2
+	k8s.io/component-base v0.31.2
 	k8s.io/klog/v2 v2.130.1
-	k8s.io/kubectl v0.31.3
-	k8s.io/kubelet v0.31.3
-	k8s.io/kubernetes v1.31.3
-	k8s.io/pod-security-admission v0.31.3
+	k8s.io/kubectl v0.31.2
+	k8s.io/kubelet v0.31.2
+	k8s.io/kubernetes v1.31.2
+	k8s.io/pod-security-admission v0.31.2
 	k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
 	sigs.k8s.io/node-feature-discovery/api/nfd v0.0.0-00010101000000-000000000000
 	sigs.k8s.io/yaml v1.4.0
@@ -136,18 +136,18 @@ require (
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	howett.net/plist v1.0.0 // indirect
-	k8s.io/apiserver v0.31.3 // indirect
-	k8s.io/cloud-provider v0.31.3 // indirect
-	k8s.io/component-helpers v0.31.3 // indirect
-	k8s.io/controller-manager v0.31.3 // indirect
-	k8s.io/cri-api v0.31.3 // indirect
+	k8s.io/apiserver v0.31.2 // indirect
+	k8s.io/cloud-provider v0.31.2 // indirect
+	k8s.io/component-helpers v0.31.2 // indirect
+	k8s.io/controller-manager v0.31.2 // indirect
+	k8s.io/cri-api v0.31.2 // indirect
 	k8s.io/cri-client v0.0.0 // indirect
-	k8s.io/csi-translation-lib v0.31.3 // indirect
-	k8s.io/dynamic-resource-allocation v0.31.3 // indirect
+	k8s.io/csi-translation-lib v0.31.2 // indirect
+	k8s.io/dynamic-resource-allocation v0.31.2 // indirect
 	k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
-	k8s.io/kms v0.31.3 // indirect
+	k8s.io/kms v0.31.2 // indirect
 	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
-	k8s.io/mount-utils v0.31.3 // indirect
+	k8s.io/mount-utils v0.25.0 // indirect
 	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
@@ -157,31 +157,31 @@ require (
 // need to override with commits (corresponding their kubernetes-* tags)
 replace (
 	github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
-	k8s.io/api => k8s.io/api v0.31.3
-	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.3
-	k8s.io/apimachinery => k8s.io/apimachinery v0.31.3
-	k8s.io/apiserver => k8s.io/apiserver v0.31.3
-	k8s.io/cli-runtime => k8s.io/cli-runtime v0.31.3
-	k8s.io/client-go => k8s.io/client-go v0.31.3
-	k8s.io/cloud-provider => k8s.io/cloud-provider v0.31.3
-	k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.31.3
-	k8s.io/code-generator => k8s.io/code-generator v0.31.3
-	k8s.io/component-base => k8s.io/component-base v0.31.3
-	k8s.io/component-helpers => k8s.io/component-helpers v0.31.3
-	k8s.io/controller-manager => k8s.io/controller-manager v0.31.3
-	k8s.io/cri-api => k8s.io/cri-api v0.31.3
-	k8s.io/cri-client => k8s.io/cri-client v0.31.3
-	k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.31.3
-	k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.31.3
-	k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.31.3
-	k8s.io/kube-proxy => k8s.io/kube-proxy v0.31.3
-	k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.31.3
-	k8s.io/kubectl => k8s.io/kubectl v0.31.3
-	k8s.io/kubelet => k8s.io/kubelet v0.31.3
-	k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.31.3
-	k8s.io/metrics => k8s.io/metrics v0.31.3
-	k8s.io/mount-utils => k8s.io/mount-utils v0.31.3
-	k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.31.3
-	k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.31.3
+	k8s.io/api => k8s.io/api v0.31.2
+	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.2
+	k8s.io/apimachinery => k8s.io/apimachinery v0.31.2
+	k8s.io/apiserver => k8s.io/apiserver v0.31.2
+	k8s.io/cli-runtime => k8s.io/cli-runtime v0.31.2
+	k8s.io/client-go => k8s.io/client-go v0.31.2
+	k8s.io/cloud-provider => k8s.io/cloud-provider v0.31.2
+	k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.31.2
+	k8s.io/code-generator => k8s.io/code-generator v0.31.2
+	k8s.io/component-base => k8s.io/component-base v0.31.2
+	k8s.io/component-helpers => k8s.io/component-helpers v0.31.2
+	k8s.io/controller-manager => k8s.io/controller-manager v0.31.2
+	k8s.io/cri-api => k8s.io/cri-api v0.31.2
+	k8s.io/cri-client => k8s.io/cri-client v0.31.2
+	k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.31.2
+	k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.31.2
+	k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.31.2
+	k8s.io/kube-proxy => k8s.io/kube-proxy v0.31.2
+	k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.31.2
+	k8s.io/kubectl => k8s.io/kubectl v0.31.2
+	k8s.io/kubelet => k8s.io/kubelet v0.31.2
+	k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.31.2
+	k8s.io/metrics => k8s.io/metrics v0.31.2
+	k8s.io/mount-utils => k8s.io/mount-utils v0.31.2
+	k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.31.2
+	k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.31.2
 	sigs.k8s.io/node-feature-discovery/api/nfd => ./api/nfd
 )
diff --git a/go.sum b/go.sum
index c3106e9c2..1e2dab4dd 100644
--- a/go.sum
+++ b/go.sum
@@ -175,8 +175,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
-github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
 github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
 github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -230,8 +230,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
@@ -367,54 +367,54 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
 howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
-k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8=
-k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE=
-k8s.io/apiextensions-apiserver v0.31.3 h1:+GFGj2qFiU7rGCsA5o+p/rul1OQIq6oYpQw4+u+nciE=
-k8s.io/apiextensions-apiserver v0.31.3/go.mod h1:2DSpFhUZZJmn/cr/RweH1cEVVbzFw9YBu4T+U3mf1e4=
-k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4=
-k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
-k8s.io/apiserver v0.31.3 h1:+1oHTtCB+OheqFEz375D0IlzHZ5VeQKX1KGXnx+TTuY=
-k8s.io/apiserver v0.31.3/go.mod h1:PrxVbebxrxQPFhJk4powDISIROkNMKHibTg9lTRQ0Qg=
-k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4=
-k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs=
-k8s.io/cloud-provider v0.31.3 h1:7C3CHQUUwnv/HWWVIaibZH06iPg663RYQ6C6Zy4FnO8=
-k8s.io/cloud-provider v0.31.3/go.mod h1:c7csKppoVb9Ej6upJ28AvHy4B3BtlRMzXfgezsDdPKw=
-k8s.io/code-generator v0.31.3 h1:Pj0fYOBms+ZrsulLi4DMsCEx1jG8fWKRLy44onHsLBI=
-k8s.io/code-generator v0.31.3/go.mod h1:/umCIlT84g1+Yu5ZXtP1KGSRTnGiIzzX5AzUAxsNlts=
-k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ=
-k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU=
-k8s.io/component-helpers v0.31.3 h1:0zGPD2PrekhFWgmz85XxlMEl7dfhlKC1tERZDe3onQc=
-k8s.io/component-helpers v0.31.3/go.mod h1:HZ1HZx2TKXM7xSUV2cR9L5yDoyZPhhHQNaE3BPBLPUQ=
-k8s.io/controller-manager v0.31.3 h1:TyUav69iNYwLGwA96JDhusoZoGRdh1sdrLjXmWTcPgs=
-k8s.io/controller-manager v0.31.3/go.mod h1:yuhec+dbXmBz+4c32kxJxmcauB+1pjO2ttfYODWuv18=
-k8s.io/cri-api v0.31.3 h1:dsZXzrGrCEwHjsTDlAV7rutEplpMLY8bfNRMIqrtXjo=
-k8s.io/cri-api v0.31.3/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI=
-k8s.io/cri-client v0.31.3 h1:9ZwddaNJomqkTBYQqSmB+Ccns3beY4HyYDwmRtWTCJM=
-k8s.io/cri-client v0.31.3/go.mod h1:klbWiYkOatOQOkXOYZMZMGSTM8q9eC/efsYGuXcgPes=
-k8s.io/csi-translation-lib v0.31.3 h1:hxcPRNdtEsk766jCXSKjgH1V8jUNx5tVqdooQ1Ars/M=
-k8s.io/csi-translation-lib v0.31.3/go.mod h1:0B1gQwd868XUIDwJYy5gB2jDXWEwlcWvSsfcQEgzbRk=
-k8s.io/dynamic-resource-allocation v0.31.3 h1:hiQMhyxrm7WA6tWJCLINE2P11Ii3rCVw+YzV3B6+eWo=
-k8s.io/dynamic-resource-allocation v0.31.3/go.mod h1:l7OvYDokvnXhFAOhInQUY/z0/HezzmRuLlspld4Xfg4=
+k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
+k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
+k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0=
+k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM=
+k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
+k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
+k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4=
+k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE=
+k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
+k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
+k8s.io/cloud-provider v0.31.2 h1:ZdstxJOcHzP45j8giE79VJmgNckBbw1ldtIqnhZvKIA=
+k8s.io/cloud-provider v0.31.2/go.mod h1:+4L8YpYCEx1Ko5EKS/PzXyBY5YREwDKChsJjAxHRf08=
+k8s.io/code-generator v0.31.2 h1:xLWxG0HEpMSHfcM//3u3Ro2Hmc6AyyLINQS//Z2GEOI=
+k8s.io/code-generator v0.31.2/go.mod h1:eEQHXgBU/m7LDaToDoiz3t97dUUVyOblQdwOr8rivqc=
+k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA=
+k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ=
+k8s.io/component-helpers v0.31.2 h1:V2yjoNeyg8WfvwrJwzfYz+RUwjlbcAIaDaHEStBbaZM=
+k8s.io/component-helpers v0.31.2/go.mod h1:cNz+1ck38R0qWrjcw/rhQgGP6+Gwgw8ngr2ziDNmSXM=
+k8s.io/controller-manager v0.31.2 h1:S5FPrZo6wpcTwQHfwcklOkr3MKGvKYtroOtCqri67Ns=
+k8s.io/controller-manager v0.31.2/go.mod h1:+MymA0Dg2pC+hYYNsca9shRZbrkK3HKIg2B11p6eC+Q=
+k8s.io/cri-api v0.31.2 h1:O/weUnSHvM59nTio0unxIUFyRHMRKkYn96YDILSQKmo=
+k8s.io/cri-api v0.31.2/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI=
+k8s.io/cri-client v0.31.2 h1:GLuzaFre8WueBohexPSUQEOMha3tBuacjb3PT10X8bI=
+k8s.io/cri-client v0.31.2/go.mod h1:vUPilfcW9LSyp1Kbc1nuMu5IkyeF1HDqik6FeSAtUhk=
+k8s.io/csi-translation-lib v0.31.2 h1:nCOE28rTUVOjwUKs4wl8wIZBHEnbQU5MkI0P6YM/Ylg=
+k8s.io/csi-translation-lib v0.31.2/go.mod h1:X0paKG/WAqDyrfpiTyj8ga4srG0guOm2Sj2pNi4kP10=
+k8s.io/dynamic-resource-allocation v0.31.2 h1:zJWogzySxVrJnGvV3yyspKHzgUieNzrPpLkTSFj+D1Q=
+k8s.io/dynamic-resource-allocation v0.31.2/go.mod h1:0txLYaTMMwne1V9opaKK/h0eM0tS07e6ZTcsI6MPLWw=
 k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
 k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kms v0.31.3 h1:XCFmiJn5CCKs8xoOLpCmu42Ubm/KW85wNHybGFcSAYc=
-k8s.io/kms v0.31.3/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94=
+k8s.io/kms v0.31.2 h1:pyx7l2qVOkClzFMIWMVF/FxsSkgd+OIGH7DecpbscJI=
+k8s.io/kms v0.31.2/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
-k8s.io/kube-scheduler v0.31.3 h1:indE2jtvbwyyEYDrQMjPR2EmnoM1pd4L6cK8r2/KY0I=
-k8s.io/kube-scheduler v0.31.3/go.mod h1:vhDtABcWycLi8139K5ScOg54WKlbEZJRgtQmLhW0Wjo=
-k8s.io/kubectl v0.31.3 h1:3r111pCjPsvnR98oLLxDMwAeM6OPGmPty6gSKaLTQes=
-k8s.io/kubectl v0.31.3/go.mod h1:lhMECDCbJN8He12qcKqs2QfmVo9Pue30geovBVpH5fs=
-k8s.io/kubelet v0.31.3 h1:DIXRAmvVGp42mV2vpA1GCLU6oO8who0/vp3Oq6kSpbI=
-k8s.io/kubelet v0.31.3/go.mod h1:KSdbEfNy5VzqUlAHlytA/fH12s+sE1u8fb/8JY9sL/8=
-k8s.io/kubernetes v1.31.3 h1:oqb7HdfnTelrGlZ6ziNugvQ/L/aJWR704114EAhUn9Q=
-k8s.io/kubernetes v1.31.3/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs=
-k8s.io/mount-utils v0.31.3 h1:CANy3prUYvvDCc2X7ZKgpjpDhAidx4gjGh/WwDrCPq8=
-k8s.io/mount-utils v0.31.3/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU=
-k8s.io/pod-security-admission v0.31.3 h1:8NzEV0HtdStX367AuSKfRMIZHn0hT4xuz8xNEf7/zO8=
-k8s.io/pod-security-admission v0.31.3/go.mod h1:YMIcTe/7f9R9d+3ErCMMM3Wtbj9ejKo7Z9S0OxZQrRg=
+k8s.io/kube-scheduler v0.31.2 h1:OcSTxT7+1WD9rN9154IhA1xbKBoSD2hwSEDXJ7cM81g=
+k8s.io/kube-scheduler v0.31.2/go.mod h1:pG4VnIaQxQ/ADxETxAYNvOHYxT5kzfThWenw58ibPI0=
+k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M=
+k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM=
+k8s.io/kubelet v0.31.2 h1:6Hytyw4LqWqhgzoi7sPfpDGClu2UfxmPmaiXPC4FRgI=
+k8s.io/kubelet v0.31.2/go.mod h1:0E4++3cMWi2cJxOwuaQP3eMBa7PSOvAFgkTPlVc/2FA=
+k8s.io/kubernetes v1.31.2 h1:VNSu4O7Xn5FFRsh9ePXyEPg6ucR21fOftarSdi053Gs=
+k8s.io/kubernetes v1.31.2/go.mod h1:9xmT2buyTYj8TRKwRae7FcuY8k5+xlxv7VivvO0KKfs=
+k8s.io/mount-utils v0.31.2 h1:Q0ygX92Lj9d1wcObAzj+JZ4oE7CNKZrqSOn1XcIS+y4=
+k8s.io/mount-utils v0.31.2/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU=
+k8s.io/pod-security-admission v0.31.2 h1:GQWWShWxYPJSRcMyN3xA1xyYa3ROrAaBBiP9BdIf5Z4=
+k8s.io/pod-security-admission v0.31.2/go.mod h1:LXpZT9KdccDH/We169EycuFC79iXmiU4mgpUEJDrf9Q=
 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
diff --git a/pkg/nfd-gc/metrics.go b/pkg/nfd-gc/metrics.go
index f10ddc02f..bc884808d 100644
--- a/pkg/nfd-gc/metrics.go
+++ b/pkg/nfd-gc/metrics.go
@@ -23,35 +23,27 @@ import (
 
 // When adding metric names, see https://prometheus.io/docs/practices/naming/#metric-names
 const (
-	buildInfoQuery          = "build_info"
-	objectsDeletedQuery     = "objects_deleted_total"
-	objectDeleteErrorsQuery = "object_delete_failures_total"
-)
-
-const (
-	// nfdGCPrefix - subsystem name used by nfd gc.
-	nfdGCPrefix = "nfd_gc"
+	buildInfoQuery          = "nfd_gc_build_info"
+	objectsDeletedQuery     = "nfd_gc_objects_deleted_total"
+	objectDeleteErrorsQuery = "nfd_gc_object_delete_failures_total"
 )
 
 var (
 	buildInfo = prometheus.NewGauge(prometheus.GaugeOpts{
-		Subsystem: nfdGCPrefix,
-		Name:      buildInfoQuery,
-		Help:      "Version from which Node Feature Discovery was built.",
+		Name: buildInfoQuery,
+		Help: "Version from which Node Feature Discovery was built.",
 		ConstLabels: map[string]string{
 			"version": version.Get(),
 		},
 	})
 	objectsDeleted = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Subsystem: nfdGCPrefix,
-		Name:      objectsDeletedQuery,
-		Help:      "Number of NodeFeature and NodeResourceTopology objects garbage collected."},
+		Name: objectsDeletedQuery,
+		Help: "Number of NodeFeature and NodeResourceTopology objects garbage collected."},
 		[]string{"kind"},
 	)
 	objectDeleteErrors = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Subsystem: nfdGCPrefix,
-		Name:      objectDeleteErrorsQuery,
-		Help:      "Number of errors in deleting NodeFeature and NodeResourceTopology objects."},
+		Name: objectDeleteErrorsQuery,
+		Help: "Number of errors in deleting NodeFeature and NodeResourceTopology objects."},
 		[]string{"kind"},
 	)
 )
diff --git a/pkg/nfd-master/metrics.go b/pkg/nfd-master/metrics.go
index 7951432ca..20335f6f0 100644
--- a/pkg/nfd-master/metrics.go
+++ b/pkg/nfd-master/metrics.go
@@ -23,73 +23,59 @@ import (
 
 // When adding metric names, see https://prometheus.io/docs/practices/naming/#metric-names
 const (
-	buildInfoQuery                      = "build_info"
-	nodeUpdateRequestsQuery             = "node_update_requests_total"
-	nodeUpdatesQuery                    = "node_updates_total"
-	nodeFeatureGroupUpdateRequestsQuery = "node_feature_group_update_requests_total"
-	nodeUpdateFailuresQuery             = "node_update_failures_total"
-	nodeLabelsRejectedQuery             = "node_labels_rejected_total"
-	nodeERsRejectedQuery                = "node_extendedresources_rejected_total"
-	nodeTaintsRejectedQuery             = "node_taints_rejected_total"
-	nfrProcessingTimeQuery              = "nodefeaturerule_processing_duration_seconds"
-	nfrProcessingErrorsQuery            = "nodefeaturerule_processing_errors_total"
-)
-
-const (
-	// nfdMasterPrefix - subsystem name used by nfd master.
-	nfdMasterPrefix = "nfd_master"
+	buildInfoQuery                      = "nfd_master_build_info"
+	nodeUpdateRequestsQuery             = "nfd_node_update_requests_total"
+	nodeUpdatesQuery                    = "nfd_node_updates_total"
+	nodeFeatureGroupUpdateRequestsQuery = "nfd_node_feature_group_update_requests_total"
+	nodeUpdateFailuresQuery             = "nfd_node_update_failures_total"
+	nodeLabelsRejectedQuery             = "nfd_node_labels_rejected_total"
+	nodeERsRejectedQuery                = "nfd_node_extendedresources_rejected_total"
+	nodeTaintsRejectedQuery             = "nfd_node_taints_rejected_total"
+	nfrProcessingTimeQuery              = "nfd_nodefeaturerule_processing_duration_seconds"
+	nfrProcessingErrorsQuery            = "nfd_nodefeaturerule_processing_errors_total"
 )
 
 var (
 	buildInfo = prometheus.NewGauge(prometheus.GaugeOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      buildInfoQuery,
-		Help:      "Version from which Node Feature Discovery was built.",
+		Name: buildInfoQuery,
+		Help: "Version from which Node Feature Discovery was built.",
 		ConstLabels: map[string]string{
 			"version": version.Get(),
 		},
 	})
 	nodeUpdateRequests = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeUpdateRequestsQuery,
-		Help:      "Number of node update requests processed by the master.",
+		Name: nodeUpdateRequestsQuery,
+		Help: "Number of node update requests processed by the master.",
 	})
 	nodeFeatureGroupUpdateRequests = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeFeatureGroupUpdateRequestsQuery,
-		Help:      "Number of cluster feature update requests processed by the master.",
+		Name: nodeFeatureGroupUpdateRequestsQuery,
+		Help: "Number of cluster feature update requests processed by the master.",
 	})
 	nodeUpdates = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeUpdatesQuery,
-		Help:      "Number of nodes updated by the master.",
+		Name: nodeUpdatesQuery,
+		Help: "Number of nodes updated by the master.",
 	})
 	nodeUpdateFailures = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeUpdateFailuresQuery,
-		Help:      "Number of node update failures.",
+		Name: nodeUpdateFailuresQuery,
+		Help: "Number of node update failures.",
 	})
 	nodeLabelsRejected = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeLabelsRejectedQuery,
-		Help:      "Number of node labels that were rejected by nfd-master.",
+		Name: nodeLabelsRejectedQuery,
+		Help: "Number of node labels that were rejected by nfd-master.",
 	})
 	nodeERsRejected = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeERsRejectedQuery,
-		Help:      "Number of node extended resources that were rejected by nfd-master.",
+		Name: nodeERsRejectedQuery,
+		Help: "Number of node extended resources that were rejected by nfd-master.",
 	})
 	nodeTaintsRejected = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nodeTaintsRejectedQuery,
-		Help:      "Number of node taints that were rejected by nfd-master.",
+		Name: nodeTaintsRejectedQuery,
+		Help: "Number of node taints that were rejected by nfd-master.",
 	})
 	nfrProcessingTime = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: nfdMasterPrefix,
-			Name:      nfrProcessingTimeQuery,
-			Help:      "Time processing time of NodeFeatureRule objects.",
-			Buckets:   []float64{0.0001, 0.00025, 0.0005, 0.001, 0.0025, 0.005, 0.01},
+			Name:    nfrProcessingTimeQuery,
+			Help:    "Time processing time of NodeFeatureRule objects.",
+			Buckets: []float64{0.0001, 0.00025, 0.0005, 0.001, 0.0025, 0.005, 0.01},
 		},
 		[]string{
 			"name",
@@ -97,9 +83,8 @@ var (
 		},
 	)
 	nfrProcessingErrors = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdMasterPrefix,
-		Name:      nfrProcessingErrorsQuery,
-		Help:      "Number of errors encountered while processing NodeFeatureRule objects.",
+		Name: nfrProcessingErrorsQuery,
+		Help: "Number of errors encountered while processing NodeFeatureRule objects.",
 	})
 )
 
diff --git a/pkg/nfd-topology-updater/metrics.go b/pkg/nfd-topology-updater/metrics.go
index ab62c6e62..978667bb2 100644
--- a/pkg/nfd-topology-updater/metrics.go
+++ b/pkg/nfd-topology-updater/metrics.go
@@ -23,28 +23,21 @@ import (
 
 // When adding metric names, see https://prometheus.io/docs/practices/naming/#metric-names
 const (
-	buildInfoQuery  = "build_info"
-	scanErrorsQuery = "scan_errors_total"
-)
-
-const (
-	// nfdTopologyUpdaterPrefix - subsystem name used by nfd topology updater.
-	nfdTopologyUpdaterPrefix = "nfd_topology_updater"
+	buildInfoQuery  = "nfd_topology_updater_build_info"
+	scanErrorsQuery = "nfd_topology_updater_scan_errors_total"
 )
 
 var (
 	buildInfo = prometheus.NewGauge(prometheus.GaugeOpts{
-		Subsystem: nfdTopologyUpdaterPrefix,
-		Name:      buildInfoQuery,
-		Help:      "Version from which Node Feature Discovery was built.",
+		Name: buildInfoQuery,
+		Help: "Version from which Node Feature Discovery was built.",
 		ConstLabels: map[string]string{
 			"version": version.Get(),
 		},
 	})
 	scanErrors = prometheus.NewCounter(prometheus.CounterOpts{
-		Subsystem: nfdTopologyUpdaterPrefix,
-		Name:      scanErrorsQuery,
-		Help:      "Number of errors in scanning resource allocation of pods.",
+		Name: scanErrorsQuery,
+		Help: "Number of errors in scanning resource allocation of pods.",
 	})
 )
 
diff --git a/pkg/nfd-worker/metrics.go b/pkg/nfd-worker/metrics.go
index 37be314ac..206c4d577 100644
--- a/pkg/nfd-worker/metrics.go
+++ b/pkg/nfd-worker/metrics.go
@@ -23,29 +23,22 @@ import (
 
 // When adding metric names, see https://prometheus.io/docs/practices/naming/#metric-names
 const (
-	buildInfoQuery                = "build_info"
-	featureDiscoveryDurationQuery = "feature_discovery_duration_seconds"
-)
-
-const (
-	// nfdWorkerPrefix - subsystem name used by nfd worker.
-	nfdWorkerPrefix = "nfd_worker"
+	buildInfoQuery                = "nfd_worker_build_info"
+	featureDiscoveryDurationQuery = "nfd_feature_discovery_duration_seconds"
 )
 
 var (
 	featureDiscoveryDuration = prometheus.NewHistogramVec(
 		prometheus.HistogramOpts{
-			Subsystem: nfdWorkerPrefix,
-			Name:      featureDiscoveryDurationQuery,
-			Help:      "Time taken to discover features",
-			Buckets:   []float64{0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1},
+			Name:    featureDiscoveryDurationQuery,
+			Help:    "Time taken to discover features",
+			Buckets: []float64{0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1},
 		},
 		[]string{"node"},
 	)
 	buildInfo = prometheus.NewGauge(prometheus.GaugeOpts{
-		Subsystem: nfdWorkerPrefix,
-		Name:      buildInfoQuery,
-		Help:      "Version from which Node Feature Discovery was built.",
+		Name: buildInfoQuery,
+		Help: "Version from which Node Feature Discovery was built.",
 		ConstLabels: map[string]string{
 			"version": version.Get(),
 		},
diff --git a/pkg/nfd-worker/nfd-worker.go b/pkg/nfd-worker/nfd-worker.go
index 7b5ce4d16..21ececf15 100644
--- a/pkg/nfd-worker/nfd-worker.go
+++ b/pkg/nfd-worker/nfd-worker.go
@@ -78,6 +78,7 @@ type coreConfig struct {
 	Klog           klogutils.KlogConfigOpts
 	LabelWhiteList utils.RegexpVal
 	NoPublish      bool
+	NoOwnerRefs    bool
 	FeatureSources []string
 	Sources        *[]string
 	LabelSources   []string
@@ -98,14 +99,15 @@ type Args struct {
 	Options        string
 	MetricsPort    int
 	GrpcHealthPort int
+	NoOwnerRefs    bool
 
 	Overrides ConfigOverrideArgs
 }
 
 // ConfigOverrideArgs are args that override config file options
 type ConfigOverrideArgs struct {
-	NoPublish *bool
-
+	NoPublish      *bool
+	NoOwnerRefs    *bool
 	FeatureSources *utils.StringSliceVal
 	LabelSources   *utils.StringSliceVal
 }
@@ -265,7 +267,44 @@ func (w *nfdWorker) runFeatureDiscovery() error {
 	return nil
 }
 
-// Run NfdWorker client. Returns if a fatal error is encountered, or, after
+// Set owner ref
+func (w *nfdWorker) setOwnerReference() error {
+	ownerReference := []metav1.OwnerReference{}
+
+	if !w.config.Core.NoOwnerRefs {
+		// Get pod owner reference
+		podName := os.Getenv("POD_NAME")
+		// Add pod owner reference if it exists
+		if podName != "" {
+			if selfPod, err := w.k8sClient.CoreV1().Pods(w.kubernetesNamespace).Get(context.TODO(), podName, metav1.GetOptions{}); err != nil {
+				klog.ErrorS(err, "failed to get self pod, cannot inherit ownerReference for NodeFeature")
+				return err
+			} else {
+				ownerReference = append(ownerReference, selfPod.OwnerReferences...)
+			}
+
+			podUID := os.Getenv("POD_UID")
+			if podUID != "" {
+				ownerReference = append(ownerReference, metav1.OwnerReference{
+					APIVersion: "v1",
+					Kind:       "Pod",
+					Name:       podName,
+					UID:        types.UID(podUID),
+				})
+			} else {
+				klog.InfoS("Cannot append POD ownerReference to NodeFeature, POD_UID not specified")
+			}
+		} else {
+			klog.InfoS("Cannot set NodeFeature owner references, POD_NAME not specified")
+		}
+	}
+
+	w.ownerReference = ownerReference
+
+	return nil
+}
+
+// Run NfdWorker client. Returns an error if a fatal error is encountered, or, after
 // one request if OneShot is set to 'true' in the worker args.
 func (w *nfdWorker) Run() error {
 	klog.InfoS("Node Feature Discovery Worker", "version", version.Get(), "nodeName", utils.NodeName(), "namespace", w.kubernetesNamespace)
@@ -281,37 +320,6 @@ func (w *nfdWorker) Run() error {
 	labelTrigger.Reset(w.config.Core.SleepInterval.Duration)
 	defer labelTrigger.Stop()
 
-	// Create owner ref
-	ownerReference := []metav1.OwnerReference{}
-	// Get pod owner reference
-	podName := os.Getenv("POD_NAME")
-
-	// Add pod owner reference if it exists
-	if podName != "" {
-		if selfPod, err := w.k8sClient.CoreV1().Pods(w.kubernetesNamespace).Get(context.TODO(), podName, metav1.GetOptions{}); err != nil {
-			klog.ErrorS(err, "failed to get self pod, cannot inherit ownerReference for NodeFeature")
-			return err
-		} else {
-			ownerReference = append(ownerReference, selfPod.OwnerReferences...)
-		}
-
-		podUID := os.Getenv("POD_UID")
-		if podUID != "" {
-			ownerReference = append(ownerReference, metav1.OwnerReference{
-				APIVersion: "v1",
-				Kind:       "Pod",
-				Name:       podName,
-				UID:        types.UID(podUID),
-			})
-		} else {
-			klog.InfoS("Cannot append POD ownerReference to NodeFeature, POD_UID not specified")
-		}
-	} else {
-		klog.InfoS("Cannot set NodeFeature owner references, POD_NAME not specified")
-	}
-
-	w.ownerReference = ownerReference
-
 	// Register to metrics server
 	if w.args.MetricsPort > 0 {
 		m := utils.CreateMetricsServer(w.args.MetricsPort,
@@ -466,6 +474,11 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
 		klogV.InfoS("enabled label sources", "labelSources", n)
 	}
 
+	err = w.setOwnerReference()
+	if err != nil {
+		return err
+	}
+
 	return nil
 }
 
@@ -511,6 +524,9 @@ func (w *nfdWorker) configure(filepath string, overrides string) error {
 	if w.args.Overrides.NoPublish != nil {
 		c.Core.NoPublish = *w.args.Overrides.NoPublish
 	}
+	if w.args.Overrides.NoOwnerRefs != nil {
+		c.Core.NoOwnerRefs = *w.args.Overrides.NoOwnerRefs
+	}
 	if w.args.Overrides.FeatureSources != nil {
 		c.Core.FeatureSources = *w.args.Overrides.FeatureSources
 	}
diff --git a/pkg/utils/fswatcher.go b/pkg/utils/fswatcher.go
new file mode 100644
index 000000000..5bc51fc5c
--- /dev/null
+++ b/pkg/utils/fswatcher.go
@@ -0,0 +1,159 @@
+/*
+Copyright 2021 The Kubernetes 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 utils
+
+import (
+	"fmt"
+	"path/filepath"
+	"time"
+
+	"github.com/fsnotify/fsnotify"
+	"k8s.io/klog/v2"
+)
+
+// FsWatcher is a wrapper helper for watching files
+type FsWatcher struct {
+	*fsnotify.Watcher
+
+	Events    chan struct{}
+	ratelimit time.Duration
+	names     []string
+	paths     map[string]struct{}
+}
+
+// CreateFsWatcher creates a new FsWatcher
+func CreateFsWatcher(ratelimit time.Duration, names ...string) (*FsWatcher, error) {
+	w := &FsWatcher{
+		Events:    make(chan struct{}),
+		names:     names,
+		ratelimit: ratelimit,
+	}
+
+	if err := w.reset(names...); err != nil {
+		return nil, err
+	}
+
+	go w.watch()
+
+	return w, nil
+}
+
+// reset resets the file watches
+func (w *FsWatcher) reset(names ...string) error {
+	if err := w.initWatcher(); err != nil {
+		return err
+	}
+	if err := w.add(names...); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (w *FsWatcher) initWatcher() error {
+	if w.Watcher != nil {
+		if err := w.Watcher.Close(); err != nil {
+			return fmt.Errorf("failed to close fsnotify watcher: %w", err)
+		}
+	}
+	w.paths = make(map[string]struct{})
+
+	watcher, err := fsnotify.NewWatcher()
+	if err != nil {
+		w.Watcher = nil
+		return fmt.Errorf("failed to create fsnotify watcher: %w", err)
+	}
+	w.Watcher = watcher
+
+	return nil
+}
+
+func (w *FsWatcher) add(names ...string) error {
+	for _, name := range names {
+		if name == "" {
+			continue
+		}
+
+		added := false
+		// Add watches for all directory components so that we catch e.g. renames
+		// upper in the tree
+		for p := name; ; p = filepath.Dir(p) {
+			if _, ok := w.paths[p]; !ok {
+				if err := w.Add(p); err != nil {
+					klog.V(1).ErrorS(err, "failed to add fsnotify watch", "path", p)
+				} else {
+					klog.V(1).InfoS("added fsnotify watch", "path", p)
+					added = true
+				}
+
+				w.paths[p] = struct{}{}
+			} else {
+				added = true
+			}
+			if filepath.Dir(p) == p {
+				break
+			}
+		}
+		if !added {
+			// Want to be sure that we watch something
+			return fmt.Errorf("failed to add any watch")
+		}
+	}
+
+	return nil
+}
+
+func (w *FsWatcher) watch() {
+	var ratelimiter <-chan time.Time
+	for {
+		select {
+		case e, ok := <-w.Watcher.Events:
+			// Watcher has been closed
+			if !ok {
+				klog.InfoS("watcher closed")
+				return
+			}
+
+			// If any of our paths change
+			name := filepath.Clean(e.Name)
+			if _, ok := w.paths[filepath.Clean(name)]; ok {
+				klog.V(2).InfoS("fsnotify event detected", "path", name, "fsNotifyEvent", e)
+
+				// Rate limiter. In certain filesystem operations we get
+				// numerous events in quick succession
+				ratelimiter = time.After(w.ratelimit)
+			}
+
+		case e, ok := <-w.Watcher.Errors:
+			// Watcher has been closed
+			if !ok {
+				klog.InfoS("watcher closed")
+				return
+			}
+			klog.ErrorS(e, "fswatcher error event detected")
+
+		case <-ratelimiter:
+			// Blindly remove existing watch and add a new one
+			if err := w.reset(w.names...); err != nil {
+				klog.ErrorS(err, "re-trying in 60 seconds")
+				ratelimiter = time.After(60 * time.Second)
+			}
+
+			w.Events <- struct{}{}
+		}
+	}
+}


Test patch:
diff --git a/cmd/nfd-worker/main_test.go b/cmd/nfd-worker/main_test.go
index 3bca6d128..e5f5b24b3 100644
--- a/cmd/nfd-worker/main_test.go
+++ b/cmd/nfd-worker/main_test.go
@@ -43,12 +43,14 @@ func TestParseArgs(t *testing.T) {
 		Convey("When all override args are specified", func() {
 			args := parseArgs(flags,
 				"-no-publish",
+				"-no-owner-refs",
 				"-feature-sources=cpu",
 				"-label-sources=fake1,fake2,fake3")
 
 			Convey("args.sources is set to appropriate values", func() {
 				So(args.Oneshot, ShouldBeFalse)
 				So(*args.Overrides.NoPublish, ShouldBeTrue)
+				So(*args.Overrides.NoOwnerRefs, ShouldBeTrue)
 				So(*args.Overrides.FeatureSources, ShouldResemble, utils.StringSliceVal{"cpu"})
 				So(*args.Overrides.LabelSources, ShouldResemble, utils.StringSliceVal{"fake1", "fake2", "fake3"})
 			})