mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-17 05:48:21 +00:00
Make the kernel feature source configurable
Adding two config options: - kernel config file to read - kconfig options that are detected
This commit is contained in:
parent
ce129aef88
commit
4053010dd9
5 changed files with 57 additions and 25 deletions
23
README.md
23
README.md
|
@ -172,16 +172,17 @@ such as restricting discovered features with the --label-whitelist option._
|
||||||
|
|
||||||
### Kernel Features
|
### Kernel Features
|
||||||
|
|
||||||
| Feature | Attribute | Description |
|
| Feature | Attribute | Description |
|
||||||
| ------- | ----------- | ---------------------------------------------------- |
|
| ------- | ------------------- | -------------------------------------------- |
|
||||||
| config | NO_HZ | Kernel config option is enabled
|
| config | <option name> | Kernel config option is enabled (set 'y' or 'm').<br> Default options are `NO_HZ`, `NO_HZ_IDLE`, `NO_HZ_FULL` and `PREEMPT`
|
||||||
| <br> | NO_HZ_FULL |
|
| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde')
|
||||||
| <br> | NO_HZ_IDLE |
|
| <br> | major | First component of the kernel version (e.g. '4')
|
||||||
| <br> | PREEMPT |
|
| <br> | minor | Second component of the kernel version (e.g. '5')
|
||||||
| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde')
|
| <br> | revision | Third component of the kernel version (e.g. '6')
|
||||||
| <br> | major | First component of the kernel version (e.g. '4')
|
|
||||||
| <br> | minor | Second component of the kernel version (e.g. '5')
|
Kernel config file to use, and, the set of config options to be detected are
|
||||||
| <br> | revision | Third component of the kernel version (e.g. '6')
|
configurable.
|
||||||
|
See [configuration options](#configuration-options) for more information.
|
||||||
|
|
||||||
### Local (User-specific Features)
|
### Local (User-specific Features)
|
||||||
|
|
||||||
|
@ -381,7 +382,7 @@ Configuration options specified from the command line will override those read
|
||||||
from the config file.
|
from the config file.
|
||||||
|
|
||||||
Currently, the only available configuration options are related to the
|
Currently, the only available configuration options are related to the
|
||||||
[PCI feature source](#pci-features).
|
[PCI](#pci-features) and [Kernel](#kernel-features) feature sources.
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
|
|
4
main.go
4
main.go
|
@ -60,7 +60,8 @@ var (
|
||||||
// Global config
|
// Global config
|
||||||
type NFDConfig struct {
|
type NFDConfig struct {
|
||||||
Sources struct {
|
Sources struct {
|
||||||
Pci *pci.NFDConfig `json:"pci,omitempty"`
|
Kernel *kernel.NFDConfig `json:"kernel,omitempty"`
|
||||||
|
Pci *pci.NFDConfig `json:"pci,omitempty"`
|
||||||
} `json:"sources,omitempty"`
|
} `json:"sources,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +224,7 @@ func argsParse(argv []string) (args Args) {
|
||||||
|
|
||||||
// Parse configuration options
|
// Parse configuration options
|
||||||
func configParse(filepath string, overrides string) error {
|
func configParse(filepath string, overrides string) error {
|
||||||
|
config.Sources.Kernel = &kernel.Config
|
||||||
config.Sources.Pci = &pci.Config
|
config.Sources.Pci = &pci.Config
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(filepath)
|
data, err := ioutil.ReadFile(filepath)
|
||||||
|
|
|
@ -205,6 +205,9 @@ func TestConfigParse(t *testing.T) {
|
||||||
defer os.Remove(f.Name())
|
defer os.Remove(f.Name())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
f.WriteString(`sources:
|
f.WriteString(`sources:
|
||||||
|
kernel:
|
||||||
|
configOpts:
|
||||||
|
- "DMI"
|
||||||
pci:
|
pci:
|
||||||
deviceClassWhitelist:
|
deviceClassWhitelist:
|
||||||
- "ff"`)
|
- "ff"`)
|
||||||
|
@ -215,6 +218,7 @@ func TestConfigParse(t *testing.T) {
|
||||||
|
|
||||||
Convey("Should return error", func() {
|
Convey("Should return error", func() {
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
So(config.Sources.Kernel.ConfigOpts, ShouldResemble, []string{"DMI"})
|
||||||
So(config.Sources.Pci.DeviceClassWhitelist, ShouldResemble, []string{"ff"})
|
So(config.Sources.Pci.DeviceClassWhitelist, ShouldResemble, []string{"ff"})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
#sources:
|
#sources:
|
||||||
|
# kernel:
|
||||||
|
# kconfigFile: "/path/to/kconfig"
|
||||||
|
# configOpts:
|
||||||
|
# - "NO_HZ"
|
||||||
|
# - "X86"
|
||||||
|
# - "DMI"
|
||||||
# pci:
|
# pci:
|
||||||
# deviceClassWhitelist:
|
# deviceClassWhitelist:
|
||||||
# - "0200"
|
# - "0200"
|
||||||
|
|
|
@ -28,16 +28,24 @@ import (
|
||||||
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default kconfig flags
|
// Configuration file options
|
||||||
var defaultKconfigFlags = [...]string{
|
type NFDConfig struct {
|
||||||
"NO_HZ",
|
KconfigFile string
|
||||||
"NO_HZ_IDLE",
|
ConfigOpts []string `json:"configOpts,omitempty"`
|
||||||
"NO_HZ_FULL",
|
|
||||||
"PREEMPT",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var logger = log.New(os.Stderr, "", log.LstdFlags)
|
var logger = log.New(os.Stderr, "", log.LstdFlags)
|
||||||
|
|
||||||
|
var Config = NFDConfig{
|
||||||
|
KconfigFile: "",
|
||||||
|
ConfigOpts: []string{
|
||||||
|
"NO_HZ",
|
||||||
|
"NO_HZ_IDLE",
|
||||||
|
"NO_HZ_FULL",
|
||||||
|
"PREEMPT",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// Implement FeatureSource interface
|
// Implement FeatureSource interface
|
||||||
type Source struct{}
|
type Source struct{}
|
||||||
|
|
||||||
|
@ -63,9 +71,9 @@ func (s Source) Discover() (source.Features, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check flags
|
// Check flags
|
||||||
for _, flag := range defaultKconfigFlags {
|
for _, opt := range Config.ConfigOpts {
|
||||||
if _, ok := kconfig[flag]; ok {
|
if _, ok := kconfig[opt]; ok {
|
||||||
features["config."+flag] = true
|
features["config."+opt] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,11 +129,22 @@ func readKconfigGzip(filename string) ([]byte, error) {
|
||||||
func parseKconfig() (map[string]bool, error) {
|
func parseKconfig() (map[string]bool, error) {
|
||||||
kconfig := map[string]bool{}
|
kconfig := map[string]bool{}
|
||||||
raw := []byte(nil)
|
raw := []byte(nil)
|
||||||
|
err := error(nil)
|
||||||
|
|
||||||
// First, try to read from /proc as this is the most reliable source
|
// First, try kconfig specified in the config file
|
||||||
raw, err := readKconfigGzip("/proc/config.gz")
|
if len(Config.KconfigFile) > 0 {
|
||||||
if err != nil {
|
raw, err = ioutil.ReadFile(Config.KconfigFile)
|
||||||
logger.Printf("ERROR: Failed to read /proc/config.gz: %s", err)
|
if err != nil {
|
||||||
|
logger.Printf("ERROR: Failed to read kernel config from %s: %s", Config.KconfigFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, try to read from /proc
|
||||||
|
if raw == nil {
|
||||||
|
raw, err = readKconfigGzip("/proc/config.gz")
|
||||||
|
if err != nil {
|
||||||
|
logger.Printf("Failed to read /proc/config.gz: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last, try to read from /boot/
|
// Last, try to read from /boot/
|
||||||
|
|
Loading…
Add table
Reference in a new issue