1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-28 18:57:10 +00:00

nfd-worker: add core.featureSources config option

Add a configuration option for controlling the enabled "raw" feature
sources. This is useful e.g. in testing and development, plus it also
allows fully shutting down discovery of features that are not needed in
a deployment. Supplements core.labelSources which controls the
enablement of label sources.
This commit is contained in:
Markus Lehtonen 2021-08-27 12:52:24 +03:00
parent 2c3a4d1588
commit df6909ed5e
5 changed files with 95 additions and 10 deletions
deployment
components/worker-config
helm/node-feature-discovery
docs/advanced
pkg/nfd-client/worker

View file

@ -2,6 +2,7 @@
# labelWhiteList:
# noPublish: false
# sleepInterval: 60s
# featureSources: [all]
# labelSources: [all]
# klog:
# addDirHeader: false

View file

@ -91,6 +91,7 @@ worker:
# labelWhiteList:
# noPublish: false
# sleepInterval: 60s
# featureSources: [all]
# labelSources: [all]
# klog:
# addDirHeader: false

View file

@ -43,12 +43,44 @@ core:
sleepInterval: 60s
```
### core.featureSources
`core.featureSources` specifies the list of enabled feature sources. A special
value `all` enables all sources. Prefixing a source name with `-` indicates
that the source will be disabled instead - this is only meaningful when used in
conjunction with `all`. This option allows completely disabling the feature
detection so that neither standard feature labels are generated nor the raw
feature data is available for custom rule processing.
Default: `[all]`
Example:
```yaml
core:
# Enable all but cpu and local sources
featureSources:
- "all"
- "-cpu"
- "-local"
```
```yaml
core:
# Enable only cpu and local sources
featureSources:
- "cpu"
- "local"
```
### core.labelSources
`core.labelSources` specifies the list of enabled label sources. A special
value `all` enables all sources. Prefixing a source name with `-` indicates
that the source will be disabled instead - this is only meaningful when used in
conjunction with `all`.
conjunction with `all`. This configuration option affects the generation of
node labels but not the actual discovery of the underlying feature data that is
used e.g. in custom/`NodeFeatureRule` rules.
Note: Overridden by the `-label-sources` and `-sources` command line flags and
the `core.sources` configurations option (if any of them is specified).

View file

@ -308,6 +308,7 @@ func TestNewNfdWorker(t *testing.T) {
worker := w.(*nfdWorker)
So(worker.configure("", ""), ShouldBeNil)
Convey("all sources should be enabled and the whitelist regexp should be empty", func() {
So(len(worker.featureSources), ShouldEqual, len(source.GetAllFeatureSources()))
So(len(worker.labelSources), ShouldEqual, len(source.GetAllLabelSources())-1)
So(worker.config.Core.LabelWhiteList, ShouldResemble, emptyRegexp)
})
@ -376,12 +377,18 @@ func TestCreateFeatureLabels(t *testing.T) {
func TestAdvertiseFeatureLabels(t *testing.T) {
Convey("When advertising labels", t, func() {
w, err := NewNfdWorker(&Args{})
So(err, ShouldBeNil)
worker := w.(*nfdWorker)
mockClient := &labeler.MockLabelerClient{}
worker.client = mockClient
labels := map[string]string{"feature-1": "value-1"}
Convey("Correct labeling request is sent", func() {
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, nil)
err := advertiseFeatureLabels(mockClient, labels)
err := worker.advertiseFeatureLabels(labels)
Convey("There should be no error", func() {
So(err, ShouldBeNil)
})
@ -389,7 +396,7 @@ func TestAdvertiseFeatureLabels(t *testing.T) {
Convey("Labeling request fails", func() {
mockErr := errors.New("mock-error")
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, mockErr)
err := advertiseFeatureLabels(mockClient, labels)
err := worker.advertiseFeatureLabels(labels)
Convey("An error should be returned", func() {
So(err, ShouldEqual, mockErr)
})

View file

@ -64,6 +64,7 @@ type coreConfig struct {
Klog map[string]string
LabelWhiteList utils.RegexpVal
NoPublish bool
FeatureSources []string
Sources *[]string
LabelSources []string
SleepInterval duration
@ -105,6 +106,7 @@ type nfdWorker struct {
configFilePath string
config *NFDConfig
stop chan struct{} // channel for signaling stop
featureSources []source.FeatureSource
labelSources []source.LabelSource
}
@ -139,6 +141,7 @@ func newDefaultConfig() *NFDConfig {
Core: coreConfig{
LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
SleepInterval: duration{60 * time.Second},
FeatureSources: []string{"all"},
LabelSources: []string{"all"},
Klog: make(map[string]string),
},
@ -178,10 +181,10 @@ func (w *nfdWorker) Run() error {
select {
case <-labelTrigger:
// Run feature discovery
for n, s := range source.GetAllFeatureSources() {
klog.V(2).Infof("running discovery for %q source", n)
for _, s := range w.featureSources {
klog.V(2).Infof("running discovery for %q source", s.Name())
if err := s.Discover(); err != nil {
klog.Errorf("feature discovery of %q source failed: %v", n, err)
klog.Errorf("feature discovery of %q source failed: %v", s.Name(), err)
}
}
@ -190,7 +193,7 @@ func (w *nfdWorker) Run() error {
// Update the node with the feature labels.
if w.client != nil {
err := advertiseFeatureLabels(w.client, labels)
err := w.advertiseFeatureLabels(labels)
if err != nil {
return fmt.Errorf("failed to advertise labels: %s", err.Error())
}
@ -293,6 +296,41 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
}
}
// Determine enabled feature sources
featureSources := make(map[string]source.FeatureSource)
for _, name := range c.FeatureSources {
if name == "all" {
for n, s := range source.GetAllFeatureSources() {
if ts, ok := s.(source.TestSource); !ok || !ts.IsTestSource() {
featureSources[n] = s
}
}
} else {
disable := false
strippedName := name
if strings.HasPrefix(name, "-") {
strippedName = name[1:]
disable = true
}
if s := source.GetFeatureSource(strippedName); s != nil {
if !disable {
featureSources[name] = s
} else {
delete(featureSources, strippedName)
}
} else {
klog.Warningf("skipping unknown feature source %q specified in core.featureSources", name)
}
}
}
w.featureSources = make([]source.FeatureSource, 0, len(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() })
// Determine enabled label sources
labelSources := make(map[string]source.LabelSource)
for _, name := range c.LabelSources {
@ -335,7 +373,13 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
})
if klog.V(1).Enabled() {
n := make([]string, len(w.labelSources))
n := make([]string, len(w.featureSources))
for i, s := range w.featureSources {
n[i] = s.Name()
}
klog.Infof("enabled feature sources: %s", strings.Join(n, ", "))
n = make([]string, len(w.labelSources))
for i, s := range w.labelSources {
n[i] = s.Name()
}
@ -510,7 +554,7 @@ func getFeatures() map[string]*feature.DomainFeatures {
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
// via the NFD server.
func advertiseFeatureLabels(client pb.LabelerClient, labels Labels) error {
func (w *nfdWorker) advertiseFeatureLabels(labels Labels) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
@ -520,7 +564,7 @@ func advertiseFeatureLabels(client pb.LabelerClient, labels Labels) error {
Features: getFeatures(),
NfdVersion: version.Get(),
NodeName: nfdclient.NodeName()}
_, err := client.SetLabels(ctx, &labelReq)
_, err := w.client.SetLabels(ctx, &labelReq)
if err != nil {
klog.Errorf("failed to set node labels: %v", err)
return err