diff --git a/README.md b/README.md index 383b794bb..961381619 100644 --- a/README.md +++ b/README.md @@ -172,16 +172,17 @@ such as restricting discovered features with the --label-whitelist option._ ### Kernel Features -| Feature | Attribute | Description | -| ------- | ----------- | ---------------------------------------------------- | -| config | NO_HZ | Kernel config option is enabled -|
| NO_HZ_FULL | -|
| NO_HZ_IDLE | -|
| PREEMPT | -| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde') -|
| major | First component of the kernel version (e.g. '4') -|
| minor | Second component of the kernel version (e.g. '5') -|
| revision | Third component of the kernel version (e.g. '6') +| Feature | Attribute | Description | +| ------- | ------------------- | -------------------------------------------- | +| config | <option name> | Kernel config option is enabled (set 'y' or 'm').
Default options are `NO_HZ`, `NO_HZ_IDLE`, `NO_HZ_FULL` and `PREEMPT` +| version | full | Full kernel version as reported by `/proc/sys/kernel/osrelease` (e.g. '4.5.6-7-g123abcde') +|
| major | First component of the kernel version (e.g. '4') +|
| minor | Second component of the kernel version (e.g. '5') +|
| revision | Third component of the kernel version (e.g. '6') + +Kernel config file to use, and, the set of config options to be detected are +configurable. +See [configuration options](#configuration-options) for more information. ### Local (User-specific Features) @@ -381,7 +382,7 @@ Configuration options specified from the command line will override those read from the config file. 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 diff --git a/main.go b/main.go index a8b7792df..a088619ec 100644 --- a/main.go +++ b/main.go @@ -60,7 +60,8 @@ var ( // Global config type NFDConfig struct { Sources struct { - Pci *pci.NFDConfig `json:"pci,omitempty"` + Kernel *kernel.NFDConfig `json:"kernel,omitempty"` + Pci *pci.NFDConfig `json:"pci,omitempty"` } `json:"sources,omitempty"` } @@ -223,6 +224,7 @@ func argsParse(argv []string) (args Args) { // Parse configuration options func configParse(filepath string, overrides string) error { + config.Sources.Kernel = &kernel.Config config.Sources.Pci = &pci.Config data, err := ioutil.ReadFile(filepath) diff --git a/main_test.go b/main_test.go index 5f36cadde..212f80453 100644 --- a/main_test.go +++ b/main_test.go @@ -205,6 +205,9 @@ func TestConfigParse(t *testing.T) { defer os.Remove(f.Name()) So(err, ShouldBeNil) f.WriteString(`sources: + kernel: + configOpts: + - "DMI" pci: deviceClassWhitelist: - "ff"`) @@ -215,6 +218,7 @@ func TestConfigParse(t *testing.T) { Convey("Should return error", func() { So(err, ShouldBeNil) + So(config.Sources.Kernel.ConfigOpts, ShouldResemble, []string{"DMI"}) So(config.Sources.Pci.DeviceClassWhitelist, ShouldResemble, []string{"ff"}) }) }) diff --git a/node-feature-discovery.conf.example b/node-feature-discovery.conf.example index a7419c3fb..d510799e6 100644 --- a/node-feature-discovery.conf.example +++ b/node-feature-discovery.conf.example @@ -1,4 +1,10 @@ #sources: +# kernel: +# kconfigFile: "/path/to/kconfig" +# configOpts: +# - "NO_HZ" +# - "X86" +# - "DMI" # pci: # deviceClassWhitelist: # - "0200" diff --git a/source/kernel/kernel.go b/source/kernel/kernel.go index b308f6638..dc0812a24 100644 --- a/source/kernel/kernel.go +++ b/source/kernel/kernel.go @@ -28,16 +28,24 @@ import ( "github.com/kubernetes-incubator/node-feature-discovery/source" ) -// Default kconfig flags -var defaultKconfigFlags = [...]string{ - "NO_HZ", - "NO_HZ_IDLE", - "NO_HZ_FULL", - "PREEMPT", +// Configuration file options +type NFDConfig struct { + KconfigFile string + ConfigOpts []string `json:"configOpts,omitempty"` } 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 type Source struct{} @@ -63,9 +71,9 @@ func (s Source) Discover() (source.Features, error) { } // Check flags - for _, flag := range defaultKconfigFlags { - if _, ok := kconfig[flag]; ok { - features["config."+flag] = true + for _, opt := range Config.ConfigOpts { + if _, ok := kconfig[opt]; ok { + features["config."+opt] = true } } @@ -121,11 +129,22 @@ func readKconfigGzip(filename string) ([]byte, error) { func parseKconfig() (map[string]bool, error) { kconfig := map[string]bool{} raw := []byte(nil) + err := error(nil) - // First, try to read from /proc as this is the most reliable source - raw, err := readKconfigGzip("/proc/config.gz") - if err != nil { - logger.Printf("ERROR: Failed to read /proc/config.gz: %s", err) + // First, try kconfig specified in the config file + if len(Config.KconfigFile) > 0 { + raw, err = ioutil.ReadFile(Config.KconfigFile) + 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/