mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2024-12-14 11:57:51 +00:00
Add Match Rules package to be used in Custom Source
- Add a Rule interface to help describe the contract between a match rule and the Custom source that uses it. - Add PciIdRule - a rule that matches on the PCI attributes: class, vendor, device. Each is provided as a list of elements(strings). Match operation: OR will be performed per element and AND will be performed per attribute. An empty attribute will not be included in the matching process. Example: { "class": ["0200"] "vendor": ["15b3"] "device": ["1014", "1016"] } - Add LoadedKmodRule - a rule that matches a list of kernel modules with the kernel modules currently loaded in the node. Example: { ["rdma_cm", "ib_core"] }
This commit is contained in:
parent
0cfe03012b
commit
b9ab93559b
4 changed files with 170 additions and 2 deletions
|
@ -17,11 +17,10 @@ limitations under the License.
|
|||
package custom
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"sigs.k8s.io/node-feature-discovery/source"
|
||||
)
|
||||
|
||||
// Custom Features Configurations
|
||||
type MatchRule struct {
|
||||
}
|
||||
|
||||
|
|
60
source/custom/rules/loaded_kmod_rule.go
Normal file
60
source/custom/rules/loaded_kmod_rule.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
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"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Rule that matches on loaded kernel modules in the system
|
||||
type LoadedKModRule []string
|
||||
|
||||
const kmodProcfsPath = "/proc/modules"
|
||||
|
||||
func (kmods *LoadedKModRule) Match() (bool, error) {
|
||||
loadedModules, err := kmods.getLoadedModules()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to get loaded kernel modules. %s", err.Error())
|
||||
}
|
||||
for _, kmod := range *kmods {
|
||||
if _, ok := loadedModules[kmod]; !ok {
|
||||
// kernel module not loaded
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (kmods *LoadedKModRule) getLoadedModules() (map[string]struct{}, error) {
|
||||
out, err := ioutil.ReadFile(kmodProcfsPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read file %s: %s", kmodProcfsPath, err.Error())
|
||||
}
|
||||
|
||||
loadedMods := make(map[string]struct{})
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
// skip empty lines
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
// append loaded module
|
||||
loadedMods[strings.Fields(line)[0]] = struct{}{}
|
||||
}
|
||||
return loadedMods, nil
|
||||
}
|
87
source/custom/rules/pci_id_rule.go
Normal file
87
source/custom/rules/pci_id_rule.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
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"
|
||||
pciutils "sigs.k8s.io/node-feature-discovery/source/internal"
|
||||
)
|
||||
|
||||
// Rule that matches on the following PCI device attributes: <class, vendor, device>
|
||||
// each device attribute will be a list elements(strings).
|
||||
// Match operation: OR will be performed per element and AND will be performed per attribute.
|
||||
// An empty attribute will not be included in the matching process.
|
||||
type PciIdRuleInput struct {
|
||||
Class []string `json:"class,omitempty"`
|
||||
Vendor []string `json:"vendor,omitempty"`
|
||||
Device []string `json:"device,omitempty"`
|
||||
}
|
||||
|
||||
type PciIdRule struct {
|
||||
PciIdRuleInput
|
||||
}
|
||||
|
||||
// Match PCI devices on the provided list of PCI regular expressions
|
||||
func (r *PciIdRule) Match() (bool, error) {
|
||||
devAttr := map[string]bool{}
|
||||
for _, attr := range []string{"class", "vendor", "device"} {
|
||||
devAttr[attr] = true
|
||||
}
|
||||
allDevs, err := pciutils.DetectPci(devAttr)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to detect PCI devices: %s", err.Error())
|
||||
}
|
||||
|
||||
for _, classDevs := range allDevs {
|
||||
for _, dev := range classDevs {
|
||||
// match rule on a single device
|
||||
if r.matchDevOnRule(dev) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (r *PciIdRule) matchDevOnRule(dev pciutils.PciDeviceInfo) bool {
|
||||
if len(r.Class) == 0 && len(r.Vendor) == 0 && len(r.Device) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(r.Class) > 0 && !in(dev["class"], r.Class) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(r.Vendor) > 0 && !in(dev["vendor"], r.Vendor) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(r.Device) > 0 && !in(dev["device"], r.Device) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func in(item string, arr []string) bool {
|
||||
for _, val := range arr {
|
||||
if val == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
22
source/custom/rules/rule.go
Normal file
22
source/custom/rules/rule.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
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
|
||||
|
||||
type Rule interface {
|
||||
// Match on rule
|
||||
Match() (bool, error)
|
||||
}
|
Loading…
Reference in a new issue