mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
source/custom: use internal api for config parsing
Change the custom feature source of nfd-worker to use the newly added internal config API for its own configuration. It now uses the internal types for json/yaml unmarshalling but converts them to external nfdv1alpha1 API to do the actual rule matching as the internal API does not duplicate that functionality.
This commit is contained in:
parent
185b406ee7
commit
a8092927fc
3 changed files with 61 additions and 45 deletions
|
@ -18,22 +18,21 @@ package custom
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||
"sigs.k8s.io/node-feature-discovery/source"
|
||||
api "sigs.k8s.io/node-feature-discovery/source/custom/api"
|
||||
)
|
||||
|
||||
// Name of this feature source
|
||||
const Name = "custom"
|
||||
|
||||
type CustomRule struct {
|
||||
nfdv1alpha1.Rule
|
||||
}
|
||||
|
||||
type config []CustomRule
|
||||
// The config files use the internal API type.
|
||||
type config []api.Rule
|
||||
|
||||
// newDefaultConfig returns a new config with pre-populated defaults
|
||||
func newDefaultConfig() *config {
|
||||
|
@ -43,13 +42,19 @@ func newDefaultConfig() *config {
|
|||
// customSource implements the LabelSource and ConfigurableSource interfaces.
|
||||
type customSource struct {
|
||||
config *config
|
||||
// The rules are stored in the NFD API format that is a superset of our
|
||||
// internal API and provides the functions for rule matching.
|
||||
rules []nfdv1alpha1.Rule
|
||||
}
|
||||
|
||||
// Singleton source instance
|
||||
var (
|
||||
src = customSource{config: newDefaultConfig()}
|
||||
_ source.LabelSource = &src
|
||||
_ source.ConfigurableSource = &src
|
||||
src = customSource{
|
||||
config: &config{},
|
||||
rules: []nfdv1alpha1.Rule{},
|
||||
}
|
||||
_ source.LabelSource = &src
|
||||
_ source.ConfigurableSource = &src
|
||||
)
|
||||
|
||||
// Name returns the name of the feature source
|
||||
|
@ -65,6 +70,8 @@ func (s *customSource) GetConfig() source.Config { return s.config }
|
|||
func (s *customSource) SetConfig(conf source.Config) {
|
||||
switch v := conf.(type) {
|
||||
case *config:
|
||||
r := []api.Rule(*v)
|
||||
s.rules = convertInternalRulesToNfdApi(&r)
|
||||
s.config = v
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid config type: %T", conf))
|
||||
|
@ -80,8 +87,8 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
|||
features := source.GetAllFeatures()
|
||||
|
||||
labels := source.FeatureLabels{}
|
||||
allFeatureConfig := append(getStaticFeatureConfig(), *s.config...)
|
||||
allFeatureConfig = append(allFeatureConfig, getDirectoryFeatureConfig()...)
|
||||
allFeatureConfig := append(getStaticRules(), s.rules...)
|
||||
allFeatureConfig = append(allFeatureConfig, getDropinDirRules()...)
|
||||
klog.V(2).InfoS("resolving custom features", "configuration", utils.DelayedDumper(allFeatureConfig))
|
||||
// Iterate over features
|
||||
for _, rule := range allFeatureConfig {
|
||||
|
@ -102,6 +109,17 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
|||
return labels, nil
|
||||
}
|
||||
|
||||
func convertInternalRulesToNfdApi(in *[]api.Rule) []nfdv1alpha1.Rule {
|
||||
out := make([]nfdv1alpha1.Rule, len(*in))
|
||||
for i := range *in {
|
||||
if err := api.ConvertRuleToV1alpha1(&(*in)[i], &out[i]); err != nil {
|
||||
klog.ErrorS(err, "FATAL: API conversion failed")
|
||||
os.Exit(255)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func init() {
|
||||
source.Register(&src)
|
||||
}
|
||||
|
|
|
@ -22,22 +22,24 @@ import (
|
|||
"strings"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||
api "sigs.k8s.io/node-feature-discovery/source/custom/api"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// Directory stores the full path for the custom sources folder
|
||||
const Directory = "/etc/kubernetes/node-feature-discovery/custom.d"
|
||||
|
||||
// getDirectoryFeatureConfig returns features configured in the "/etc/kubernetes/node-feature-discovery/custom.d"
|
||||
// getDropinDirRules returns features configured in the "/etc/kubernetes/node-feature-discovery/custom.d"
|
||||
// host directory and its 1st level subdirectories, which can be populated e.g. by ConfigMaps
|
||||
func getDirectoryFeatureConfig() []CustomRule {
|
||||
func getDropinDirRules() []nfdv1alpha1.Rule {
|
||||
features := readDir(Directory, true)
|
||||
klog.V(3).InfoS("all custom feature specs from config dir", "featureSpecs", features)
|
||||
return features
|
||||
}
|
||||
|
||||
func readDir(dirName string, recursive bool) []CustomRule {
|
||||
features := make([]CustomRule, 0)
|
||||
func readDir(dirName string, recursive bool) []nfdv1alpha1.Rule {
|
||||
features := make([]nfdv1alpha1.Rule, 0)
|
||||
|
||||
klog.V(4).InfoS("reading directory", "path", dirName)
|
||||
files, err := os.ReadDir(dirName)
|
||||
|
@ -74,14 +76,14 @@ func readDir(dirName string, recursive bool) []CustomRule {
|
|||
continue
|
||||
}
|
||||
|
||||
config := &[]CustomRule{}
|
||||
config := &[]api.Rule{}
|
||||
err = yaml.UnmarshalStrict(bytes, config)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "could not parse file", "path", fileName)
|
||||
continue
|
||||
}
|
||||
|
||||
features = append(features, *config...)
|
||||
features = append(features, convertInternalRulesToNfdApi(config)...)
|
||||
}
|
||||
return features
|
||||
}
|
||||
|
|
|
@ -20,40 +20,36 @@ import (
|
|||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||
)
|
||||
|
||||
// getStaticFeatures returns statically configured custom features to discover
|
||||
// getStaticRules returns statically configured custom features to discover
|
||||
// e.g RMDA related features. NFD configuration file may extend these custom features by adding rules.
|
||||
func getStaticFeatureConfig() []CustomRule {
|
||||
return []CustomRule{
|
||||
{
|
||||
nfdv1alpha1.Rule{
|
||||
Name: "RDMA capable static rule",
|
||||
Labels: map[string]string{"rdma.capable": "true"},
|
||||
MatchFeatures: nfdv1alpha1.FeatureMatcher{
|
||||
nfdv1alpha1.FeatureMatcherTerm{
|
||||
Feature: "pci.device",
|
||||
MatchExpressions: &nfdv1alpha1.MatchExpressionSet{
|
||||
"vendor": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchIn,
|
||||
Value: nfdv1alpha1.MatchValue{"15b3"}},
|
||||
},
|
||||
func getStaticRules() []nfdv1alpha1.Rule {
|
||||
return []nfdv1alpha1.Rule{
|
||||
nfdv1alpha1.Rule{
|
||||
Name: "RDMA capable static rule",
|
||||
Labels: map[string]string{"rdma.capable": "true"},
|
||||
MatchFeatures: nfdv1alpha1.FeatureMatcher{
|
||||
nfdv1alpha1.FeatureMatcherTerm{
|
||||
Feature: "pci.device",
|
||||
MatchExpressions: &nfdv1alpha1.MatchExpressionSet{
|
||||
"vendor": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchIn,
|
||||
Value: nfdv1alpha1.MatchValue{"15b3"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
nfdv1alpha1.Rule{
|
||||
Name: "RDMA available static rule",
|
||||
Labels: map[string]string{"rdma.available": "true"},
|
||||
MatchFeatures: nfdv1alpha1.FeatureMatcher{
|
||||
nfdv1alpha1.FeatureMatcherTerm{
|
||||
Feature: "kernel.loadedmodule",
|
||||
MatchExpressions: &nfdv1alpha1.MatchExpressionSet{
|
||||
"ib_uverbs": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchExists,
|
||||
},
|
||||
"rdma_ucm": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchExists,
|
||||
},
|
||||
nfdv1alpha1.Rule{
|
||||
Name: "RDMA available static rule",
|
||||
Labels: map[string]string{"rdma.available": "true"},
|
||||
MatchFeatures: nfdv1alpha1.FeatureMatcher{
|
||||
nfdv1alpha1.FeatureMatcherTerm{
|
||||
Feature: "kernel.loadedmodule",
|
||||
MatchExpressions: &nfdv1alpha1.MatchExpressionSet{
|
||||
"ib_uverbs": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchExists,
|
||||
},
|
||||
"rdma_ucm": &nfdv1alpha1.MatchExpression{
|
||||
Op: nfdv1alpha1.MatchExists,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue