mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-05 16:27:05 +00:00
source/custom: drop support for the legacy rule format
This commit is contained in:
parent
160c9107f5
commit
7d1df87305
9 changed files with 19 additions and 681 deletions
|
@ -1062,278 +1062,3 @@ must be present):
|
||||||
vendor: "0fff"
|
vendor: "0fff"
|
||||||
device: "abcd"
|
device: "abcd"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Legacy custom rule syntax
|
|
||||||
|
|
||||||
**DEPRECATED**: use the new rule syntax instead.
|
|
||||||
|
|
||||||
The `custom` source supports the legacy `matchOn` rule syntax for
|
|
||||||
backwards-compatibility.
|
|
||||||
|
|
||||||
To aid in making the legacy rule syntax clearer, we define a general and a per
|
|
||||||
rule nomenclature, keeping things as consistent as possible.
|
|
||||||
|
|
||||||
### General nomenclature and definitions
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Rule :Represents a matching logic that is used to match on a feature.
|
|
||||||
Rule Input :The input a Rule is provided. This determines how a Rule performs the match operation.
|
|
||||||
Matcher :A composition of Rules, each Matcher may be composed of at most one instance of each Rule.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Custom features format (using the nomenclature defined above)
|
|
||||||
|
|
||||||
Rules are specified under `sources.custom` in the nfd-worker configuration
|
|
||||||
file.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
sources:
|
|
||||||
custom:
|
|
||||||
- name: <feature name>
|
|
||||||
value: <optional feature value, defaults to "true">
|
|
||||||
matchOn:
|
|
||||||
- <Rule-1>: <Rule-1 Input>
|
|
||||||
[<Rule-2>: <Rule-2 Input>]
|
|
||||||
- <Matcher-2>
|
|
||||||
- ...
|
|
||||||
- ...
|
|
||||||
- <Matcher-N>
|
|
||||||
- <custom feature 2>
|
|
||||||
- ...
|
|
||||||
- ...
|
|
||||||
- <custom feature M>
|
|
||||||
```
|
|
||||||
|
|
||||||
The label is constructed by adding `custom-` prefix to the name field, label
|
|
||||||
value defaults to `true` if not specified in the rule spec:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
feature.node.kubernetes.io/custom-<name> = <value>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Matching process
|
|
||||||
|
|
||||||
Specifying Rules to match on a feature is done by providing a list of Matchers.
|
|
||||||
Each Matcher contains one or more Rules.
|
|
||||||
|
|
||||||
Logical _OR_ is performed between Matchers and logical _AND_ is performed
|
|
||||||
between Rules of a given Matcher.
|
|
||||||
|
|
||||||
### Rules
|
|
||||||
|
|
||||||
#### pciid rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Attribute :A PCI attribute.
|
|
||||||
Element :An identifier of the PCI attribute.
|
|
||||||
```
|
|
||||||
|
|
||||||
The PciId Rule allows matching the PCI devices in the system on the following
|
|
||||||
Attributes: `class`,`vendor` and `device`. A list of Elements is provided for
|
|
||||||
each Attribute.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
pciId :
|
|
||||||
class: [<class id>, ...]
|
|
||||||
vendor: [<vendor id>, ...]
|
|
||||||
device: [<device id>, ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing a logical _OR_ between Elements of an Attribute
|
|
||||||
and logical _AND_ between the specified Attributes for each PCI device in the
|
|
||||||
system. At least one Attribute must be specified. Missing attributes will not
|
|
||||||
partake in the matching process.
|
|
||||||
|
|
||||||
#### UsbId rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Attribute :A USB attribute.
|
|
||||||
Element :An identifier of the USB attribute.
|
|
||||||
```
|
|
||||||
|
|
||||||
The UsbId Rule allows matching the USB devices in the system on the following
|
|
||||||
Attributes: `class`,`vendor`, `device` and `serial`. A list of Elements is
|
|
||||||
provided for each Attribute.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
usbId :
|
|
||||||
class: [<class id>, ...]
|
|
||||||
vendor: [<vendor id>, ...]
|
|
||||||
device: [<device id>, ...]
|
|
||||||
serial: [<serial>, ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing a logical _OR_ between Elements of an Attribute
|
|
||||||
and logical _AND_ between the specified Attributes for each USB device in the
|
|
||||||
system. At least one Attribute must be specified. Missing attributes will not
|
|
||||||
partake in the matching process.
|
|
||||||
|
|
||||||
#### LoadedKMod rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Element :A kernel module
|
|
||||||
```
|
|
||||||
|
|
||||||
The LoadedKMod Rule allows matching the loaded kernel modules in the system
|
|
||||||
against a provided list of Elements.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
loadedKMod : [<kernel module>, ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing logical _AND_ for each provided Element, i.e
|
|
||||||
the Rule will match if all provided Elements (kernel modules) are loaded in the
|
|
||||||
system.
|
|
||||||
|
|
||||||
#### CpuId rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Element :A CPUID flag
|
|
||||||
```
|
|
||||||
|
|
||||||
The Rule allows matching the available CPUID flags in the system against a
|
|
||||||
provided list of Elements.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
cpuId : [<CPUID flag string>, ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing logical _AND_ for each provided Element, i.e the
|
|
||||||
Rule will match if all provided Elements (CPUID flag strings) are available in
|
|
||||||
the system.
|
|
||||||
|
|
||||||
#### Kconfig rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Element :A Kconfig option
|
|
||||||
```
|
|
||||||
|
|
||||||
The Rule allows matching the kconfig options in the system against a provided
|
|
||||||
list of Elements.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
kConfig: [<kernel config option ('y' or 'm') or '=<value>'>, ...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing logical _AND_ for each provided Element, i.e the
|
|
||||||
Rule will match if all provided Elements (kernel config options) are enabled
|
|
||||||
(`y` or `m`) or matching `=<value>` in the kernel.
|
|
||||||
|
|
||||||
#### Nodename rule
|
|
||||||
|
|
||||||
##### Nomenclature
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Element :A nodename regexp pattern
|
|
||||||
```
|
|
||||||
|
|
||||||
The Rule allows matching the node's name against a provided list of Elements.
|
|
||||||
|
|
||||||
##### Format
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
nodename: [ <nodename regexp pattern>, ... ]
|
|
||||||
```
|
|
||||||
|
|
||||||
Matching is done by performing logical _OR_ for each provided Element, i.e the
|
|
||||||
Rule will match if one of the provided Elements (nodename regexp pattern)
|
|
||||||
matches the node's name.
|
|
||||||
|
|
||||||
### Legacy custom rule example
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
custom:
|
|
||||||
- name: "my.kernel.feature"
|
|
||||||
matchOn:
|
|
||||||
- loadedKMod: ["kmod1", "kmod2"]
|
|
||||||
- name: "my.pci.feature"
|
|
||||||
matchOn:
|
|
||||||
- pciId:
|
|
||||||
vendor: ["15b3"]
|
|
||||||
device: ["1014", "1017"]
|
|
||||||
- name: "my.usb.feature"
|
|
||||||
matchOn:
|
|
||||||
- usbId:
|
|
||||||
vendor: ["1d6b"]
|
|
||||||
device: ["0003"]
|
|
||||||
serial: ["090129a"]
|
|
||||||
- name: "my.combined.feature"
|
|
||||||
matchOn:
|
|
||||||
- loadedKMod : ["vendor_kmod1", "vendor_kmod2"]
|
|
||||||
pciId:
|
|
||||||
vendor: ["15b3"]
|
|
||||||
device: ["1014", "1017"]
|
|
||||||
- name: "vendor.feature.node.kubernetes.io/accumulated.feature"
|
|
||||||
matchOn:
|
|
||||||
- loadedKMod : ["some_kmod1", "some_kmod2"]
|
|
||||||
- pciId:
|
|
||||||
vendor: ["15b3"]
|
|
||||||
device: ["1014", "1017"]
|
|
||||||
- name: "my.kernel.featureneedscpu"
|
|
||||||
matchOn:
|
|
||||||
- kConfig: ["KVM_INTEL"]
|
|
||||||
- cpuId: ["VMX"]
|
|
||||||
- name: "my.kernel.modulecompiler"
|
|
||||||
matchOn:
|
|
||||||
- kConfig: ["GCC_VERSION=100101"]
|
|
||||||
loadedKMod: ["kmod1"]
|
|
||||||
- name: "profile.node.kubernetes.io/my-datacenter"
|
|
||||||
value: "datacenter-1"
|
|
||||||
matchOn:
|
|
||||||
- nodename: [ "node-datacenter1-rack.*-server.*" ]
|
|
||||||
```
|
|
||||||
|
|
||||||
__In the example above:__
|
|
||||||
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.kernel.feature=true` if the node has
|
|
||||||
`kmod1` _AND_ `kmod2` kernel modules loaded.
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.pci.feature=true` if the node contains
|
|
||||||
a PCI device with a PCI vendor ID of `15b3` _AND_ PCI device ID of `1014` _OR_
|
|
||||||
`1017`.
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.usb.feature=true` if the node contains
|
|
||||||
a USB device with a USB vendor ID of `1d6b` _AND_ USB device ID of `0003`.
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.combined.feature=true` if
|
|
||||||
`vendor_kmod1` _AND_ `vendor_kmod2` kernel modules are loaded __AND__ the node
|
|
||||||
contains a PCI device
|
|
||||||
with a PCI vendor ID of `15b3` _AND_ PCI device ID of `1014` _or_ `1017`.
|
|
||||||
- A node would contain the label:
|
|
||||||
`vendor.feature.node.kubernetes.io/accumulated.feature=true` if
|
|
||||||
`some_kmod1` _AND_ `some_kmod2` kernel modules are loaded __OR__ the node
|
|
||||||
contains a PCI device
|
|
||||||
with a PCI vendor ID of `15b3` _AND_ PCI device ID of `1014` _OR_ `1017`.
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.kernel.featureneedscpu=true` if
|
|
||||||
`KVM_INTEL` kernel config is enabled __AND__ the node CPU supports `VMX`
|
|
||||||
virtual machine extensions
|
|
||||||
- A node would contain the label:
|
|
||||||
`feature.node.kubernetes.io/custom-my.kernel.modulecompiler=true` if the
|
|
||||||
in-tree `kmod1` kernel module is loaded __AND__ it's built with
|
|
||||||
`GCC_VERSION=100101`.
|
|
||||||
- A node would contain the label:
|
|
||||||
`profile.node.kubernetes.io/my-datacenter=datacenter-1` if the node's name
|
|
||||||
matches the `node-datacenter1-rack.*-server.*` pattern, e.g.
|
|
||||||
`node-datacenter1-rack2-server42`
|
|
||||||
|
|
|
@ -17,50 +17,24 @@ limitations under the License.
|
||||||
package custom
|
package custom
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"sigs.k8s.io/yaml"
|
|
||||||
|
|
||||||
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"
|
||||||
"sigs.k8s.io/node-feature-discovery/source/custom/rules"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Name of this feature source
|
// Name of this feature source
|
||||||
const Name = "custom"
|
const Name = "custom"
|
||||||
|
|
||||||
// LegacyMatcher contains the legacy custom rules.
|
type CustomRule struct {
|
||||||
type LegacyMatcher struct {
|
|
||||||
PciID *rules.PciIDRule `json:"pciId,omitempty"`
|
|
||||||
UsbID *rules.UsbIDRule `json:"usbId,omitempty"`
|
|
||||||
LoadedKMod *rules.LoadedKModRule `json:"loadedKMod,omitempty"`
|
|
||||||
CpuID *rules.CpuIDRule `json:"cpuId,omitempty"`
|
|
||||||
Kconfig *rules.KconfigRule `json:"kConfig,omitempty"`
|
|
||||||
Nodename *rules.NodenameRule `json:"nodename,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LegacyRule struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
MatchOn []LegacyMatcher `json:"matchOn"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rule struct {
|
|
||||||
nfdv1alpha1.Rule
|
nfdv1alpha1.Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
type config []CustomRule
|
type config []CustomRule
|
||||||
|
|
||||||
type CustomRule struct {
|
|
||||||
*LegacyRule
|
|
||||||
*Rule
|
|
||||||
}
|
|
||||||
|
|
||||||
// newDefaultConfig returns a new config with pre-populated defaults
|
// newDefaultConfig returns a new config with pre-populated defaults
|
||||||
func newDefaultConfig() *config {
|
func newDefaultConfig() *config {
|
||||||
return &config{}
|
return &config{}
|
||||||
|
@ -71,10 +45,6 @@ type customSource struct {
|
||||||
config *config
|
config *config
|
||||||
}
|
}
|
||||||
|
|
||||||
type legacyRule interface {
|
|
||||||
Match() (bool, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
var (
|
var (
|
||||||
src = customSource{config: newDefaultConfig()}
|
src = customSource{config: newDefaultConfig()}
|
||||||
|
@ -115,7 +85,7 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
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 {
|
||||||
ruleOut, err := rule.execute(features)
|
ruleOut, err := rule.Execute(features)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "failed to execute rule")
|
klog.ErrorS(err, "failed to execute rule")
|
||||||
continue
|
continue
|
||||||
|
@ -132,112 +102,6 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CustomRule) execute(features *nfdv1alpha1.Features) (nfdv1alpha1.RuleOutput, error) {
|
|
||||||
if r.LegacyRule != nil {
|
|
||||||
klog.InfoS("legacy 'matchOn' rule format is deprecated, please convert to the new 'matchFeatures' rule format", "ruleName", r.LegacyRule.Name)
|
|
||||||
ruleOut, err := r.LegacyRule.execute()
|
|
||||||
if err != nil {
|
|
||||||
return nfdv1alpha1.RuleOutput{}, fmt.Errorf("failed to execute legacy rule %s: %w", r.LegacyRule.Name, err)
|
|
||||||
}
|
|
||||||
return nfdv1alpha1.RuleOutput{Labels: ruleOut}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Rule != nil {
|
|
||||||
ruleOut, err := r.Rule.Execute(features)
|
|
||||||
if err != nil {
|
|
||||||
return ruleOut, fmt.Errorf("failed to execute rule %s: %w", r.Rule.Name, err)
|
|
||||||
}
|
|
||||||
return ruleOut, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nfdv1alpha1.RuleOutput{}, fmt.Errorf("BUG: an empty rule, this really should not happen")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *LegacyRule) execute() (map[string]string, error) {
|
|
||||||
if len(r.MatchOn) > 0 {
|
|
||||||
// Logical OR over the legacy rules
|
|
||||||
matched := false
|
|
||||||
for _, matcher := range r.MatchOn {
|
|
||||||
if m, err := matcher.match(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if m {
|
|
||||||
matched = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !matched {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefix non-namespaced labels with "custom-"
|
|
||||||
name := r.Name
|
|
||||||
if !strings.Contains(name, "/") {
|
|
||||||
name = "custom-" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
value := "true"
|
|
||||||
if r.Value != nil {
|
|
||||||
value = *r.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]string{name: value}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *LegacyMatcher) match() (bool, error) {
|
|
||||||
allRules := []legacyRule{
|
|
||||||
m.PciID,
|
|
||||||
m.UsbID,
|
|
||||||
m.LoadedKMod,
|
|
||||||
m.CpuID,
|
|
||||||
m.Kconfig,
|
|
||||||
m.Nodename,
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true, nil if all rules match
|
|
||||||
matchRules := func(rules []legacyRule) (bool, error) {
|
|
||||||
for _, rule := range rules {
|
|
||||||
if reflect.ValueOf(rule).IsNil() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if match, err := rule.Match(); err != nil {
|
|
||||||
return false, err
|
|
||||||
} else if !match {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchRules(allRules)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the Unmarshaler interface from "encoding/json"
|
|
||||||
func (c *CustomRule) UnmarshalJSON(data []byte) error {
|
|
||||||
// Do a raw parse to determine if this is a legacy rule
|
|
||||||
raw := map[string]json.RawMessage{}
|
|
||||||
err := yaml.Unmarshal(data, &raw)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for k := range raw {
|
|
||||||
if strings.ToLower(k) == "matchon" {
|
|
||||||
return yaml.Unmarshal(data, &c.LegacyRule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return yaml.Unmarshal(data, &c.Rule)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON implements the Marshaler interface from "encoding/json"
|
|
||||||
func (c *CustomRule) MarshalJSON() ([]byte, error) {
|
|
||||||
if c.LegacyRule != nil {
|
|
||||||
return json.Marshal(c.LegacyRule)
|
|
||||||
}
|
|
||||||
return json.Marshal(c.Rule)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
source.Register(&src)
|
source.Register(&src)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020-2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/cpu"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CpuIDRule implements Rule for the custom source
|
|
||||||
type CpuIDRule struct {
|
|
||||||
nfdv1alpha1.MatchExpressionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match checks if CpuId rule matches.
|
|
||||||
func (r *CpuIDRule) Match() (bool, error) {
|
|
||||||
flags, ok := source.GetFeatureSource("cpu").GetFeatures().Flags[cpu.CpuidFeature]
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("cpuid information not available")
|
|
||||||
}
|
|
||||||
return r.MatchKeys(flags.Elements)
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020-2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/kernel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// KconfigRule implements Rule for the custom source
|
|
||||||
type KconfigRule struct {
|
|
||||||
nfdv1alpha1.MatchExpressionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match compares the values of Kernel config provided and legacy config
|
|
||||||
func (r *KconfigRule) Match() (bool, error) {
|
|
||||||
options := kernel.GetLegacyKconfig()
|
|
||||||
if options == nil {
|
|
||||||
return false, fmt.Errorf("kernel config options not available")
|
|
||||||
}
|
|
||||||
return r.MatchValues(options)
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020-2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/kernel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LoadedKModRule matches loaded kernel modules in the system
|
|
||||||
type LoadedKModRule struct {
|
|
||||||
nfdv1alpha1.MatchExpressionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match loaded kernel modules on provided list of kernel modules
|
|
||||||
func (r *LoadedKModRule) Match() (bool, error) {
|
|
||||||
modules, ok := source.GetFeatureSource("kernel").GetFeatures().Flags[kernel.LoadedModuleFeature]
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("info about loaded modules not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.MatchKeys(modules.Elements)
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NodenameRule matches on nodenames configured in a ConfigMap
|
|
||||||
type NodenameRule struct {
|
|
||||||
nfdv1alpha1.MatchExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match checks if node name matches the rule.
|
|
||||||
func (r *NodenameRule) Match() (bool, error) {
|
|
||||||
nodeName, ok := source.GetFeatureSource("system").GetFeatures().Attributes[system.NameFeature].Elements["nodename"]
|
|
||||||
if !ok || nodeName == "" {
|
|
||||||
return false, fmt.Errorf("node name not available")
|
|
||||||
}
|
|
||||||
return r.MatchExpression.Match(true, nodeName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON unmarshals and validates the data provided
|
|
||||||
func (r *NodenameRule) UnmarshalJSON(data []byte) error {
|
|
||||||
if err := json.Unmarshal(data, &r.MatchExpression); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Force regexp matching
|
|
||||||
if r.Op == nfdv1alpha1.MatchIn {
|
|
||||||
r.Op = nfdv1alpha1.MatchInRegexp
|
|
||||||
}
|
|
||||||
// We need to run Validate() because operator forcing above
|
|
||||||
return r.Validate()
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020-2021 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/pci"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PciIDRule struct {
|
|
||||||
nfdv1alpha1.MatchExpressionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match PCI devices on provided PCI device attributes
|
|
||||||
func (r *PciIDRule) Match() (bool, error) {
|
|
||||||
devs, ok := source.GetFeatureSource("pci").GetFeatures().Instances[pci.DeviceFeature]
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("cpuid information not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.MatchInstances(devs.Elements)
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rules
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/source/usb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UsbIDRule struct {
|
|
||||||
nfdv1alpha1.MatchExpressionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match USB devices on provided USB device attributes
|
|
||||||
func (r *UsbIDRule) Match() (bool, error) {
|
|
||||||
devs, ok := source.GetFeatureSource("usb").GetFeatures().Instances[usb.DeviceFeature]
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("usb device information not available")
|
|
||||||
}
|
|
||||||
return r.MatchInstances(devs.Elements)
|
|
||||||
}
|
|
|
@ -25,7 +25,6 @@ import (
|
||||||
func getStaticFeatureConfig() []CustomRule {
|
func getStaticFeatureConfig() []CustomRule {
|
||||||
return []CustomRule{
|
return []CustomRule{
|
||||||
{
|
{
|
||||||
Rule: &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,9 +38,7 @@ func getStaticFeatureConfig() []CustomRule {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Rule: &Rule{
|
|
||||||
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"},
|
||||||
|
@ -56,7 +53,6 @@ func getStaticFeatureConfig() []CustomRule {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue