mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-15 17:50:49 +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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"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"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
"sigs.k8s.io/node-feature-discovery/source"
|
||||||
|
api "sigs.k8s.io/node-feature-discovery/source/custom/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Name of this feature source
|
// Name of this feature source
|
||||||
const Name = "custom"
|
const Name = "custom"
|
||||||
|
|
||||||
type CustomRule struct {
|
// The config files use the internal API type.
|
||||||
nfdv1alpha1.Rule
|
type config []api.Rule
|
||||||
}
|
|
||||||
|
|
||||||
type config []CustomRule
|
|
||||||
|
|
||||||
// newDefaultConfig returns a new config with pre-populated defaults
|
// newDefaultConfig returns a new config with pre-populated defaults
|
||||||
func newDefaultConfig() *config {
|
func newDefaultConfig() *config {
|
||||||
|
@ -43,11 +42,17 @@ func newDefaultConfig() *config {
|
||||||
// customSource implements the LabelSource and ConfigurableSource interfaces.
|
// customSource implements the LabelSource and ConfigurableSource interfaces.
|
||||||
type customSource struct {
|
type customSource struct {
|
||||||
config *config
|
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
|
// Singleton source instance
|
||||||
var (
|
var (
|
||||||
src = customSource{config: newDefaultConfig()}
|
src = customSource{
|
||||||
|
config: &config{},
|
||||||
|
rules: []nfdv1alpha1.Rule{},
|
||||||
|
}
|
||||||
_ source.LabelSource = &src
|
_ source.LabelSource = &src
|
||||||
_ source.ConfigurableSource = &src
|
_ source.ConfigurableSource = &src
|
||||||
)
|
)
|
||||||
|
@ -65,6 +70,8 @@ func (s *customSource) GetConfig() source.Config { return s.config }
|
||||||
func (s *customSource) SetConfig(conf source.Config) {
|
func (s *customSource) SetConfig(conf source.Config) {
|
||||||
switch v := conf.(type) {
|
switch v := conf.(type) {
|
||||||
case *config:
|
case *config:
|
||||||
|
r := []api.Rule(*v)
|
||||||
|
s.rules = convertInternalRulesToNfdApi(&r)
|
||||||
s.config = v
|
s.config = v
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("invalid config type: %T", conf))
|
panic(fmt.Sprintf("invalid config type: %T", conf))
|
||||||
|
@ -80,8 +87,8 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
features := source.GetAllFeatures()
|
features := source.GetAllFeatures()
|
||||||
|
|
||||||
labels := source.FeatureLabels{}
|
labels := source.FeatureLabels{}
|
||||||
allFeatureConfig := append(getStaticFeatureConfig(), *s.config...)
|
allFeatureConfig := append(getStaticRules(), s.rules...)
|
||||||
allFeatureConfig = append(allFeatureConfig, getDirectoryFeatureConfig()...)
|
allFeatureConfig = append(allFeatureConfig, getDropinDirRules()...)
|
||||||
klog.V(2).InfoS("resolving custom features", "configuration", utils.DelayedDumper(allFeatureConfig))
|
klog.V(2).InfoS("resolving custom features", "configuration", utils.DelayedDumper(allFeatureConfig))
|
||||||
// Iterate over features
|
// Iterate over features
|
||||||
for _, rule := range allFeatureConfig {
|
for _, rule := range allFeatureConfig {
|
||||||
|
@ -102,6 +109,17 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
return labels, nil
|
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() {
|
func init() {
|
||||||
source.Register(&src)
|
source.Register(&src)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,22 +22,24 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"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"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Directory stores the full path for the custom sources folder
|
// Directory stores the full path for the custom sources folder
|
||||||
const Directory = "/etc/kubernetes/node-feature-discovery/custom.d"
|
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
|
// 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)
|
features := readDir(Directory, true)
|
||||||
klog.V(3).InfoS("all custom feature specs from config dir", "featureSpecs", features)
|
klog.V(3).InfoS("all custom feature specs from config dir", "featureSpecs", features)
|
||||||
return features
|
return features
|
||||||
}
|
}
|
||||||
|
|
||||||
func readDir(dirName string, recursive bool) []CustomRule {
|
func readDir(dirName string, recursive bool) []nfdv1alpha1.Rule {
|
||||||
features := make([]CustomRule, 0)
|
features := make([]nfdv1alpha1.Rule, 0)
|
||||||
|
|
||||||
klog.V(4).InfoS("reading directory", "path", dirName)
|
klog.V(4).InfoS("reading directory", "path", dirName)
|
||||||
files, err := os.ReadDir(dirName)
|
files, err := os.ReadDir(dirName)
|
||||||
|
@ -74,14 +76,14 @@ func readDir(dirName string, recursive bool) []CustomRule {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &[]CustomRule{}
|
config := &[]api.Rule{}
|
||||||
err = yaml.UnmarshalStrict(bytes, config)
|
err = yaml.UnmarshalStrict(bytes, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "could not parse file", "path", fileName)
|
klog.ErrorS(err, "could not parse file", "path", fileName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
features = append(features, *config...)
|
features = append(features, convertInternalRulesToNfdApi(config)...)
|
||||||
}
|
}
|
||||||
return features
|
return features
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,10 @@ import (
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
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.
|
// e.g RMDA related features. NFD configuration file may extend these custom features by adding rules.
|
||||||
func getStaticFeatureConfig() []CustomRule {
|
func getStaticRules() []nfdv1alpha1.Rule {
|
||||||
return []CustomRule{
|
return []nfdv1alpha1.Rule{
|
||||||
{
|
|
||||||
nfdv1alpha1.Rule{
|
nfdv1alpha1.Rule{
|
||||||
Name: "RDMA capable static rule",
|
Name: "RDMA capable static rule",
|
||||||
Labels: map[string]string{"rdma.capable": "true"},
|
Labels: map[string]string{"rdma.capable": "true"},
|
||||||
|
@ -39,8 +38,6 @@ func getStaticFeatureConfig() []CustomRule {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
|
||||||
nfdv1alpha1.Rule{
|
nfdv1alpha1.Rule{
|
||||||
Name: "RDMA available static rule",
|
Name: "RDMA available static rule",
|
||||||
Labels: map[string]string{"rdma.available": "true"},
|
Labels: map[string]string{"rdma.available": "true"},
|
||||||
|
@ -58,7 +55,6 @@ func getStaticFeatureConfig() []CustomRule {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue