mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
Use generics for maps and slices
This commit is contained in:
parent
6ef153e4c3
commit
cb0a46ec0e
10 changed files with 42 additions and 79 deletions
2
go.mod
2
go.mod
|
@ -20,6 +20,7 @@ require (
|
||||||
github.com/smartystreets/goconvey v1.6.4
|
github.com/smartystreets/goconvey v1.6.4
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
|
github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
|
||||||
|
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb
|
||||||
golang.org/x/net v0.19.0
|
golang.org/x/net v0.19.0
|
||||||
golang.org/x/time v0.5.0
|
golang.org/x/time v0.5.0
|
||||||
google.golang.org/grpc v1.59.0
|
google.golang.org/grpc v1.59.0
|
||||||
|
@ -163,7 +164,6 @@ require (
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.16.0 // indirect
|
golang.org/x/crypto v0.16.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect
|
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.14.0 // indirect
|
||||||
golang.org/x/oauth2 v0.14.0 // indirect
|
golang.org/x/oauth2 v0.14.0 // indirect
|
||||||
golang.org/x/sync v0.5.0 // indirect
|
golang.org/x/sync v0.5.0 // indirect
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -259,10 +260,7 @@ func (m *MatchExpression) MatchKeys(name string, keys map[string]Nil) (bool, err
|
||||||
if klogV := klog.V(3); klogV.Enabled() {
|
if klogV := klog.V(3); klogV.Enabled() {
|
||||||
klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op)
|
klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op)
|
||||||
} else if klogV := klog.V(4); klogV.Enabled() {
|
} else if klogV := klog.V(4); klogV.Enabled() {
|
||||||
k := make([]string, 0, len(keys))
|
k := maps.Keys(keys)
|
||||||
for n := range keys {
|
|
||||||
k = append(k, n)
|
|
||||||
}
|
|
||||||
sort.Strings(k)
|
sort.Strings(k)
|
||||||
klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op, "inputKeys", k)
|
klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op, "inputKeys", k)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
|
import "maps"
|
||||||
|
|
||||||
// NewNodeFeatureSpec creates a new emprty instance of NodeFeatureSpec type,
|
// NewNodeFeatureSpec creates a new emprty instance of NodeFeatureSpec type,
|
||||||
// initializing all fields to proper empty values.
|
// initializing all fields to proper empty values.
|
||||||
func NewNodeFeatureSpec() *NodeFeatureSpec {
|
func NewNodeFeatureSpec() *NodeFeatureSpec {
|
||||||
|
@ -75,9 +77,7 @@ func (f *Features) InsertAttributeFeatures(domain, feature string, values map[st
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range values {
|
maps.Copy(f.Attributes[key].Elements, values)
|
||||||
f.Attributes[key].Elements[k] = v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists returns a non-empty string if a feature exists. The return value is
|
// Exists returns a non-empty string if a feature exists. The return value is
|
||||||
|
@ -103,9 +103,7 @@ func (in *NodeFeatureSpec) MergeInto(out *NodeFeatureSpec) {
|
||||||
if out.Labels == nil {
|
if out.Labels == nil {
|
||||||
out.Labels = make(map[string]string, len(in.Labels))
|
out.Labels = make(map[string]string, len(in.Labels))
|
||||||
}
|
}
|
||||||
for key, val := range in.Labels {
|
maps.Copy(out.Labels, in.Labels)
|
||||||
out.Labels[key] = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +149,7 @@ func (in *FlagFeatureSet) MergeInto(out *FlagFeatureSet) {
|
||||||
if out.Elements == nil {
|
if out.Elements == nil {
|
||||||
out.Elements = make(map[string]Nil, len(in.Elements))
|
out.Elements = make(map[string]Nil, len(in.Elements))
|
||||||
}
|
}
|
||||||
for key, val := range in.Elements {
|
maps.Copy(out.Elements, in.Elements)
|
||||||
out.Elements[key] = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,9 +159,7 @@ func (in *AttributeFeatureSet) MergeInto(out *AttributeFeatureSet) {
|
||||||
if out.Elements == nil {
|
if out.Elements == nil {
|
||||||
out.Elements = make(map[string]string, len(in.Elements))
|
out.Elements = make(map[string]string, len(in.Elements))
|
||||||
}
|
}
|
||||||
for key, val := range in.Elements {
|
maps.Copy(out.Elements, in.Elements)
|
||||||
out.Elements[key] = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ package v1alpha1
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
@ -40,7 +42,6 @@ type RuleOutput struct {
|
||||||
|
|
||||||
// Execute the rule against a set of input features.
|
// Execute the rule against a set of input features.
|
||||||
func (r *Rule) Execute(features *Features) (RuleOutput, error) {
|
func (r *Rule) Execute(features *Features) (RuleOutput, error) {
|
||||||
extendedResources := make(map[string]string)
|
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
vars := make(map[string]string)
|
vars := make(map[string]string)
|
||||||
|
|
||||||
|
@ -92,18 +93,16 @@ func (r *Rule) Execute(features *Features) (RuleOutput, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range r.ExtendedResources {
|
maps.Copy(labels, r.Labels)
|
||||||
extendedResources[k] = v
|
maps.Copy(vars, r.Vars)
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range r.Labels {
|
ret := RuleOutput{
|
||||||
labels[k] = v
|
Labels: labels,
|
||||||
|
Vars: vars,
|
||||||
|
Annotations: maps.Clone(r.Annotations),
|
||||||
|
ExtendedResources: maps.Clone(r.ExtendedResources),
|
||||||
|
Taints: slices.Clone(r.Taints),
|
||||||
}
|
}
|
||||||
for k, v := range r.Vars {
|
|
||||||
vars[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := RuleOutput{ExtendedResources: extendedResources, Labels: labels, Vars: vars, Taints: r.Taints, Annotations: r.Annotations}
|
|
||||||
klog.V(2).InfoS("rule matched", "ruleName", r.Name, "ruleOutput", utils.DelayedDumper(ret))
|
klog.V(2).InfoS("rule matched", "ruleName", r.Name, "ruleOutput", utils.DelayedDumper(ret))
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -477,11 +478,9 @@ func (m *nfdMaster) prune() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for a := range node.Annotations {
|
maps.DeleteFunc(node.Annotations, func(k, v string) bool {
|
||||||
if strings.HasPrefix(a, m.instanceAnnotation(nfdv1alpha1.AnnotationNs)) {
|
return strings.HasPrefix(k, m.instanceAnnotation(nfdv1alpha1.AnnotationNs))
|
||||||
delete(node.Annotations, a)
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
err = m.apihelper.UpdateNode(cli, node)
|
err = m.apihelper.UpdateNode(cli, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to prune annotations from node %q: %v", node.Name, err)
|
return fmt.Errorf("failed to prune annotations from node %q: %v", node.Name, err)
|
||||||
|
@ -812,18 +811,14 @@ func (m *nfdMaster) refreshNodeFeatures(cli *kubernetes.Clientset, nodeName stri
|
||||||
crLabels, crAnnotations, crExtendedResources, crTaints := m.processNodeFeatureRule(nodeName, features)
|
crLabels, crAnnotations, crExtendedResources, crTaints := m.processNodeFeatureRule(nodeName, features)
|
||||||
|
|
||||||
// Mix in CR-originated labels
|
// Mix in CR-originated labels
|
||||||
for k, v := range crLabels {
|
maps.Copy(labels, crLabels)
|
||||||
labels[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove labels which are intended to be extended resources via
|
// Remove labels which are intended to be extended resources via
|
||||||
// -resource-labels or their NS is not whitelisted
|
// -resource-labels or their NS is not whitelisted
|
||||||
labels, extendedResources := m.filterFeatureLabels(labels, features)
|
labels, extendedResources := m.filterFeatureLabels(labels, features)
|
||||||
|
|
||||||
// Mix in CR-originated extended resources with -resource-labels
|
// Mix in CR-originated extended resources with -resource-labels
|
||||||
for k, v := range crExtendedResources {
|
maps.Copy(extendedResources, crExtendedResources)
|
||||||
extendedResources[k] = v
|
|
||||||
}
|
|
||||||
extendedResources = m.filterExtendedResources(features, extendedResources)
|
extendedResources = m.filterExtendedResources(features, extendedResources)
|
||||||
|
|
||||||
// Annotations
|
// Annotations
|
||||||
|
@ -991,15 +986,9 @@ func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha
|
||||||
e = addNsToMapKeys(ruleOut.ExtendedResources, nfdv1alpha1.ExtendedResourceNs)
|
e = addNsToMapKeys(ruleOut.ExtendedResources, nfdv1alpha1.ExtendedResourceNs)
|
||||||
a = addNsToMapKeys(ruleOut.Annotations, nfdv1alpha1.FeatureAnnotationNs)
|
a = addNsToMapKeys(ruleOut.Annotations, nfdv1alpha1.FeatureAnnotationNs)
|
||||||
}
|
}
|
||||||
for k, v := range l {
|
maps.Copy(labels, l)
|
||||||
labels[k] = v
|
maps.Copy(extendedResources, e)
|
||||||
}
|
maps.Copy(annotations, a)
|
||||||
for k, v := range e {
|
|
||||||
extendedResources[k] = v
|
|
||||||
}
|
|
||||||
for k, v := range a {
|
|
||||||
annotations[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Feed back rule output to features map for subsequent rules to match
|
// Feed back rule output to features map for subsequent rules to match
|
||||||
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
||||||
|
@ -1061,9 +1050,7 @@ func (m *nfdMaster) updateNodeObject(cli *kubernetes.Clientset, nodeName string,
|
||||||
}
|
}
|
||||||
sort.Strings(annotationKeys)
|
sort.Strings(annotationKeys)
|
||||||
annotations[m.instanceAnnotation(nfdv1alpha1.FeatureAnnotationsTrackingAnnotation)] = strings.Join(annotationKeys, ",")
|
annotations[m.instanceAnnotation(nfdv1alpha1.FeatureAnnotationsTrackingAnnotation)] = strings.Join(annotationKeys, ",")
|
||||||
for k, v := range featureAnnotations {
|
maps.Copy(annotations, featureAnnotations)
|
||||||
annotations[k] = v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create JSON patches for changes in labels and annotations
|
// Create JSON patches for changes in labels and annotations
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
@ -415,10 +416,7 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.featureSources = make([]source.FeatureSource, 0, len(featureSources))
|
w.featureSources = maps.Values(featureSources)
|
||||||
for _, s := range featureSources {
|
|
||||||
w.featureSources = append(w.featureSources, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(w.featureSources, func(i, j int) bool { return w.featureSources[i].Name() < w.featureSources[j].Name() })
|
sort.Slice(w.featureSources, func(i, j int) bool { return w.featureSources[i].Name() < w.featureSources[j].Name() })
|
||||||
|
|
||||||
|
@ -450,10 +448,7 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.labelSources = make([]source.LabelSource, 0, len(labelSources))
|
w.labelSources = maps.Values(labelSources)
|
||||||
for _, s := range labelSources {
|
|
||||||
w.labelSources = append(w.labelSources, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(w.labelSources, func(i, j int) bool {
|
sort.Slice(w.labelSources, func(i, j int) bool {
|
||||||
iP, jP := w.labelSources[i].Priority(), w.labelSources[j].Priority()
|
iP, jP := w.labelSources[i].Priority(), w.labelSources[j].Priority()
|
||||||
|
@ -560,9 +555,7 @@ func createFeatureLabels(sources []source.LabelSource, labelWhiteList regexp.Reg
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, value := range labelsFromSource {
|
maps.Copy(labels, labelsFromSource)
|
||||||
labels[name] = value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if klogV := klog.V(1); klogV.Enabled() {
|
if klogV := klog.V(1); klogV.Enabled() {
|
||||||
klogV.InfoS("feature discovery completed", "labels", utils.DelayedDumper(labels))
|
klogV.InfoS("feature discovery completed", "labels", utils.DelayedDumper(labels))
|
||||||
|
|
|
@ -24,6 +24,8 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegexpVal is a wrapper for regexp command line flags
|
// RegexpVal is a wrapper for regexp command line flags
|
||||||
|
@ -77,10 +79,7 @@ func (a *StringSetVal) String() string {
|
||||||
if *a == nil {
|
if *a == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
vals := make([]string, 0, len(*a))
|
vals := maps.Keys(*a)
|
||||||
for val := range *a {
|
|
||||||
vals = append(vals, val)
|
|
||||||
}
|
|
||||||
sort.Strings(vals)
|
sort.Strings(vals)
|
||||||
return strings.Join(vals, ",")
|
return strings.Join(vals, ",")
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -75,9 +76,7 @@ func GetNumaMemoryResources() (NumaMemoryResources, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for n, s := range hugepageBytes {
|
maps.Copy(info, hugepageBytes)
|
||||||
info[n] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
memoryResources[nodeID] = info
|
memoryResources[nodeID] = info
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||||
|
@ -102,11 +103,7 @@ func (s *pciSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(configLabelFields) > 0 {
|
if len(configLabelFields) > 0 {
|
||||||
keys := []string{}
|
klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", maps.Keys(configLabelFields))
|
||||||
for key := range configLabelFields {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", keys)
|
|
||||||
}
|
}
|
||||||
if len(deviceLabelFields) == 0 {
|
if len(deviceLabelFields) == 0 {
|
||||||
deviceLabelFields = []string{"class", "vendor"}
|
deviceLabelFields = []string{"class", "vendor"}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||||
|
@ -105,11 +106,7 @@ func (s *usbSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(configLabelFields) > 0 {
|
if len(configLabelFields) > 0 {
|
||||||
keys := []string{}
|
klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", maps.Keys(configLabelFields))
|
||||||
for key := range configLabelFields {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", keys)
|
|
||||||
}
|
}
|
||||||
if len(deviceLabelFields) == 0 {
|
if len(deviceLabelFields) == 0 {
|
||||||
deviceLabelFields = defaultDeviceLabelFields()
|
deviceLabelFields = defaultDeviceLabelFields()
|
||||||
|
|
Loading…
Reference in a new issue