From be04d3ebdb818cd5a93d1483261965974fd23aea Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Thu, 2 Apr 2026 17:28:13 +0200 Subject: [PATCH 1/5] feat: add NFD API dependency, measurement keys, timeout, and HardwareDetector interface Add NFD API types dependency (sigs.k8s.io/node-feature-discovery/api/nfd@v0.18.3) for GPU hardware detection without driver dependency. New measurement keys: KeyGPUPresent, KeyDriverLoaded, KeyDetectionSource in pkg/measurement/types.go for NFD-based hardware detection results. New timeout: NFDDetectionTimeout (5s) in pkg/defaults/timeouts.go for local sysfs/procfs operations (PCI enumeration and kernel module listing). New interface: HardwareDetector with HardwareInfo type in pkg/collector/gpu/hardware.go for abstracting GPU hardware detection. PCI and NFD constants deferred to Task 1 when they are consumed. New tests: TestHardwareDetectorInterface validates interface contract with mock implementation. NFDDetectionTimeout added to TestTimeoutConstants. Signed-off-by: Carlos Eduardo Arango Gutierrez --- go.mod | 1 + go.sum | 2 + pkg/collector/gpu/hardware.go | 44 ++ pkg/collector/gpu/hardware_test.go | 87 +++ pkg/defaults/timeouts.go | 5 + pkg/defaults/timeouts_test.go | 1 + pkg/measurement/types.go | 5 + vendor/modules.txt | 3 + .../node-feature-discovery/api/nfd/LICENSE | 176 +++++ .../api/nfd/v1alpha1/annotations_labels.go | 80 ++ .../api/nfd/v1alpha1/doc.go | 21 + .../api/nfd/v1alpha1/feature.go | 161 ++++ .../api/nfd/v1alpha1/register.go | 49 ++ .../api/nfd/v1alpha1/types.go | 394 ++++++++++ .../api/nfd/v1alpha1/utils.go | 29 + .../api/nfd/v1alpha1/zz_generated.deepcopy.go | 718 ++++++++++++++++++ 16 files changed, 1776 insertions(+) create mode 100644 pkg/collector/gpu/hardware.go create mode 100644 pkg/collector/gpu/hardware_test.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go create mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go diff --git a/go.mod b/go.mod index 06e825150..ae6f2ea95 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( sigs.k8s.io/controller-runtime v0.23.3 sigs.k8s.io/kustomize/api v0.21.1 sigs.k8s.io/kustomize/kyaml v0.21.1 + sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 sigs.k8s.io/yaml v1.6.0 ) diff --git a/go.sum b/go.sum index f7c5aa684..21237506f 100644 --- a/go.sum +++ b/go.sum @@ -559,6 +559,8 @@ sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs sigs.k8s.io/kustomize/api v0.21.1/go.mod h1:f3wkKByTrgpgltLgySCntrYoq5d3q7aaxveSagwTlwI= sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7fI= sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= +sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 h1:l+ZtPZTdgsdG2POxY7oh7gdk/ML/FLI5VKwSDBl1fyk= +sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3/go.mod h1:XzGgUqDUyV/X+qkXEwG+CgfTUUeZix5iuobsmLoT0Ck= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= diff --git a/pkg/collector/gpu/hardware.go b/pkg/collector/gpu/hardware.go new file mode 100644 index 000000000..324f79a91 --- /dev/null +++ b/pkg/collector/gpu/hardware.go @@ -0,0 +1,44 @@ +// Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gpu + +import ( + "context" + + // Ensure NFD dependency is retained in go.mod for Task 1 (NFDHardwareDetector implementation). + _ "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" +) + +// HardwareDetector abstracts GPU hardware detection for testability. +// Implementations enumerate PCI devices and kernel module state without +// requiring GPU drivers to be installed. +type HardwareDetector interface { + // Detect discovers GPU hardware and driver module state. + // Returns HardwareInfo describing what was found, or an error if + // detection could not be performed (e.g., sysfs not available). + Detect(ctx context.Context) (*HardwareInfo, error) +} + +// HardwareInfo describes the GPU hardware state detected without drivers. +type HardwareInfo struct { + // GPUPresent is true if at least one NVIDIA GPU was found via PCI enumeration. + GPUPresent bool + + // GPUCount is the number of NVIDIA GPUs detected via PCI enumeration. + GPUCount int + + // DriverLoaded is true if the nvidia kernel module is currently loaded. + DriverLoaded bool +} diff --git a/pkg/collector/gpu/hardware_test.go b/pkg/collector/gpu/hardware_test.go new file mode 100644 index 000000000..f5948383e --- /dev/null +++ b/pkg/collector/gpu/hardware_test.go @@ -0,0 +1,87 @@ +// Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gpu + +import ( + "context" + "testing" +) + +// mockHardwareDetector is a test double for the HardwareDetector interface. +type mockHardwareDetector struct { + info *HardwareInfo + err error +} + +func (m *mockHardwareDetector) Detect(_ context.Context) (*HardwareInfo, error) { + return m.info, m.err +} + +func TestHardwareDetectorInterface(t *testing.T) { + tests := []struct { + name string + detector HardwareDetector + wantPresent bool + wantCount int + wantDriver bool + wantErr bool + }{ + { + name: "GPU present with driver", + detector: &mockHardwareDetector{ + info: &HardwareInfo{ + GPUPresent: true, + GPUCount: 2, + DriverLoaded: true, + }, + }, + wantPresent: true, + wantCount: 2, + wantDriver: true, + }, + { + name: "no GPU hardware", + detector: &mockHardwareDetector{ + info: &HardwareInfo{ + GPUPresent: false, + GPUCount: 0, + DriverLoaded: false, + }, + }, + wantPresent: false, + wantCount: 0, + wantDriver: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + info, err := tt.detector.Detect(context.Background()) + if (err != nil) != tt.wantErr { + t.Errorf("Detect() error = %v, wantErr %v", err, tt.wantErr) + return + } + if info.GPUPresent != tt.wantPresent { + t.Errorf("GPUPresent = %v, want %v", info.GPUPresent, tt.wantPresent) + } + if info.GPUCount != tt.wantCount { + t.Errorf("GPUCount = %v, want %v", info.GPUCount, tt.wantCount) + } + if info.DriverLoaded != tt.wantDriver { + t.Errorf("DriverLoaded = %v, want %v", info.DriverLoaded, tt.wantDriver) + } + }) + } +} diff --git a/pkg/defaults/timeouts.go b/pkg/defaults/timeouts.go index 3ed90afdb..940e64abc 100644 --- a/pkg/defaults/timeouts.go +++ b/pkg/defaults/timeouts.go @@ -25,6 +25,11 @@ const ( // CollectorK8sTimeout is the timeout for Kubernetes API calls in collectors. // Covers 6 sequential sub-collectors (server, image, policy, node, helm, argocd). CollectorK8sTimeout = 60 * time.Second + + // NFDDetectionTimeout is the timeout for NFD-based hardware detection. + // PCI enumeration and kernel module listing are fast local operations + // reading from sysfs/procfs, so a short timeout is sufficient. + NFDDetectionTimeout = 5 * time.Second ) // Node topology collector constants. diff --git a/pkg/defaults/timeouts_test.go b/pkg/defaults/timeouts_test.go index cbfe59d82..367207c29 100644 --- a/pkg/defaults/timeouts_test.go +++ b/pkg/defaults/timeouts_test.go @@ -29,6 +29,7 @@ func TestTimeoutConstants(t *testing.T) { // Collector timeouts {"CollectorTimeout", CollectorTimeout, 5 * time.Second, 30 * time.Second}, {"CollectorK8sTimeout", CollectorK8sTimeout, 30 * time.Second, 120 * time.Second}, + {"NFDDetectionTimeout", NFDDetectionTimeout, 1 * time.Second, 15 * time.Second}, {"CollectorTopologyTimeout", CollectorTopologyTimeout, 60 * time.Second, 180 * time.Second}, // Handler timeouts diff --git a/pkg/measurement/types.go b/pkg/measurement/types.go index 45b78d34a..c66a9cefa 100644 --- a/pkg/measurement/types.go +++ b/pkg/measurement/types.go @@ -31,6 +31,11 @@ const ( KeyGPUDriver = "driver" KeyGPUModel = "model" KeyGPUCount = "gpu-count" + + // GPU hardware detection keys (NFD-based, no driver required) + KeyGPUPresent = "gpu-present" + KeyDriverLoaded = "driver-loaded" + KeyDetectionSource = "detection-source" ) // Internal measurement keys used only within this package. diff --git a/vendor/modules.txt b/vendor/modules.txt index d8cbc8afb..a09ffa922 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1407,6 +1407,9 @@ sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/validation/field sigs.k8s.io/kustomize/kyaml/yaml/merge2 sigs.k8s.io/kustomize/kyaml/yaml/schema sigs.k8s.io/kustomize/kyaml/yaml/walk +# sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 +## explicit; go 1.23.0 +sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1 # sigs.k8s.io/randfill v1.0.0 ## explicit; go 1.18 sigs.k8s.io/randfill diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE new file mode 100644 index 000000000..d9a10c0d8 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go new file mode 100644 index 000000000..a447f1dcd --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go @@ -0,0 +1,80 @@ +/* +Copyright 2022 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 v1alpha1 + +const ( + // FeatureLabelNs is the (default) namespace for feature labels. + FeatureLabelNs = "feature.node.kubernetes.io" + + // FeatureLabelSubNsSuffix is the suffix for allowed feature label sub-namespaces. + FeatureLabelSubNsSuffix = "." + FeatureLabelNs + + // ProfileLabelNs is the namespace for profile labels. + ProfileLabelNs = "profile.node.kubernetes.io" + + // ProfileLabelSubNsSuffix is the suffix for allowed profile label sub-namespaces. + ProfileLabelSubNsSuffix = "." + ProfileLabelNs + + // TaintNs is the k8s.io namespace that can be used for NFD-managed taints. + TaintNs = "feature.node.kubernetes.io" + + // TaintSubNsSuffix is the suffix for allowed sub-namespaces for NFD-managed taints. + TaintSubNsSuffix = "." + TaintNs + + // AnnotationNs namespace for all NFD-related annotations. + AnnotationNs = "nfd.node.kubernetes.io" + + // ExtendedResourceNs is the namespace for extended resources. + ExtendedResourceNs = "feature.node.kubernetes.io" + + // ExtendedResourceSubNsSuffix is the suffix for allowed extended resources sub-namespaces. + ExtendedResourceSubNsSuffix = "." + ExtendedResourceNs + + // ExtendedResourceAnnotation is the annotation that holds all extended resources managed by NFD. + ExtendedResourceAnnotation = AnnotationNs + "/extended-resources" + + // FeatureLabelsAnnotation is the annotation that holds all feature labels managed by NFD. + FeatureLabelsAnnotation = AnnotationNs + "/feature-labels" + + // MasterVersionAnnotation is the annotation that holds the version of nfd-master running on the node + // DEPRECATED: will not be used in NFD v0.15 or later. + MasterVersionAnnotation = AnnotationNs + "/master.version" + + // WorkerVersionAnnotation is the annotation that holds the version of nfd-worker running on the node + WorkerVersionAnnotation = AnnotationNs + "/worker.version" + + // NodeTaintsAnnotation is the annotation that holds the taints that nfd-master set on the node + NodeTaintsAnnotation = AnnotationNs + "/taints" + + // FeatureAnnotationsTrackingAnnotation is the annotation that holds all feature annotations that nfd-master set on the node + FeatureAnnotationsTrackingAnnotation = AnnotationNs + "/feature-annotations" + + // NodeFeatureObjNodeNameLabel is the label that specifies which node the + // NodeFeature object is targeting. Creators of NodeFeature objects must + // set this label and consumers of the objects are supposed to use the + // label for filtering features designated for a certain node. + NodeFeatureObjNodeNameLabel = "nfd.node.kubernetes.io/node-name" + + // FeatureAnnotationNs is the (default) namespace for feature annotations. + FeatureAnnotationNs = "feature.node.kubernetes.io" + + // FeatureAnnotationSubNsSuffix is the suffix for allowed feature annotation sub-namespaces. + FeatureAnnotationSubNsSuffix = "." + FeatureAnnotationNs + + // FeatureAnnotationValueSizeLimit is the maximum allowed length for the value of a feature annotation. + FeatureAnnotationValueSizeLimit = 1 << 10 +) diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go new file mode 100644 index 000000000..32b425965 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +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 v1alpha1 is the v1alpha1 version of the nfd API. +// +k8s:deepcopy-gen=package +// +kubebuilder:object:generate=true +// +groupName=nfd.k8s-sigs.io +package v1alpha1 diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go new file mode 100644 index 000000000..1f4f1d074 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go @@ -0,0 +1,161 @@ +/* +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 v1alpha1 + +import "maps" + +// NewNodeFeatureSpec creates a new emprty instance of NodeFeatureSpec type, +// initializing all fields to proper empty values. +func NewNodeFeatureSpec() *NodeFeatureSpec { + return &NodeFeatureSpec{ + Features: *NewFeatures(), + Labels: make(map[string]string), + } +} + +// NewFeatures creates a new instance of Features, initializing all feature +// types (flags, attributes and instances) to empty values. +func NewFeatures() *Features { + return &Features{ + Flags: make(map[string]FlagFeatureSet), + Attributes: make(map[string]AttributeFeatureSet), + Instances: make(map[string]InstanceFeatureSet)} +} + +// NewFlagFeatures creates a new instance of KeyFeatureSet. +func NewFlagFeatures(keys ...string) FlagFeatureSet { + e := make(map[string]Nil, len(keys)) + for _, k := range keys { + e[k] = Nil{} + } + return FlagFeatureSet{Elements: e} +} + +// NewAttributeFeatures creates a new instance of ValueFeatureSet. +func NewAttributeFeatures(values map[string]string) AttributeFeatureSet { + if values == nil { + values = make(map[string]string) + } + return AttributeFeatureSet{Elements: values} +} + +// NewInstanceFeatures creates a new instance of InstanceFeatureSet. +func NewInstanceFeatures(instances ...InstanceFeature) InstanceFeatureSet { + return InstanceFeatureSet{Elements: instances} +} + +// NewInstanceFeature creates a new InstanceFeature instance. +func NewInstanceFeature(attrs map[string]string) *InstanceFeature { + if attrs == nil { + attrs = make(map[string]string) + } + return &InstanceFeature{Attributes: attrs} +} + +// InsertAttributeFeatures inserts new values into a specific feature. +func (f *Features) InsertAttributeFeatures(domain, feature string, values map[string]string) { + if f.Attributes == nil { + f.Attributes = make(map[string]AttributeFeatureSet) + } + key := domain + "." + feature + if _, ok := f.Attributes[key]; !ok { + f.Attributes[key] = NewAttributeFeatures(values) + return + } + + maps.Copy(f.Attributes[key].Elements, values) +} + +// MergeInto merges two FeatureSpecs into one. Data in the input object takes +// precedence (overwrite) over data of the existing object we're merging into. +func (in *NodeFeatureSpec) MergeInto(out *NodeFeatureSpec) { + in.Features.MergeInto(&out.Features) + if in.Labels != nil { + if out.Labels == nil { + out.Labels = make(map[string]string, len(in.Labels)) + } + maps.Copy(out.Labels, in.Labels) + } +} + +// MergeInto merges two sets of features into one. Features from the input set +// take precedence (overwrite) features from the existing features of the set +// we're merging into. +func (in *Features) MergeInto(out *Features) { + if in.Flags != nil { + if out.Flags == nil { + out.Flags = make(map[string]FlagFeatureSet, len(in.Flags)) + } + for key, val := range in.Flags { + outVal := out.Flags[key] + val.MergeInto(&outVal) + out.Flags[key] = outVal + } + } + if in.Attributes != nil { + if out.Attributes == nil { + out.Attributes = make(map[string]AttributeFeatureSet, len(in.Attributes)) + } + for key, val := range in.Attributes { + outVal := out.Attributes[key] + val.MergeInto(&outVal) + out.Attributes[key] = outVal + } + } + if in.Instances != nil { + if out.Instances == nil { + out.Instances = make(map[string]InstanceFeatureSet, len(in.Instances)) + } + for key, val := range in.Instances { + outVal := out.Instances[key] + val.MergeInto(&outVal) + out.Instances[key] = outVal + } + } +} + +// MergeInto merges two sets of flag featues. +func (in *FlagFeatureSet) MergeInto(out *FlagFeatureSet) { + if in.Elements != nil { + if out.Elements == nil { + out.Elements = make(map[string]Nil, len(in.Elements)) + } + maps.Copy(out.Elements, in.Elements) + } +} + +// MergeInto merges two sets of attribute featues. +func (in *AttributeFeatureSet) MergeInto(out *AttributeFeatureSet) { + if in.Elements != nil { + if out.Elements == nil { + out.Elements = make(map[string]string, len(in.Elements)) + } + maps.Copy(out.Elements, in.Elements) + } +} + +// MergeInto merges two sets of instance featues. +func (in *InstanceFeatureSet) MergeInto(out *InstanceFeatureSet) { + if in.Elements != nil { + if out.Elements == nil { + out.Elements = make([]InstanceFeature, 0, len(in.Elements)) + } + for _, e := range in.Elements { + out.Elements = append(out.Elements, *e.DeepCopy()) + } + } +} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go new file mode 100644 index 000000000..9ccfbba25 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go @@ -0,0 +1,49 @@ +/* +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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "nfd.k8s-sigs.io", Version: "v1alpha1"} + + // SchemeBuilder is the scheme builder for this API. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme is a function to register this API group and version to a scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +// Resource takes an unqualified resource name and returns a Group qualified GroupResource. +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &NodeFeature{}, + &NodeFeatureRule{}, + &NodeFeatureGroup{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go new file mode 100644 index 000000000..41b7e3e90 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go @@ -0,0 +1,394 @@ +/* +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 v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NodeFeatureList contains a list of NodeFeature objects. +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NodeFeatureList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + // List of NodeFeatures. + Items []NodeFeature `json:"items"` +} + +// NodeFeature resource holds the features discovered for one node in the +// cluster. +// +kubebuilder:object:root=true +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NodeFeature struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Specification of the NodeFeature, containing features discovered for a node. + Spec NodeFeatureSpec `json:"spec"` +} + +// NodeFeatureSpec describes a NodeFeature object. +type NodeFeatureSpec struct { + // Features is the full "raw" features data that has been discovered. + // +optional + Features Features `json:"features"` + // Labels is the set of node labels that are requested to be created. + // +optional + Labels map[string]string `json:"labels"` +} + +// Features is the collection of all discovered features. +type Features struct { + // Flags contains all the flag-type features of the node. + // +optional + Flags map[string]FlagFeatureSet `json:"flags"` + // Attributes contains all the attribute-type features of the node. + // +optional + Attributes map[string]AttributeFeatureSet `json:"attributes"` + // Instances contains all the instance-type features of the node. + // +optional + Instances map[string]InstanceFeatureSet `json:"instances"` +} + +// FlagFeatureSet is a set of simple features only containing names without values. +type FlagFeatureSet struct { + // Individual features of the feature set. + Elements map[string]Nil `json:"elements"` +} + +// AttributeFeatureSet is a set of features having string value. +type AttributeFeatureSet struct { + // Individual features of the feature set. + Elements map[string]string `json:"elements"` +} + +// InstanceFeatureSet is a set of features each of which is an instance having multiple attributes. +type InstanceFeatureSet struct { + // Individual features of the feature set. + Elements []InstanceFeature `json:"elements"` +} + +// InstanceFeature represents one instance of a complex features, e.g. a device. +type InstanceFeature struct { + // Attributes of the instance feature. + Attributes map[string]string `json:"attributes"` +} + +// Nil is a dummy empty struct for protobuf compatibility. +// NOTE: protobuf definitions have been removed but this is kept for API compatibility. +type Nil struct{} + +// NodeFeatureRuleList contains a list of NodeFeatureRule objects. +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NodeFeatureRuleList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + // List of NodeFeatureRules. + Items []NodeFeatureRule `json:"items"` +} + +// NodeFeatureRule resource specifies a configuration for feature-based +// customization of node objects, such as node labeling. +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Cluster,shortName=nfr +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient +// +genclient:nonNamespaced +type NodeFeatureRule struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the rules to be evaluated. + Spec NodeFeatureRuleSpec `json:"spec"` +} + +// NodeFeatureRuleSpec describes a NodeFeatureRule. +type NodeFeatureRuleSpec struct { + // Rules is a list of node customization rules. + Rules []Rule `json:"rules"` +} + +// NodeFeatureGroup resource holds Node pools by featureGroup +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Namespaced,shortName=nfg +// +kubebuilder:subresource:status +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient +type NodeFeatureGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the rules to be evaluated. + Spec NodeFeatureGroupSpec `json:"spec"` + + // Status of the NodeFeatureGroup after the most recent evaluation of the + // specification. + Status NodeFeatureGroupStatus `json:"status,omitempty"` +} + +// NodeFeatureGroupSpec describes a NodeFeatureGroup object. +type NodeFeatureGroupSpec struct { + // List of rules to evaluate to determine nodes that belong in this group. + Rules []GroupRule `json:"featureGroupRules"` +} + +type NodeFeatureGroupStatus struct { + // Nodes is a list of FeatureGroupNode in the cluster that match the featureGroupRules + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + Nodes []FeatureGroupNode `json:"nodes"` +} + +type FeatureGroupNode struct { + // Name of the node. + Name string `json:"name"` +} + +// NodeFeatureGroupList contains a list of NodeFeatureGroup objects. +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type NodeFeatureGroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + // List of NodeFeatureGroups. + Items []NodeFeatureGroup `json:"items"` +} + +// GroupRule defines a rule for nodegroup filtering. +type GroupRule struct { + // Name of the rule. + Name string `json:"name"` + + // Vars is the variables to store if the rule matches. Variables can be + // referenced from other rules enabling more complex rule hierarchies. + // +optional + Vars map[string]string `json:"vars"` + + // VarsTemplate specifies a template to expand for dynamically generating + // multiple variables. Data (after template expansion) must be keys with an + // optional value ([=]) separated by newlines. + // +optional + VarsTemplate string `json:"varsTemplate"` + + // MatchFeatures specifies a set of matcher terms all of which must match. + // +optional + MatchFeatures FeatureMatcher `json:"matchFeatures"` + + // MatchAny specifies a list of matchers one of which must match. + // +optional + MatchAny []MatchAnyElem `json:"matchAny"` +} + +// Rule defines a rule for node customization such as labeling. +type Rule struct { + // Name of the rule. + Name string `json:"name"` + + // Labels to create if the rule matches. + // +optional + Labels map[string]string `json:"labels"` + + // LabelsTemplate specifies a template to expand for dynamically generating + // multiple labels. Data (after template expansion) must be keys with an + // optional value ([=]) separated by newlines. + // +optional + LabelsTemplate string `json:"labelsTemplate"` + + // Annotations to create if the rule matches. + // +optional + Annotations map[string]string `json:"annotations"` + + // Vars is the variables to store if the rule matches. Variables do not + // directly inflict any changes in the node object. However, they can be + // referenced from other rules enabling more complex rule hierarchies, + // without exposing intermediary output values as labels. + // +optional + Vars map[string]string `json:"vars"` + + // VarsTemplate specifies a template to expand for dynamically generating + // multiple variables. Data (after template expansion) must be keys with an + // optional value ([=]) separated by newlines. + // +optional + VarsTemplate string `json:"varsTemplate"` + + // Taints to create if the rule matches. + // +optional + Taints []corev1.Taint `json:"taints,omitempty"` + + // ExtendedResources to create if the rule matches. + // +optional + ExtendedResources map[string]string `json:"extendedResources"` + + // MatchFeatures specifies a set of matcher terms all of which must match. + // +optional + MatchFeatures FeatureMatcher `json:"matchFeatures"` + + // MatchAny specifies a list of matchers one of which must match. + // +optional + MatchAny []MatchAnyElem `json:"matchAny"` +} + +// MatchAnyElem specifies one sub-matcher of MatchAny. +type MatchAnyElem struct { + // MatchFeatures specifies a set of matcher terms all of which must match. + MatchFeatures FeatureMatcher `json:"matchFeatures"` +} + +// FeatureMatcher specifies a set of feature matcher terms (i.e. per-feature +// matchers), all of which must match. +type FeatureMatcher []FeatureMatcherTerm + +// FeatureMatcherTerm defines requirements against one feature set. All +// requirements (specified as MatchExpressions) are evaluated against each +// element in the feature set. +type FeatureMatcherTerm struct { + // Feature is the name of the feature set to match against. + Feature string `json:"feature"` + // MatchExpressions is the set of per-element expressions evaluated. These + // match against the value of the specified elements. + // +optional + MatchExpressions *MatchExpressionSet `json:"matchExpressions"` + // MatchName in an expression that is matched against the name of each + // element in the feature set. + // +optional + MatchName *MatchExpression `json:"matchName"` +} + +// MatchExpressionSet contains a set of MatchExpressions, each of which is +// evaluated against a set of input values. +type MatchExpressionSet map[string]*MatchExpression + +// MatchExpression specifies an expression to evaluate against a set of input +// values. It contains an operator that is applied when matching the input and +// an array of values that the operator evaluates the input against. +type MatchExpression struct { + // Op is the operator to be applied. + Op MatchOp `json:"op"` + + // Value is the list of values that the operand evaluates the input + // against. Value should be empty if the operator is Exists, DoesNotExist, + // IsTrue or IsFalse. Value should contain exactly one element if the + // operator is Gt or Lt and exactly two elements if the operator is GtLt. + // In other cases Value should contain at least one element. + // +optional + Value MatchValue `json:"value,omitempty"` + + // Type defines the value type for specific operators. + // The currently supported type is 'version' for Gt,Ge,Lt,Le,GtLt,GeLe operators. + // +optional + Type ValueType `json:"type,omitempty"` +} + +// MatchOp is the match operator that is applied on values when evaluating a +// MatchExpression. +// +kubebuilder:validation:Enum="In";"NotIn";"InRegexp";"Exists";"DoesNotExist";"Gt";"Ge";"Lt";"Le";"GtLt";"GeLe";"IsTrue";"IsFalse" +type MatchOp string + +// MatchValue is the list of values associated with a MatchExpression. +type MatchValue []string + +// ValueType represents the type of value in the expression. +type ValueType string + +const ( + // TypeEmpty is a default value for the expression type. + TypeEmpty ValueType = "" + // TypeVersion represents a version with the following supported formats (major.minor.patch): + // %d.%d.%d (e.g., 1.2.3), + // %d.%d (e.g., 1.2), + // %d (e.g., 1) + TypeVersion ValueType = "version" +) + +const ( + // MatchAny returns always true. + MatchAny MatchOp = "" + // MatchIn returns true if any of the values stored in the expression is + // equal to the input. + MatchIn MatchOp = "In" + // MatchNotIn returns true if none of the values in the expression are + // equal to the input. + MatchNotIn MatchOp = "NotIn" + // MatchInRegexp treats values of the expression as regular expressions and + // returns true if any of them matches the input. + MatchInRegexp MatchOp = "InRegexp" + // MatchExists returns true if the input is valid. The expression must not + // have any values. + MatchExists MatchOp = "Exists" + // MatchDoesNotExist returns true if the input is not valid. The expression + // must not have any values. + MatchDoesNotExist MatchOp = "DoesNotExist" + // MatchGt returns true if the input is greater than the value of the + // expression (number of values in the expression must be exactly one). + // Both the input and value must be integer numbers, otherwise an error is + // returned. + MatchGt MatchOp = "Gt" + // MatchGe returns true if the input is greater than or equal to the value of the + // expression (number of values in the expression must be exactly one). + // Both the input and value must be integer numbers, otherwise an error is + // returned. + MatchGe MatchOp = "Ge" + // MatchLt returns true if the input is less than the value of the + // expression (number of values in the expression must be exactly one). + // Both the input and value must be integer numbers, otherwise an error is + // returned. + MatchLt MatchOp = "Lt" + // MatchLe returns true if the input is less than or equal to the value of the + // expression (number of values in the expression must be exactly one). + // Both the input and value must be integer numbers, otherwise an error is + // returned. + MatchLe MatchOp = "Le" + // MatchGtLt returns true if the input is between two values, i.e. greater + // than the first value and less than the second value of the expression + // (number of values in the expression must be exactly two). Both the input + // and values must be integer numbers, otherwise an error is returned. + MatchGtLt MatchOp = "GtLt" + // MatchGeLe returns true if the input is between two values including the boundary values, + // i.e. greater than or equal to the first value and less than or equal to the second value + // of the expression (number of values in the expression must be exactly two). Both the input + // and values must be integer numbers, otherwise an error is returned. + MatchGeLe MatchOp = "GeLe" + // MatchIsTrue returns true if the input holds the value "true". The + // expression must not have any values. + MatchIsTrue MatchOp = "IsTrue" + // MatchIsFalse returns true if the input holds the value "false". The + // expression must not have any values. + MatchIsFalse MatchOp = "IsFalse" +) + +const ( + // RuleBackrefDomain is the special feature domain for backreferencing + // output of preceding rules. + RuleBackrefDomain = "rule" + // RuleBackrefFeature is the special feature name for backreferencing + // output of preceding rules. + RuleBackrefFeature = "matched" +) + +// MatchAllNames is a special key in MatchExpressionSet to use field names +// (keys from the input) instead of values when matching. +const MatchAllNames = "*" diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go new file mode 100644 index 000000000..49c34a426 --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go @@ -0,0 +1,29 @@ +/* +Copyright 2024 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 v1alpha1 + +import ( + "fmt" +) + +// String represents the match expression as a string type. +func (m MatchExpression) String() string { + if len(m.Value) < 1 { + return fmt.Sprintf("{op: %q}", m.Op) + } + return fmt.Sprintf("{op: %q, value: %q}", m.Op, m.Value) +} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..75d71cbdc --- /dev/null +++ b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,718 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2025 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AttributeFeatureSet) DeepCopyInto(out *AttributeFeatureSet) { + *out = *in + if in.Elements != nil { + in, out := &in.Elements, &out.Elements + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttributeFeatureSet. +func (in *AttributeFeatureSet) DeepCopy() *AttributeFeatureSet { + if in == nil { + return nil + } + out := new(AttributeFeatureSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FeatureGroupNode) DeepCopyInto(out *FeatureGroupNode) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureGroupNode. +func (in *FeatureGroupNode) DeepCopy() *FeatureGroupNode { + if in == nil { + return nil + } + out := new(FeatureGroupNode) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in FeatureMatcher) DeepCopyInto(out *FeatureMatcher) { + { + in := &in + *out = make(FeatureMatcher, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcher. +func (in FeatureMatcher) DeepCopy() FeatureMatcher { + if in == nil { + return nil + } + out := new(FeatureMatcher) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FeatureMatcherTerm) DeepCopyInto(out *FeatureMatcherTerm) { + *out = *in + if in.MatchExpressions != nil { + in, out := &in.MatchExpressions, &out.MatchExpressions + *out = new(MatchExpressionSet) + if **in != nil { + in, out := *in, *out + *out = make(map[string]*MatchExpression, len(*in)) + for key, val := range *in { + var outVal *MatchExpression + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(MatchExpression) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } + } + if in.MatchName != nil { + in, out := &in.MatchName, &out.MatchName + *out = new(MatchExpression) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcherTerm. +func (in *FeatureMatcherTerm) DeepCopy() *FeatureMatcherTerm { + if in == nil { + return nil + } + out := new(FeatureMatcherTerm) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Features) DeepCopyInto(out *Features) { + *out = *in + if in.Flags != nil { + in, out := &in.Flags, &out.Flags + *out = make(map[string]FlagFeatureSet, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(map[string]AttributeFeatureSet, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make(map[string]InstanceFeatureSet, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features. +func (in *Features) DeepCopy() *Features { + if in == nil { + return nil + } + out := new(Features) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FlagFeatureSet) DeepCopyInto(out *FlagFeatureSet) { + *out = *in + if in.Elements != nil { + in, out := &in.Elements, &out.Elements + *out = make(map[string]Nil, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagFeatureSet. +func (in *FlagFeatureSet) DeepCopy() *FlagFeatureSet { + if in == nil { + return nil + } + out := new(FlagFeatureSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupRule) DeepCopyInto(out *GroupRule) { + *out = *in + if in.Vars != nil { + in, out := &in.Vars, &out.Vars + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MatchFeatures != nil { + in, out := &in.MatchFeatures, &out.MatchFeatures + *out = make(FeatureMatcher, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MatchAny != nil { + in, out := &in.MatchAny, &out.MatchAny + *out = make([]MatchAnyElem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupRule. +func (in *GroupRule) DeepCopy() *GroupRule { + if in == nil { + return nil + } + out := new(GroupRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceFeature) DeepCopyInto(out *InstanceFeature) { + *out = *in + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeature. +func (in *InstanceFeature) DeepCopy() *InstanceFeature { + if in == nil { + return nil + } + out := new(InstanceFeature) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceFeatureSet) DeepCopyInto(out *InstanceFeatureSet) { + *out = *in + if in.Elements != nil { + in, out := &in.Elements, &out.Elements + *out = make([]InstanceFeature, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeatureSet. +func (in *InstanceFeatureSet) DeepCopy() *InstanceFeatureSet { + if in == nil { + return nil + } + out := new(InstanceFeatureSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchAnyElem) DeepCopyInto(out *MatchAnyElem) { + *out = *in + if in.MatchFeatures != nil { + in, out := &in.MatchFeatures, &out.MatchFeatures + *out = make(FeatureMatcher, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchAnyElem. +func (in *MatchAnyElem) DeepCopy() *MatchAnyElem { + if in == nil { + return nil + } + out := new(MatchAnyElem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchExpression) DeepCopyInto(out *MatchExpression) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = make(MatchValue, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpression. +func (in *MatchExpression) DeepCopy() *MatchExpression { + if in == nil { + return nil + } + out := new(MatchExpression) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in MatchExpressionSet) DeepCopyInto(out *MatchExpressionSet) { + { + in := &in + *out = make(MatchExpressionSet, len(*in)) + for key, val := range *in { + var outVal *MatchExpression + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(MatchExpression) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpressionSet. +func (in MatchExpressionSet) DeepCopy() MatchExpressionSet { + if in == nil { + return nil + } + out := new(MatchExpressionSet) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in MatchValue) DeepCopyInto(out *MatchValue) { + { + in := &in + *out = make(MatchValue, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchValue. +func (in MatchValue) DeepCopy() MatchValue { + if in == nil { + return nil + } + out := new(MatchValue) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Nil) DeepCopyInto(out *Nil) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nil. +func (in *Nil) DeepCopy() *Nil { + if in == nil { + return nil + } + out := new(Nil) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeature) DeepCopyInto(out *NodeFeature) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeature. +func (in *NodeFeature) DeepCopy() *NodeFeature { + if in == nil { + return nil + } + out := new(NodeFeature) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeature) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureGroup) DeepCopyInto(out *NodeFeatureGroup) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroup. +func (in *NodeFeatureGroup) DeepCopy() *NodeFeatureGroup { + if in == nil { + return nil + } + out := new(NodeFeatureGroup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureGroup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureGroupList) DeepCopyInto(out *NodeFeatureGroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeFeatureGroup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupList. +func (in *NodeFeatureGroupList) DeepCopy() *NodeFeatureGroupList { + if in == nil { + return nil + } + out := new(NodeFeatureGroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureGroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureGroupSpec) DeepCopyInto(out *NodeFeatureGroupSpec) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]GroupRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupSpec. +func (in *NodeFeatureGroupSpec) DeepCopy() *NodeFeatureGroupSpec { + if in == nil { + return nil + } + out := new(NodeFeatureGroupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureGroupStatus) DeepCopyInto(out *NodeFeatureGroupStatus) { + *out = *in + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]FeatureGroupNode, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupStatus. +func (in *NodeFeatureGroupStatus) DeepCopy() *NodeFeatureGroupStatus { + if in == nil { + return nil + } + out := new(NodeFeatureGroupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureList) DeepCopyInto(out *NodeFeatureList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeFeature, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureList. +func (in *NodeFeatureList) DeepCopy() *NodeFeatureList { + if in == nil { + return nil + } + out := new(NodeFeatureList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureRule) DeepCopyInto(out *NodeFeatureRule) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRule. +func (in *NodeFeatureRule) DeepCopy() *NodeFeatureRule { + if in == nil { + return nil + } + out := new(NodeFeatureRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureRule) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureRuleList) DeepCopyInto(out *NodeFeatureRuleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeFeatureRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleList. +func (in *NodeFeatureRuleList) DeepCopy() *NodeFeatureRuleList { + if in == nil { + return nil + } + out := new(NodeFeatureRuleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeFeatureRuleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureRuleSpec) DeepCopyInto(out *NodeFeatureRuleSpec) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]Rule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleSpec. +func (in *NodeFeatureRuleSpec) DeepCopy() *NodeFeatureRuleSpec { + if in == nil { + return nil + } + out := new(NodeFeatureRuleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeFeatureSpec) DeepCopyInto(out *NodeFeatureSpec) { + *out = *in + in.Features.DeepCopyInto(&out.Features) + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureSpec. +func (in *NodeFeatureSpec) DeepCopy() *NodeFeatureSpec { + if in == nil { + return nil + } + out := new(NodeFeatureSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Rule) DeepCopyInto(out *Rule) { + *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Vars != nil { + in, out := &in.Vars, &out.Vars + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Taints != nil { + in, out := &in.Taints, &out.Taints + *out = make([]v1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExtendedResources != nil { + in, out := &in.ExtendedResources, &out.ExtendedResources + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MatchFeatures != nil { + in, out := &in.MatchFeatures, &out.MatchFeatures + *out = make(FeatureMatcher, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MatchAny != nil { + in, out := &in.MatchAny, &out.MatchAny + *out = make([]MatchAnyElem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. +func (in *Rule) DeepCopy() *Rule { + if in == nil { + return nil + } + out := new(Rule) + in.DeepCopyInto(out) + return out +} From 0358c03a7a5509f0cfcad64fbd3d3a6c92297510 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Fri, 3 Apr 2026 10:45:46 +0200 Subject: [PATCH 2/5] fix: remove blank NFD import to avoid init() side-effects The blank import of sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1 executes K8s scheme registration init() functions in every binary. The NFD dependency will be added in Task 1 when actual code uses it. Addresses reviewer feedback: critical finding. Signed-off-by: Carlos Eduardo Arango Gutierrez --- go.mod | 1 - go.sum | 2 - pkg/collector/gpu/hardware.go | 7 +- vendor/modules.txt | 3 - .../node-feature-discovery/api/nfd/LICENSE | 176 ----- .../api/nfd/v1alpha1/annotations_labels.go | 80 -- .../api/nfd/v1alpha1/doc.go | 21 - .../api/nfd/v1alpha1/feature.go | 161 ---- .../api/nfd/v1alpha1/register.go | 49 -- .../api/nfd/v1alpha1/types.go | 394 ---------- .../api/nfd/v1alpha1/utils.go | 29 - .../api/nfd/v1alpha1/zz_generated.deepcopy.go | 718 ------------------ 12 files changed, 1 insertion(+), 1640 deletions(-) delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go delete mode 100644 vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go diff --git a/go.mod b/go.mod index ae6f2ea95..06e825150 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,6 @@ require ( sigs.k8s.io/controller-runtime v0.23.3 sigs.k8s.io/kustomize/api v0.21.1 sigs.k8s.io/kustomize/kyaml v0.21.1 - sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 sigs.k8s.io/yaml v1.6.0 ) diff --git a/go.sum b/go.sum index 21237506f..f7c5aa684 100644 --- a/go.sum +++ b/go.sum @@ -559,8 +559,6 @@ sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs sigs.k8s.io/kustomize/api v0.21.1/go.mod h1:f3wkKByTrgpgltLgySCntrYoq5d3q7aaxveSagwTlwI= sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7fI= sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= -sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 h1:l+ZtPZTdgsdG2POxY7oh7gdk/ML/FLI5VKwSDBl1fyk= -sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3/go.mod h1:XzGgUqDUyV/X+qkXEwG+CgfTUUeZix5iuobsmLoT0Ck= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= diff --git a/pkg/collector/gpu/hardware.go b/pkg/collector/gpu/hardware.go index 324f79a91..3a79ab89c 100644 --- a/pkg/collector/gpu/hardware.go +++ b/pkg/collector/gpu/hardware.go @@ -14,12 +14,7 @@ package gpu -import ( - "context" - - // Ensure NFD dependency is retained in go.mod for Task 1 (NFDHardwareDetector implementation). - _ "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1" -) +import "context" // HardwareDetector abstracts GPU hardware detection for testability. // Implementations enumerate PCI devices and kernel module state without diff --git a/vendor/modules.txt b/vendor/modules.txt index a09ffa922..d8cbc8afb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1407,9 +1407,6 @@ sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/validation/field sigs.k8s.io/kustomize/kyaml/yaml/merge2 sigs.k8s.io/kustomize/kyaml/yaml/schema sigs.k8s.io/kustomize/kyaml/yaml/walk -# sigs.k8s.io/node-feature-discovery/api/nfd v0.18.3 -## explicit; go 1.23.0 -sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1 # sigs.k8s.io/randfill v1.0.0 ## explicit; go 1.18 sigs.k8s.io/randfill diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE deleted file mode 100644 index d9a10c0d8..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go deleted file mode 100644 index a447f1dcd..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/annotations_labels.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2022 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 v1alpha1 - -const ( - // FeatureLabelNs is the (default) namespace for feature labels. - FeatureLabelNs = "feature.node.kubernetes.io" - - // FeatureLabelSubNsSuffix is the suffix for allowed feature label sub-namespaces. - FeatureLabelSubNsSuffix = "." + FeatureLabelNs - - // ProfileLabelNs is the namespace for profile labels. - ProfileLabelNs = "profile.node.kubernetes.io" - - // ProfileLabelSubNsSuffix is the suffix for allowed profile label sub-namespaces. - ProfileLabelSubNsSuffix = "." + ProfileLabelNs - - // TaintNs is the k8s.io namespace that can be used for NFD-managed taints. - TaintNs = "feature.node.kubernetes.io" - - // TaintSubNsSuffix is the suffix for allowed sub-namespaces for NFD-managed taints. - TaintSubNsSuffix = "." + TaintNs - - // AnnotationNs namespace for all NFD-related annotations. - AnnotationNs = "nfd.node.kubernetes.io" - - // ExtendedResourceNs is the namespace for extended resources. - ExtendedResourceNs = "feature.node.kubernetes.io" - - // ExtendedResourceSubNsSuffix is the suffix for allowed extended resources sub-namespaces. - ExtendedResourceSubNsSuffix = "." + ExtendedResourceNs - - // ExtendedResourceAnnotation is the annotation that holds all extended resources managed by NFD. - ExtendedResourceAnnotation = AnnotationNs + "/extended-resources" - - // FeatureLabelsAnnotation is the annotation that holds all feature labels managed by NFD. - FeatureLabelsAnnotation = AnnotationNs + "/feature-labels" - - // MasterVersionAnnotation is the annotation that holds the version of nfd-master running on the node - // DEPRECATED: will not be used in NFD v0.15 or later. - MasterVersionAnnotation = AnnotationNs + "/master.version" - - // WorkerVersionAnnotation is the annotation that holds the version of nfd-worker running on the node - WorkerVersionAnnotation = AnnotationNs + "/worker.version" - - // NodeTaintsAnnotation is the annotation that holds the taints that nfd-master set on the node - NodeTaintsAnnotation = AnnotationNs + "/taints" - - // FeatureAnnotationsTrackingAnnotation is the annotation that holds all feature annotations that nfd-master set on the node - FeatureAnnotationsTrackingAnnotation = AnnotationNs + "/feature-annotations" - - // NodeFeatureObjNodeNameLabel is the label that specifies which node the - // NodeFeature object is targeting. Creators of NodeFeature objects must - // set this label and consumers of the objects are supposed to use the - // label for filtering features designated for a certain node. - NodeFeatureObjNodeNameLabel = "nfd.node.kubernetes.io/node-name" - - // FeatureAnnotationNs is the (default) namespace for feature annotations. - FeatureAnnotationNs = "feature.node.kubernetes.io" - - // FeatureAnnotationSubNsSuffix is the suffix for allowed feature annotation sub-namespaces. - FeatureAnnotationSubNsSuffix = "." + FeatureAnnotationNs - - // FeatureAnnotationValueSizeLimit is the maximum allowed length for the value of a feature annotation. - FeatureAnnotationValueSizeLimit = 1 << 10 -) diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go deleted file mode 100644 index 32b425965..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -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 v1alpha1 is the v1alpha1 version of the nfd API. -// +k8s:deepcopy-gen=package -// +kubebuilder:object:generate=true -// +groupName=nfd.k8s-sigs.io -package v1alpha1 diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go deleted file mode 100644 index 1f4f1d074..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/feature.go +++ /dev/null @@ -1,161 +0,0 @@ -/* -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 v1alpha1 - -import "maps" - -// NewNodeFeatureSpec creates a new emprty instance of NodeFeatureSpec type, -// initializing all fields to proper empty values. -func NewNodeFeatureSpec() *NodeFeatureSpec { - return &NodeFeatureSpec{ - Features: *NewFeatures(), - Labels: make(map[string]string), - } -} - -// NewFeatures creates a new instance of Features, initializing all feature -// types (flags, attributes and instances) to empty values. -func NewFeatures() *Features { - return &Features{ - Flags: make(map[string]FlagFeatureSet), - Attributes: make(map[string]AttributeFeatureSet), - Instances: make(map[string]InstanceFeatureSet)} -} - -// NewFlagFeatures creates a new instance of KeyFeatureSet. -func NewFlagFeatures(keys ...string) FlagFeatureSet { - e := make(map[string]Nil, len(keys)) - for _, k := range keys { - e[k] = Nil{} - } - return FlagFeatureSet{Elements: e} -} - -// NewAttributeFeatures creates a new instance of ValueFeatureSet. -func NewAttributeFeatures(values map[string]string) AttributeFeatureSet { - if values == nil { - values = make(map[string]string) - } - return AttributeFeatureSet{Elements: values} -} - -// NewInstanceFeatures creates a new instance of InstanceFeatureSet. -func NewInstanceFeatures(instances ...InstanceFeature) InstanceFeatureSet { - return InstanceFeatureSet{Elements: instances} -} - -// NewInstanceFeature creates a new InstanceFeature instance. -func NewInstanceFeature(attrs map[string]string) *InstanceFeature { - if attrs == nil { - attrs = make(map[string]string) - } - return &InstanceFeature{Attributes: attrs} -} - -// InsertAttributeFeatures inserts new values into a specific feature. -func (f *Features) InsertAttributeFeatures(domain, feature string, values map[string]string) { - if f.Attributes == nil { - f.Attributes = make(map[string]AttributeFeatureSet) - } - key := domain + "." + feature - if _, ok := f.Attributes[key]; !ok { - f.Attributes[key] = NewAttributeFeatures(values) - return - } - - maps.Copy(f.Attributes[key].Elements, values) -} - -// MergeInto merges two FeatureSpecs into one. Data in the input object takes -// precedence (overwrite) over data of the existing object we're merging into. -func (in *NodeFeatureSpec) MergeInto(out *NodeFeatureSpec) { - in.Features.MergeInto(&out.Features) - if in.Labels != nil { - if out.Labels == nil { - out.Labels = make(map[string]string, len(in.Labels)) - } - maps.Copy(out.Labels, in.Labels) - } -} - -// MergeInto merges two sets of features into one. Features from the input set -// take precedence (overwrite) features from the existing features of the set -// we're merging into. -func (in *Features) MergeInto(out *Features) { - if in.Flags != nil { - if out.Flags == nil { - out.Flags = make(map[string]FlagFeatureSet, len(in.Flags)) - } - for key, val := range in.Flags { - outVal := out.Flags[key] - val.MergeInto(&outVal) - out.Flags[key] = outVal - } - } - if in.Attributes != nil { - if out.Attributes == nil { - out.Attributes = make(map[string]AttributeFeatureSet, len(in.Attributes)) - } - for key, val := range in.Attributes { - outVal := out.Attributes[key] - val.MergeInto(&outVal) - out.Attributes[key] = outVal - } - } - if in.Instances != nil { - if out.Instances == nil { - out.Instances = make(map[string]InstanceFeatureSet, len(in.Instances)) - } - for key, val := range in.Instances { - outVal := out.Instances[key] - val.MergeInto(&outVal) - out.Instances[key] = outVal - } - } -} - -// MergeInto merges two sets of flag featues. -func (in *FlagFeatureSet) MergeInto(out *FlagFeatureSet) { - if in.Elements != nil { - if out.Elements == nil { - out.Elements = make(map[string]Nil, len(in.Elements)) - } - maps.Copy(out.Elements, in.Elements) - } -} - -// MergeInto merges two sets of attribute featues. -func (in *AttributeFeatureSet) MergeInto(out *AttributeFeatureSet) { - if in.Elements != nil { - if out.Elements == nil { - out.Elements = make(map[string]string, len(in.Elements)) - } - maps.Copy(out.Elements, in.Elements) - } -} - -// MergeInto merges two sets of instance featues. -func (in *InstanceFeatureSet) MergeInto(out *InstanceFeatureSet) { - if in.Elements != nil { - if out.Elements == nil { - out.Elements = make([]InstanceFeature, 0, len(in.Elements)) - } - for _, e := range in.Elements { - out.Elements = append(out.Elements, *e.DeepCopy()) - } - } -} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go deleted file mode 100644 index 9ccfbba25..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/register.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -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 v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "nfd.k8s-sigs.io", Version: "v1alpha1"} - - // SchemeBuilder is the scheme builder for this API. - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - - // AddToScheme is a function to register this API group and version to a scheme. - AddToScheme = SchemeBuilder.AddToScheme -) - -// Resource takes an unqualified resource name and returns a Group qualified GroupResource. -func Resource(resource string) schema.GroupResource { - return SchemeGroupVersion.WithResource(resource).GroupResource() -} - -func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &NodeFeature{}, - &NodeFeatureRule{}, - &NodeFeatureGroup{}, - ) - metav1.AddToGroupVersion(scheme, SchemeGroupVersion) - return nil -} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go deleted file mode 100644 index 41b7e3e90..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/types.go +++ /dev/null @@ -1,394 +0,0 @@ -/* -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 v1alpha1 - -import ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// NodeFeatureList contains a list of NodeFeature objects. -// +kubebuilder:object:root=true -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type NodeFeatureList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - - // List of NodeFeatures. - Items []NodeFeature `json:"items"` -} - -// NodeFeature resource holds the features discovered for one node in the -// cluster. -// +kubebuilder:object:root=true -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type NodeFeature struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Specification of the NodeFeature, containing features discovered for a node. - Spec NodeFeatureSpec `json:"spec"` -} - -// NodeFeatureSpec describes a NodeFeature object. -type NodeFeatureSpec struct { - // Features is the full "raw" features data that has been discovered. - // +optional - Features Features `json:"features"` - // Labels is the set of node labels that are requested to be created. - // +optional - Labels map[string]string `json:"labels"` -} - -// Features is the collection of all discovered features. -type Features struct { - // Flags contains all the flag-type features of the node. - // +optional - Flags map[string]FlagFeatureSet `json:"flags"` - // Attributes contains all the attribute-type features of the node. - // +optional - Attributes map[string]AttributeFeatureSet `json:"attributes"` - // Instances contains all the instance-type features of the node. - // +optional - Instances map[string]InstanceFeatureSet `json:"instances"` -} - -// FlagFeatureSet is a set of simple features only containing names without values. -type FlagFeatureSet struct { - // Individual features of the feature set. - Elements map[string]Nil `json:"elements"` -} - -// AttributeFeatureSet is a set of features having string value. -type AttributeFeatureSet struct { - // Individual features of the feature set. - Elements map[string]string `json:"elements"` -} - -// InstanceFeatureSet is a set of features each of which is an instance having multiple attributes. -type InstanceFeatureSet struct { - // Individual features of the feature set. - Elements []InstanceFeature `json:"elements"` -} - -// InstanceFeature represents one instance of a complex features, e.g. a device. -type InstanceFeature struct { - // Attributes of the instance feature. - Attributes map[string]string `json:"attributes"` -} - -// Nil is a dummy empty struct for protobuf compatibility. -// NOTE: protobuf definitions have been removed but this is kept for API compatibility. -type Nil struct{} - -// NodeFeatureRuleList contains a list of NodeFeatureRule objects. -// +kubebuilder:object:root=true -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type NodeFeatureRuleList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - - // List of NodeFeatureRules. - Items []NodeFeatureRule `json:"items"` -} - -// NodeFeatureRule resource specifies a configuration for feature-based -// customization of node objects, such as node labeling. -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster,shortName=nfr -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +genclient -// +genclient:nonNamespaced -type NodeFeatureRule struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Spec defines the rules to be evaluated. - Spec NodeFeatureRuleSpec `json:"spec"` -} - -// NodeFeatureRuleSpec describes a NodeFeatureRule. -type NodeFeatureRuleSpec struct { - // Rules is a list of node customization rules. - Rules []Rule `json:"rules"` -} - -// NodeFeatureGroup resource holds Node pools by featureGroup -// +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Namespaced,shortName=nfg -// +kubebuilder:subresource:status -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +genclient -type NodeFeatureGroup struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Spec defines the rules to be evaluated. - Spec NodeFeatureGroupSpec `json:"spec"` - - // Status of the NodeFeatureGroup after the most recent evaluation of the - // specification. - Status NodeFeatureGroupStatus `json:"status,omitempty"` -} - -// NodeFeatureGroupSpec describes a NodeFeatureGroup object. -type NodeFeatureGroupSpec struct { - // List of rules to evaluate to determine nodes that belong in this group. - Rules []GroupRule `json:"featureGroupRules"` -} - -type NodeFeatureGroupStatus struct { - // Nodes is a list of FeatureGroupNode in the cluster that match the featureGroupRules - // +optional - // +patchMergeKey=name - // +patchStrategy=merge - // +listType=map - // +listMapKey=name - Nodes []FeatureGroupNode `json:"nodes"` -} - -type FeatureGroupNode struct { - // Name of the node. - Name string `json:"name"` -} - -// NodeFeatureGroupList contains a list of NodeFeatureGroup objects. -// +kubebuilder:object:root=true -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type NodeFeatureGroupList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - - // List of NodeFeatureGroups. - Items []NodeFeatureGroup `json:"items"` -} - -// GroupRule defines a rule for nodegroup filtering. -type GroupRule struct { - // Name of the rule. - Name string `json:"name"` - - // Vars is the variables to store if the rule matches. Variables can be - // referenced from other rules enabling more complex rule hierarchies. - // +optional - Vars map[string]string `json:"vars"` - - // VarsTemplate specifies a template to expand for dynamically generating - // multiple variables. Data (after template expansion) must be keys with an - // optional value ([=]) separated by newlines. - // +optional - VarsTemplate string `json:"varsTemplate"` - - // MatchFeatures specifies a set of matcher terms all of which must match. - // +optional - MatchFeatures FeatureMatcher `json:"matchFeatures"` - - // MatchAny specifies a list of matchers one of which must match. - // +optional - MatchAny []MatchAnyElem `json:"matchAny"` -} - -// Rule defines a rule for node customization such as labeling. -type Rule struct { - // Name of the rule. - Name string `json:"name"` - - // Labels to create if the rule matches. - // +optional - Labels map[string]string `json:"labels"` - - // LabelsTemplate specifies a template to expand for dynamically generating - // multiple labels. Data (after template expansion) must be keys with an - // optional value ([=]) separated by newlines. - // +optional - LabelsTemplate string `json:"labelsTemplate"` - - // Annotations to create if the rule matches. - // +optional - Annotations map[string]string `json:"annotations"` - - // Vars is the variables to store if the rule matches. Variables do not - // directly inflict any changes in the node object. However, they can be - // referenced from other rules enabling more complex rule hierarchies, - // without exposing intermediary output values as labels. - // +optional - Vars map[string]string `json:"vars"` - - // VarsTemplate specifies a template to expand for dynamically generating - // multiple variables. Data (after template expansion) must be keys with an - // optional value ([=]) separated by newlines. - // +optional - VarsTemplate string `json:"varsTemplate"` - - // Taints to create if the rule matches. - // +optional - Taints []corev1.Taint `json:"taints,omitempty"` - - // ExtendedResources to create if the rule matches. - // +optional - ExtendedResources map[string]string `json:"extendedResources"` - - // MatchFeatures specifies a set of matcher terms all of which must match. - // +optional - MatchFeatures FeatureMatcher `json:"matchFeatures"` - - // MatchAny specifies a list of matchers one of which must match. - // +optional - MatchAny []MatchAnyElem `json:"matchAny"` -} - -// MatchAnyElem specifies one sub-matcher of MatchAny. -type MatchAnyElem struct { - // MatchFeatures specifies a set of matcher terms all of which must match. - MatchFeatures FeatureMatcher `json:"matchFeatures"` -} - -// FeatureMatcher specifies a set of feature matcher terms (i.e. per-feature -// matchers), all of which must match. -type FeatureMatcher []FeatureMatcherTerm - -// FeatureMatcherTerm defines requirements against one feature set. All -// requirements (specified as MatchExpressions) are evaluated against each -// element in the feature set. -type FeatureMatcherTerm struct { - // Feature is the name of the feature set to match against. - Feature string `json:"feature"` - // MatchExpressions is the set of per-element expressions evaluated. These - // match against the value of the specified elements. - // +optional - MatchExpressions *MatchExpressionSet `json:"matchExpressions"` - // MatchName in an expression that is matched against the name of each - // element in the feature set. - // +optional - MatchName *MatchExpression `json:"matchName"` -} - -// MatchExpressionSet contains a set of MatchExpressions, each of which is -// evaluated against a set of input values. -type MatchExpressionSet map[string]*MatchExpression - -// MatchExpression specifies an expression to evaluate against a set of input -// values. It contains an operator that is applied when matching the input and -// an array of values that the operator evaluates the input against. -type MatchExpression struct { - // Op is the operator to be applied. - Op MatchOp `json:"op"` - - // Value is the list of values that the operand evaluates the input - // against. Value should be empty if the operator is Exists, DoesNotExist, - // IsTrue or IsFalse. Value should contain exactly one element if the - // operator is Gt or Lt and exactly two elements if the operator is GtLt. - // In other cases Value should contain at least one element. - // +optional - Value MatchValue `json:"value,omitempty"` - - // Type defines the value type for specific operators. - // The currently supported type is 'version' for Gt,Ge,Lt,Le,GtLt,GeLe operators. - // +optional - Type ValueType `json:"type,omitempty"` -} - -// MatchOp is the match operator that is applied on values when evaluating a -// MatchExpression. -// +kubebuilder:validation:Enum="In";"NotIn";"InRegexp";"Exists";"DoesNotExist";"Gt";"Ge";"Lt";"Le";"GtLt";"GeLe";"IsTrue";"IsFalse" -type MatchOp string - -// MatchValue is the list of values associated with a MatchExpression. -type MatchValue []string - -// ValueType represents the type of value in the expression. -type ValueType string - -const ( - // TypeEmpty is a default value for the expression type. - TypeEmpty ValueType = "" - // TypeVersion represents a version with the following supported formats (major.minor.patch): - // %d.%d.%d (e.g., 1.2.3), - // %d.%d (e.g., 1.2), - // %d (e.g., 1) - TypeVersion ValueType = "version" -) - -const ( - // MatchAny returns always true. - MatchAny MatchOp = "" - // MatchIn returns true if any of the values stored in the expression is - // equal to the input. - MatchIn MatchOp = "In" - // MatchNotIn returns true if none of the values in the expression are - // equal to the input. - MatchNotIn MatchOp = "NotIn" - // MatchInRegexp treats values of the expression as regular expressions and - // returns true if any of them matches the input. - MatchInRegexp MatchOp = "InRegexp" - // MatchExists returns true if the input is valid. The expression must not - // have any values. - MatchExists MatchOp = "Exists" - // MatchDoesNotExist returns true if the input is not valid. The expression - // must not have any values. - MatchDoesNotExist MatchOp = "DoesNotExist" - // MatchGt returns true if the input is greater than the value of the - // expression (number of values in the expression must be exactly one). - // Both the input and value must be integer numbers, otherwise an error is - // returned. - MatchGt MatchOp = "Gt" - // MatchGe returns true if the input is greater than or equal to the value of the - // expression (number of values in the expression must be exactly one). - // Both the input and value must be integer numbers, otherwise an error is - // returned. - MatchGe MatchOp = "Ge" - // MatchLt returns true if the input is less than the value of the - // expression (number of values in the expression must be exactly one). - // Both the input and value must be integer numbers, otherwise an error is - // returned. - MatchLt MatchOp = "Lt" - // MatchLe returns true if the input is less than or equal to the value of the - // expression (number of values in the expression must be exactly one). - // Both the input and value must be integer numbers, otherwise an error is - // returned. - MatchLe MatchOp = "Le" - // MatchGtLt returns true if the input is between two values, i.e. greater - // than the first value and less than the second value of the expression - // (number of values in the expression must be exactly two). Both the input - // and values must be integer numbers, otherwise an error is returned. - MatchGtLt MatchOp = "GtLt" - // MatchGeLe returns true if the input is between two values including the boundary values, - // i.e. greater than or equal to the first value and less than or equal to the second value - // of the expression (number of values in the expression must be exactly two). Both the input - // and values must be integer numbers, otherwise an error is returned. - MatchGeLe MatchOp = "GeLe" - // MatchIsTrue returns true if the input holds the value "true". The - // expression must not have any values. - MatchIsTrue MatchOp = "IsTrue" - // MatchIsFalse returns true if the input holds the value "false". The - // expression must not have any values. - MatchIsFalse MatchOp = "IsFalse" -) - -const ( - // RuleBackrefDomain is the special feature domain for backreferencing - // output of preceding rules. - RuleBackrefDomain = "rule" - // RuleBackrefFeature is the special feature name for backreferencing - // output of preceding rules. - RuleBackrefFeature = "matched" -) - -// MatchAllNames is a special key in MatchExpressionSet to use field names -// (keys from the input) instead of values when matching. -const MatchAllNames = "*" diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go deleted file mode 100644 index 49c34a426..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/utils.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2024 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 v1alpha1 - -import ( - "fmt" -) - -// String represents the match expression as a string type. -func (m MatchExpression) String() string { - if len(m.Value) < 1 { - return fmt.Sprintf("{op: %q}", m.Op) - } - return fmt.Sprintf("{op: %q, value: %q}", m.Op, m.Value) -} diff --git a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 75d71cbdc..000000000 --- a/vendor/sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,718 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 2025 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. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AttributeFeatureSet) DeepCopyInto(out *AttributeFeatureSet) { - *out = *in - if in.Elements != nil { - in, out := &in.Elements, &out.Elements - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttributeFeatureSet. -func (in *AttributeFeatureSet) DeepCopy() *AttributeFeatureSet { - if in == nil { - return nil - } - out := new(AttributeFeatureSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FeatureGroupNode) DeepCopyInto(out *FeatureGroupNode) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureGroupNode. -func (in *FeatureGroupNode) DeepCopy() *FeatureGroupNode { - if in == nil { - return nil - } - out := new(FeatureGroupNode) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in FeatureMatcher) DeepCopyInto(out *FeatureMatcher) { - { - in := &in - *out = make(FeatureMatcher, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcher. -func (in FeatureMatcher) DeepCopy() FeatureMatcher { - if in == nil { - return nil - } - out := new(FeatureMatcher) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FeatureMatcherTerm) DeepCopyInto(out *FeatureMatcherTerm) { - *out = *in - if in.MatchExpressions != nil { - in, out := &in.MatchExpressions, &out.MatchExpressions - *out = new(MatchExpressionSet) - if **in != nil { - in, out := *in, *out - *out = make(map[string]*MatchExpression, len(*in)) - for key, val := range *in { - var outVal *MatchExpression - if val == nil { - (*out)[key] = nil - } else { - in, out := &val, &outVal - *out = new(MatchExpression) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } - } - if in.MatchName != nil { - in, out := &in.MatchName, &out.MatchName - *out = new(MatchExpression) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcherTerm. -func (in *FeatureMatcherTerm) DeepCopy() *FeatureMatcherTerm { - if in == nil { - return nil - } - out := new(FeatureMatcherTerm) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Features) DeepCopyInto(out *Features) { - *out = *in - if in.Flags != nil { - in, out := &in.Flags, &out.Flags - *out = make(map[string]FlagFeatureSet, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(map[string]AttributeFeatureSet, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Instances != nil { - in, out := &in.Instances, &out.Instances - *out = make(map[string]InstanceFeatureSet, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features. -func (in *Features) DeepCopy() *Features { - if in == nil { - return nil - } - out := new(Features) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FlagFeatureSet) DeepCopyInto(out *FlagFeatureSet) { - *out = *in - if in.Elements != nil { - in, out := &in.Elements, &out.Elements - *out = make(map[string]Nil, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagFeatureSet. -func (in *FlagFeatureSet) DeepCopy() *FlagFeatureSet { - if in == nil { - return nil - } - out := new(FlagFeatureSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GroupRule) DeepCopyInto(out *GroupRule) { - *out = *in - if in.Vars != nil { - in, out := &in.Vars, &out.Vars - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.MatchFeatures != nil { - in, out := &in.MatchFeatures, &out.MatchFeatures - *out = make(FeatureMatcher, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.MatchAny != nil { - in, out := &in.MatchAny, &out.MatchAny - *out = make([]MatchAnyElem, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupRule. -func (in *GroupRule) DeepCopy() *GroupRule { - if in == nil { - return nil - } - out := new(GroupRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InstanceFeature) DeepCopyInto(out *InstanceFeature) { - *out = *in - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeature. -func (in *InstanceFeature) DeepCopy() *InstanceFeature { - if in == nil { - return nil - } - out := new(InstanceFeature) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InstanceFeatureSet) DeepCopyInto(out *InstanceFeatureSet) { - *out = *in - if in.Elements != nil { - in, out := &in.Elements, &out.Elements - *out = make([]InstanceFeature, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeatureSet. -func (in *InstanceFeatureSet) DeepCopy() *InstanceFeatureSet { - if in == nil { - return nil - } - out := new(InstanceFeatureSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MatchAnyElem) DeepCopyInto(out *MatchAnyElem) { - *out = *in - if in.MatchFeatures != nil { - in, out := &in.MatchFeatures, &out.MatchFeatures - *out = make(FeatureMatcher, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchAnyElem. -func (in *MatchAnyElem) DeepCopy() *MatchAnyElem { - if in == nil { - return nil - } - out := new(MatchAnyElem) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MatchExpression) DeepCopyInto(out *MatchExpression) { - *out = *in - if in.Value != nil { - in, out := &in.Value, &out.Value - *out = make(MatchValue, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpression. -func (in *MatchExpression) DeepCopy() *MatchExpression { - if in == nil { - return nil - } - out := new(MatchExpression) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in MatchExpressionSet) DeepCopyInto(out *MatchExpressionSet) { - { - in := &in - *out = make(MatchExpressionSet, len(*in)) - for key, val := range *in { - var outVal *MatchExpression - if val == nil { - (*out)[key] = nil - } else { - in, out := &val, &outVal - *out = new(MatchExpression) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchExpressionSet. -func (in MatchExpressionSet) DeepCopy() MatchExpressionSet { - if in == nil { - return nil - } - out := new(MatchExpressionSet) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in MatchValue) DeepCopyInto(out *MatchValue) { - { - in := &in - *out = make(MatchValue, len(*in)) - copy(*out, *in) - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchValue. -func (in MatchValue) DeepCopy() MatchValue { - if in == nil { - return nil - } - out := new(MatchValue) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Nil) DeepCopyInto(out *Nil) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nil. -func (in *Nil) DeepCopy() *Nil { - if in == nil { - return nil - } - out := new(Nil) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeature) DeepCopyInto(out *NodeFeature) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeature. -func (in *NodeFeature) DeepCopy() *NodeFeature { - if in == nil { - return nil - } - out := new(NodeFeature) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeature) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureGroup) DeepCopyInto(out *NodeFeatureGroup) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroup. -func (in *NodeFeatureGroup) DeepCopy() *NodeFeatureGroup { - if in == nil { - return nil - } - out := new(NodeFeatureGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeatureGroup) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureGroupList) DeepCopyInto(out *NodeFeatureGroupList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]NodeFeatureGroup, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupList. -func (in *NodeFeatureGroupList) DeepCopy() *NodeFeatureGroupList { - if in == nil { - return nil - } - out := new(NodeFeatureGroupList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeatureGroupList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureGroupSpec) DeepCopyInto(out *NodeFeatureGroupSpec) { - *out = *in - if in.Rules != nil { - in, out := &in.Rules, &out.Rules - *out = make([]GroupRule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupSpec. -func (in *NodeFeatureGroupSpec) DeepCopy() *NodeFeatureGroupSpec { - if in == nil { - return nil - } - out := new(NodeFeatureGroupSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureGroupStatus) DeepCopyInto(out *NodeFeatureGroupStatus) { - *out = *in - if in.Nodes != nil { - in, out := &in.Nodes, &out.Nodes - *out = make([]FeatureGroupNode, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureGroupStatus. -func (in *NodeFeatureGroupStatus) DeepCopy() *NodeFeatureGroupStatus { - if in == nil { - return nil - } - out := new(NodeFeatureGroupStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureList) DeepCopyInto(out *NodeFeatureList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]NodeFeature, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureList. -func (in *NodeFeatureList) DeepCopy() *NodeFeatureList { - if in == nil { - return nil - } - out := new(NodeFeatureList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeatureList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureRule) DeepCopyInto(out *NodeFeatureRule) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRule. -func (in *NodeFeatureRule) DeepCopy() *NodeFeatureRule { - if in == nil { - return nil - } - out := new(NodeFeatureRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeatureRule) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureRuleList) DeepCopyInto(out *NodeFeatureRuleList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]NodeFeatureRule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleList. -func (in *NodeFeatureRuleList) DeepCopy() *NodeFeatureRuleList { - if in == nil { - return nil - } - out := new(NodeFeatureRuleList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeFeatureRuleList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureRuleSpec) DeepCopyInto(out *NodeFeatureRuleSpec) { - *out = *in - if in.Rules != nil { - in, out := &in.Rules, &out.Rules - *out = make([]Rule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureRuleSpec. -func (in *NodeFeatureRuleSpec) DeepCopy() *NodeFeatureRuleSpec { - if in == nil { - return nil - } - out := new(NodeFeatureRuleSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeFeatureSpec) DeepCopyInto(out *NodeFeatureSpec) { - *out = *in - in.Features.DeepCopyInto(&out.Features) - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeFeatureSpec. -func (in *NodeFeatureSpec) DeepCopy() *NodeFeatureSpec { - if in == nil { - return nil - } - out := new(NodeFeatureSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Rule) DeepCopyInto(out *Rule) { - *out = *in - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Vars != nil { - in, out := &in.Vars, &out.Vars - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Taints != nil { - in, out := &in.Taints, &out.Taints - *out = make([]v1.Taint, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.ExtendedResources != nil { - in, out := &in.ExtendedResources, &out.ExtendedResources - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.MatchFeatures != nil { - in, out := &in.MatchFeatures, &out.MatchFeatures - *out = make(FeatureMatcher, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.MatchAny != nil { - in, out := &in.MatchAny, &out.MatchAny - *out = make([]MatchAnyElem, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. -func (in *Rule) DeepCopy() *Rule { - if in == nil { - return nil - } - out := new(Rule) - in.DeepCopyInto(out) - return out -} From 7953cb4675053ddac114cd1c39cf823499ffbd3a Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Fri, 3 Apr 2026 10:47:00 +0200 Subject: [PATCH 3/5] fix: add DetectionSource field to HardwareInfo Aligns the struct with the KeyGPUDetectionSource measurement key so implementations don't need to pass detection source out-of-band. Addresses reviewer feedback: important finding. Signed-off-by: Carlos Eduardo Arango Gutierrez --- pkg/collector/gpu/hardware.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/collector/gpu/hardware.go b/pkg/collector/gpu/hardware.go index 3a79ab89c..18988e020 100644 --- a/pkg/collector/gpu/hardware.go +++ b/pkg/collector/gpu/hardware.go @@ -36,4 +36,8 @@ type HardwareInfo struct { // DriverLoaded is true if the nvidia kernel module is currently loaded. DriverLoaded bool + + // DetectionSource identifies which detection method produced this result + // (e.g., "nfd", "sysfs"). + DetectionSource string } From 59a4309bcf413901018117e6d482bd4a20a20f06 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Fri, 3 Apr 2026 10:58:21 +0200 Subject: [PATCH 4/5] fix: add error-path test case and nil guard for HardwareDetector Adds 'detection failure' test case exercising wantErr=true with nil info. Adds early return after error check to prevent nil-pointer dereference. Adds DetectionSource field assertions to existing test cases. Addresses reviewer feedback: important finding. Signed-off-by: Carlos Eduardo Arango Gutierrez --- pkg/collector/gpu/hardware_test.go | 33 ++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/pkg/collector/gpu/hardware_test.go b/pkg/collector/gpu/hardware_test.go index f5948383e..94dcec7de 100644 --- a/pkg/collector/gpu/hardware_test.go +++ b/pkg/collector/gpu/hardware_test.go @@ -17,6 +17,8 @@ package gpu import ( "context" "testing" + + "github.com/NVIDIA/aicr/pkg/errors" ) // mockHardwareDetector is a test double for the HardwareDetector interface. @@ -36,33 +38,46 @@ func TestHardwareDetectorInterface(t *testing.T) { wantPresent bool wantCount int wantDriver bool + wantDetSrc string wantErr bool }{ { name: "GPU present with driver", detector: &mockHardwareDetector{ info: &HardwareInfo{ - GPUPresent: true, - GPUCount: 2, - DriverLoaded: true, + GPUPresent: true, + GPUCount: 2, + DriverLoaded: true, + DetectionSource: "nfd", }, }, wantPresent: true, wantCount: 2, wantDriver: true, + wantDetSrc: "nfd", }, { name: "no GPU hardware", detector: &mockHardwareDetector{ info: &HardwareInfo{ - GPUPresent: false, - GPUCount: 0, - DriverLoaded: false, + GPUPresent: false, + GPUCount: 0, + DriverLoaded: false, + DetectionSource: "nfd", }, }, wantPresent: false, wantCount: 0, wantDriver: false, + wantDetSrc: "nfd", + }, + { + name: "detection failure", + detector: &mockHardwareDetector{ + info: nil, + err: errors.New(errors.ErrCodeInternal, "sysfs not available"), + }, + wantErr: true, }, } @@ -73,6 +88,9 @@ func TestHardwareDetectorInterface(t *testing.T) { t.Errorf("Detect() error = %v, wantErr %v", err, tt.wantErr) return } + if err != nil { + return // error expected and received; skip field assertions + } if info.GPUPresent != tt.wantPresent { t.Errorf("GPUPresent = %v, want %v", info.GPUPresent, tt.wantPresent) } @@ -82,6 +100,9 @@ func TestHardwareDetectorInterface(t *testing.T) { if info.DriverLoaded != tt.wantDriver { t.Errorf("DriverLoaded = %v, want %v", info.DriverLoaded, tt.wantDriver) } + if info.DetectionSource != tt.wantDetSrc { + t.Errorf("DetectionSource = %v, want %v", info.DetectionSource, tt.wantDetSrc) + } }) } } From 7177911bdc56565ac9bec54575569920ae0af8a8 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Fri, 3 Apr 2026 11:01:40 +0200 Subject: [PATCH 5/5] fix: rename measurement keys to follow KeyGPU* convention KeyDriverLoaded -> KeyGPUDriverLoaded KeyDetectionSource -> KeyGPUDetectionSource String values unchanged. Aligns with existing KeyGPUDriver, KeyGPUModel, KeyGPUCount naming convention. Addresses reviewer feedback: minor finding. Signed-off-by: Carlos Eduardo Arango Gutierrez --- pkg/measurement/types.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/measurement/types.go b/pkg/measurement/types.go index c66a9cefa..2e1a705a6 100644 --- a/pkg/measurement/types.go +++ b/pkg/measurement/types.go @@ -33,9 +33,9 @@ const ( KeyGPUCount = "gpu-count" // GPU hardware detection keys (NFD-based, no driver required) - KeyGPUPresent = "gpu-present" - KeyDriverLoaded = "driver-loaded" - KeyDetectionSource = "detection-source" + KeyGPUPresent = "gpu-present" + KeyGPUDriverLoaded = "driver-loaded" + KeyGPUDetectionSource = "detection-source" ) // Internal measurement keys used only within this package.