mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-31 04:04:51 +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:
parent
2c3a4d1588
commit
df6909ed5e
5 changed files with 95 additions and 10 deletions
|
@ -2,6 +2,7 @@
|
||||||
# labelWhiteList:
|
# labelWhiteList:
|
||||||
# noPublish: false
|
# noPublish: false
|
||||||
# sleepInterval: 60s
|
# sleepInterval: 60s
|
||||||
|
# featureSources: [all]
|
||||||
# labelSources: [all]
|
# labelSources: [all]
|
||||||
# klog:
|
# klog:
|
||||||
# addDirHeader: false
|
# addDirHeader: false
|
||||||
|
|
|
@ -91,6 +91,7 @@ worker:
|
||||||
# labelWhiteList:
|
# labelWhiteList:
|
||||||
# noPublish: false
|
# noPublish: false
|
||||||
# sleepInterval: 60s
|
# sleepInterval: 60s
|
||||||
|
# featureSources: [all]
|
||||||
# labelSources: [all]
|
# labelSources: [all]
|
||||||
# klog:
|
# klog:
|
||||||
# addDirHeader: false
|
# addDirHeader: false
|
||||||
|
|
|
@ -43,12 +43,44 @@ core:
|
||||||
sleepInterval: 60s
|
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
|
||||||
|
|
||||||
`core.labelSources` specifies the list of enabled label sources. A special
|
`core.labelSources` specifies the list of enabled label sources. A special
|
||||||
value `all` enables all sources. Prefixing a source name with `-` indicates
|
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
|
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
|
Note: Overridden by the `-label-sources` and `-sources` command line flags and
|
||||||
the `core.sources` configurations option (if any of them is specified).
|
the `core.sources` configurations option (if any of them is specified).
|
||||||
|
|
|
@ -308,6 +308,7 @@ func TestNewNfdWorker(t *testing.T) {
|
||||||
worker := w.(*nfdWorker)
|
worker := w.(*nfdWorker)
|
||||||
So(worker.configure("", ""), ShouldBeNil)
|
So(worker.configure("", ""), ShouldBeNil)
|
||||||
Convey("all sources should be enabled and the whitelist regexp should be empty", func() {
|
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(len(worker.labelSources), ShouldEqual, len(source.GetAllLabelSources())-1)
|
||||||
So(worker.config.Core.LabelWhiteList, ShouldResemble, emptyRegexp)
|
So(worker.config.Core.LabelWhiteList, ShouldResemble, emptyRegexp)
|
||||||
})
|
})
|
||||||
|
@ -376,12 +377,18 @@ func TestCreateFeatureLabels(t *testing.T) {
|
||||||
|
|
||||||
func TestAdvertiseFeatureLabels(t *testing.T) {
|
func TestAdvertiseFeatureLabels(t *testing.T) {
|
||||||
Convey("When advertising labels", t, func() {
|
Convey("When advertising labels", t, func() {
|
||||||
|
w, err := NewNfdWorker(&Args{})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
worker := w.(*nfdWorker)
|
||||||
|
|
||||||
mockClient := &labeler.MockLabelerClient{}
|
mockClient := &labeler.MockLabelerClient{}
|
||||||
|
worker.client = mockClient
|
||||||
|
|
||||||
labels := map[string]string{"feature-1": "value-1"}
|
labels := map[string]string{"feature-1": "value-1"}
|
||||||
|
|
||||||
Convey("Correct labeling request is sent", func() {
|
Convey("Correct labeling request is sent", func() {
|
||||||
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, nil)
|
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() {
|
Convey("There should be no error", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
})
|
})
|
||||||
|
@ -389,7 +396,7 @@ func TestAdvertiseFeatureLabels(t *testing.T) {
|
||||||
Convey("Labeling request fails", func() {
|
Convey("Labeling request fails", func() {
|
||||||
mockErr := errors.New("mock-error")
|
mockErr := errors.New("mock-error")
|
||||||
mockClient.On("SetLabels", mock.AnythingOfType("*context.timerCtx"), mock.AnythingOfType("*labeler.SetLabelsRequest")).Return(&labeler.SetLabelsReply{}, mockErr)
|
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() {
|
Convey("An error should be returned", func() {
|
||||||
So(err, ShouldEqual, mockErr)
|
So(err, ShouldEqual, mockErr)
|
||||||
})
|
})
|
||||||
|
|
|
@ -64,6 +64,7 @@ type coreConfig struct {
|
||||||
Klog map[string]string
|
Klog map[string]string
|
||||||
LabelWhiteList utils.RegexpVal
|
LabelWhiteList utils.RegexpVal
|
||||||
NoPublish bool
|
NoPublish bool
|
||||||
|
FeatureSources []string
|
||||||
Sources *[]string
|
Sources *[]string
|
||||||
LabelSources []string
|
LabelSources []string
|
||||||
SleepInterval duration
|
SleepInterval duration
|
||||||
|
@ -105,6 +106,7 @@ type nfdWorker struct {
|
||||||
configFilePath string
|
configFilePath string
|
||||||
config *NFDConfig
|
config *NFDConfig
|
||||||
stop chan struct{} // channel for signaling stop
|
stop chan struct{} // channel for signaling stop
|
||||||
|
featureSources []source.FeatureSource
|
||||||
labelSources []source.LabelSource
|
labelSources []source.LabelSource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +141,7 @@ func newDefaultConfig() *NFDConfig {
|
||||||
Core: coreConfig{
|
Core: coreConfig{
|
||||||
LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
|
LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
|
||||||
SleepInterval: duration{60 * time.Second},
|
SleepInterval: duration{60 * time.Second},
|
||||||
|
FeatureSources: []string{"all"},
|
||||||
LabelSources: []string{"all"},
|
LabelSources: []string{"all"},
|
||||||
Klog: make(map[string]string),
|
Klog: make(map[string]string),
|
||||||
},
|
},
|
||||||
|
@ -178,10 +181,10 @@ func (w *nfdWorker) Run() error {
|
||||||
select {
|
select {
|
||||||
case <-labelTrigger:
|
case <-labelTrigger:
|
||||||
// Run feature discovery
|
// Run feature discovery
|
||||||
for n, s := range source.GetAllFeatureSources() {
|
for _, s := range w.featureSources {
|
||||||
klog.V(2).Infof("running discovery for %q source", n)
|
klog.V(2).Infof("running discovery for %q source", s.Name())
|
||||||
if err := s.Discover(); err != nil {
|
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.
|
// Update the node with the feature labels.
|
||||||
if w.client != nil {
|
if w.client != nil {
|
||||||
err := advertiseFeatureLabels(w.client, labels)
|
err := w.advertiseFeatureLabels(labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to advertise labels: %s", err.Error())
|
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
|
// Determine enabled label sources
|
||||||
labelSources := make(map[string]source.LabelSource)
|
labelSources := make(map[string]source.LabelSource)
|
||||||
for _, name := range c.LabelSources {
|
for _, name := range c.LabelSources {
|
||||||
|
@ -335,7 +373,13 @@ func (w *nfdWorker) configureCore(c coreConfig) error {
|
||||||
})
|
})
|
||||||
|
|
||||||
if klog.V(1).Enabled() {
|
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 {
|
for i, s := range w.labelSources {
|
||||||
n[i] = s.Name()
|
n[i] = s.Name()
|
||||||
}
|
}
|
||||||
|
@ -510,7 +554,7 @@ func getFeatures() map[string]*feature.DomainFeatures {
|
||||||
|
|
||||||
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
||||||
// via the NFD server.
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
@ -520,7 +564,7 @@ func advertiseFeatureLabels(client pb.LabelerClient, labels Labels) error {
|
||||||
Features: getFeatures(),
|
Features: getFeatures(),
|
||||||
NfdVersion: version.Get(),
|
NfdVersion: version.Get(),
|
||||||
NodeName: nfdclient.NodeName()}
|
NodeName: nfdclient.NodeName()}
|
||||||
_, err := client.SetLabels(ctx, &labelReq)
|
_, err := w.client.SetLabels(ctx, &labelReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("failed to set node labels: %v", err)
|
klog.Errorf("failed to set node labels: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Add table
Reference in a new issue