mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-15 21:08:23 +00:00
Support for non-binary labels
Make it possible to advertise also other than simple 'true' values for feature labels.
This commit is contained in:
parent
b0fedab786
commit
56c2ab3d58
16 changed files with 99 additions and 54 deletions
|
@ -96,6 +96,7 @@ The published node labels encode a few pieces of information:
|
||||||
- The source for each label (e.g. `cpuid`).
|
- The source for each label (e.g. `cpuid`).
|
||||||
- The name of the discovered feature as it appears in the underlying
|
- The name of the discovered feature as it appears in the underlying
|
||||||
source, (e.g. `AESNI` from cpuid).
|
source, (e.g. `AESNI` from cpuid).
|
||||||
|
- The value of the discovered feature.
|
||||||
|
|
||||||
Feature label names adhere to the following pattern:
|
Feature label names adhere to the following pattern:
|
||||||
```
|
```
|
||||||
|
|
4
main.go
4
main.go
|
@ -332,8 +332,8 @@ func getFeatureLabels(source source.FeatureSource) (labels Labels, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, f := range features {
|
for k := range features {
|
||||||
labels[fmt.Sprintf("%s-%s-%s", prefix, source.Name(), f)] = "true"
|
labels[fmt.Sprintf("%s-%s-%s", prefix, source.Name(), k)] = fmt.Sprintf("%v", features[k])
|
||||||
}
|
}
|
||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,11 @@ func TestDiscoveryWithMockSources(t *testing.T) {
|
||||||
Convey("When I discover features from fake source and update the node using fake client", t, func() {
|
Convey("When I discover features from fake source and update the node using fake client", t, func() {
|
||||||
mockFeatureSource := new(MockFeatureSource)
|
mockFeatureSource := new(MockFeatureSource)
|
||||||
fakeFeatureSourceName := string("testSource")
|
fakeFeatureSourceName := string("testSource")
|
||||||
fakeFeatures := []string{"testfeature1", "testfeature2", "testfeature3"}
|
fakeFeatureNames := []string{"testfeature1", "testfeature2", "testfeature3"}
|
||||||
|
fakeFeatures := source.Features{}
|
||||||
fakeFeatureLabels := Labels{}
|
fakeFeatureLabels := Labels{}
|
||||||
for _, f := range fakeFeatures {
|
for _, f := range fakeFeatureNames {
|
||||||
|
fakeFeatures[f] = true
|
||||||
fakeFeatureLabels[fmt.Sprintf("%s-testSource-%s", prefix, f)] = "true"
|
fakeFeatureLabels[fmt.Sprintf("%s-testSource-%s", prefix, f)] = "true"
|
||||||
}
|
}
|
||||||
fakeFeatureSource := source.FeatureSource(mockFeatureSource)
|
fakeFeatureSource := source.FeatureSource(mockFeatureSource)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/stretchr/testify/mock"
|
import (
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
type MockFeatureSource struct {
|
type MockFeatureSource struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
|
@ -23,15 +26,15 @@ func (_m *MockFeatureSource) Name() string {
|
||||||
|
|
||||||
// Discover provides a mock function with no input arguments
|
// Discover provides a mock function with no input arguments
|
||||||
// and []string and error as the return values
|
// and []string and error as the return values
|
||||||
func (_m *MockFeatureSource) Discover() ([]string, error) {
|
func (_m *MockFeatureSource) Discover() (source.Features, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|
||||||
var r0 []string
|
var r0 source.Features
|
||||||
if rf, ok := ret.Get(0).(func() []string); ok {
|
if rf, ok := ret.Get(0).(func() source.Features); ok {
|
||||||
r0 = rf()
|
r0 = rf()
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).([]string)
|
r0 = ret.Get(0).(source.Features)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,10 @@ limitations under the License.
|
||||||
|
|
||||||
package cpuid
|
package cpuid
|
||||||
|
|
||||||
import "github.com/klauspost/cpuid"
|
import (
|
||||||
|
"github.com/klauspost/cpuid"
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
type Source struct{}
|
type Source struct{}
|
||||||
|
@ -25,7 +28,11 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "cpuid" }
|
func (s Source) Name() string { return "cpuid" }
|
||||||
|
|
||||||
// Discover returns feature names for all the supported CPU features.
|
// Discover returns feature names for all the supported CPU features.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
// Get the cpu features as strings
|
// Get the cpu features as strings
|
||||||
return cpuid.CPU.Features.Strings(), nil
|
features := source.Features{}
|
||||||
|
for _, f := range cpuid.CPU.Features.Strings() {
|
||||||
|
features[f] = true
|
||||||
|
}
|
||||||
|
return features, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
package fake
|
package fake
|
||||||
|
|
||||||
|
import "github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
type Source struct{}
|
type Source struct{}
|
||||||
|
|
||||||
|
@ -23,11 +25,13 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "fake" }
|
func (s Source) Name() string { return "fake" }
|
||||||
|
|
||||||
// Discover returns feature names for some fake features.
|
// Discover returns feature names for some fake features.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
|
||||||
|
|
||||||
// Adding three fake features.
|
// Adding three fake features.
|
||||||
features = append(features, "fakefeature1", "fakefeature2", "fakefeature3")
|
features := source.Features{
|
||||||
|
"fakefeature1": true,
|
||||||
|
"fakefeature2": true,
|
||||||
|
"fakefeature3": true,
|
||||||
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package iommu
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Implement FeatureSource interface
|
// Implement FeatureSource interface
|
||||||
|
@ -26,8 +28,8 @@ type Source struct{}
|
||||||
|
|
||||||
func (s Source) Name() string { return "iommu" }
|
func (s Source) Name() string { return "iommu" }
|
||||||
|
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
|
|
||||||
// Check if any iommu devices are available
|
// Check if any iommu devices are available
|
||||||
devices, err := ioutil.ReadDir("/sys/class/iommu/")
|
devices, err := ioutil.ReadDir("/sys/class/iommu/")
|
||||||
|
@ -36,7 +38,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(devices) > 0 {
|
if len(devices) > 0 {
|
||||||
features = append(features, "enabled")
|
features["enabled"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
|
@ -29,8 +31,8 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "memory" }
|
func (s Source) Name() string { return "memory" }
|
||||||
|
|
||||||
// Discover returns feature names for memory: numa if more than one memory node is present.
|
// Discover returns feature names for memory: numa if more than one memory node is present.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
|
|
||||||
// Find out how many nodes are online
|
// Find out how many nodes are online
|
||||||
// Multiple nodes is a sign of NUMA
|
// Multiple nodes is a sign of NUMA
|
||||||
|
@ -44,7 +46,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
// presence of newline requires TrimSpace
|
// presence of newline requires TrimSpace
|
||||||
if strings.TrimSpace(string(bytes)) != "0" {
|
if strings.TrimSpace(string(bytes)) != "0" {
|
||||||
// more than one node means NUMA
|
// more than one node means NUMA
|
||||||
features = append(features, "numa")
|
features["numa"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
|
|
|
@ -24,6 +24,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
|
@ -33,8 +35,8 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "network" }
|
func (s Source) Name() string { return "network" }
|
||||||
|
|
||||||
// Discover returns feature names sriov-configured and sriov if SR-IOV capable NICs are present and/or SR-IOV virtual functions are configured on the node
|
// Discover returns feature names sriov-configured and sriov if SR-IOV capable NICs are present and/or SR-IOV virtual functions are configured on the node
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
netInterfaces, err := net.Interfaces()
|
netInterfaces, err := net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't obtain the network interfaces details: %s", err.Error())
|
return nil, fmt.Errorf("can't obtain the network interfaces details: %s", err.Error())
|
||||||
|
@ -57,7 +59,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
if t > 0 {
|
if t > 0 {
|
||||||
glog.Infof("SR-IOV capability is detected on the network interface: %s", netInterface.Name)
|
glog.Infof("SR-IOV capability is detected on the network interface: %s", netInterface.Name)
|
||||||
glog.Infof("%d maximum supported number of virtual functions on network interface: %s", t, netInterface.Name)
|
glog.Infof("%d maximum supported number of virtual functions on network interface: %s", t, netInterface.Name)
|
||||||
features = append(features, "sriov.capable")
|
features["sriov.capable"] = true
|
||||||
numVfsPath := "/sys/class/net/" + netInterface.Name + "/device/sriov_numvfs"
|
numVfsPath := "/sys/class/net/" + netInterface.Name + "/device/sriov_numvfs"
|
||||||
numBytes, err := ioutil.ReadFile(numVfsPath)
|
numBytes, err := ioutil.ReadFile(numVfsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,7 +74,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
}
|
}
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
glog.Infof("%d virtual functions configured on network interface: %s", n, netInterface.Name)
|
glog.Infof("%d virtual functions configured on network interface: %s", n, netInterface.Name)
|
||||||
features = append(features, "sriov.configured")
|
features["sriov.configured"] = true
|
||||||
break
|
break
|
||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
glog.Errorf("SR-IOV not configured on network interface: %s", netInterface.Name)
|
glog.Errorf("SR-IOV not configured on network interface: %s", netInterface.Name)
|
||||||
|
|
|
@ -16,6 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
package panic_fake
|
package panic_fake
|
||||||
|
|
||||||
|
import "github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
type Source struct{}
|
type Source struct{}
|
||||||
|
|
||||||
|
@ -23,6 +25,6 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "panic_fake" }
|
func (s Source) Name() string { return "panic_fake" }
|
||||||
|
|
||||||
// Discover calls panic().
|
// Discover calls panic().
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
panic("fake panic error")
|
panic("fake panic error")
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pciDeviceInfo map[string]string
|
type pciDeviceInfo map[string]string
|
||||||
|
@ -48,8 +50,8 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "pci" }
|
func (s Source) Name() string { return "pci" }
|
||||||
|
|
||||||
// Discover features
|
// Discover features
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := map[string]bool{}
|
features := source.Features{}
|
||||||
|
|
||||||
devs, err := detectPci()
|
devs, err := detectPci()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,12 +102,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
feature_list := []string{}
|
return features, nil
|
||||||
for feature := range features {
|
|
||||||
feature_list = append(feature_list, feature)
|
|
||||||
}
|
|
||||||
|
|
||||||
return feature_list, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read information of one PCI device
|
// Read information of one PCI device
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
|
@ -29,8 +31,8 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "pstate" }
|
func (s Source) Name() string { return "pstate" }
|
||||||
|
|
||||||
// Discover returns feature names for p-state related features such as turbo boost.
|
// Discover returns feature names for p-state related features such as turbo boost.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
|
|
||||||
// On Arm platform, the frequency boost mechanism is software-based.
|
// On Arm platform, the frequency boost mechanism is software-based.
|
||||||
// So skip pstate detection on Arm.
|
// So skip pstate detection on Arm.
|
||||||
|
@ -46,7 +48,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
}
|
}
|
||||||
if bytes[0] == byte('0') {
|
if bytes[0] == byte('0') {
|
||||||
// Turbo boost is enabled.
|
// Turbo boost is enabled.
|
||||||
features = append(features, "turbo")
|
features["turbo"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
|
@ -29,15 +30,15 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "rdt" }
|
func (s Source) Name() string { return "rdt" }
|
||||||
|
|
||||||
// Discover returns feature names for CMT and CAT if supported.
|
// Discover returns feature names for CMT and CAT if supported.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
|
|
||||||
cmd := exec.Command("bash", "-c", "mon-discovery")
|
cmd := exec.Command("bash", "-c", "mon-discovery")
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
glog.Errorf("support for RDT monitoring was not detected: %v", err)
|
glog.Errorf("support for RDT monitoring was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT monitoring detected.
|
// RDT monitoring detected.
|
||||||
features = append(features, "RDTMON")
|
features["RDTMON"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("bash", "-c", "mon-cmt-discovery")
|
cmd = exec.Command("bash", "-c", "mon-cmt-discovery")
|
||||||
|
@ -45,7 +46,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
glog.Errorf("support for RDT CMT monitoring was not detected: %v", err)
|
glog.Errorf("support for RDT CMT monitoring was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT CMT monitoring detected.
|
// RDT CMT monitoring detected.
|
||||||
features = append(features, "RDTCMT")
|
features["RDTCMT"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("bash", "-c", "mon-mbm-discovery")
|
cmd = exec.Command("bash", "-c", "mon-mbm-discovery")
|
||||||
|
@ -53,7 +54,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
glog.Errorf("support for RDT MBM monitoring was not detected: %v", err)
|
glog.Errorf("support for RDT MBM monitoring was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT MBM monitoring detected.
|
// RDT MBM monitoring detected.
|
||||||
features = append(features, "RDTMBM")
|
features["RDTMBM"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("bash", "-c", "l3-alloc-discovery")
|
cmd = exec.Command("bash", "-c", "l3-alloc-discovery")
|
||||||
|
@ -61,7 +62,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
glog.Errorf("support for RDT L3 allocation was not detected: %v", err)
|
glog.Errorf("support for RDT L3 allocation was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT L3 cache allocation detected.
|
// RDT L3 cache allocation detected.
|
||||||
features = append(features, "RDTL3CA")
|
features["RDTL3CA"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("bash", "-c", "l2-alloc-discovery")
|
cmd = exec.Command("bash", "-c", "l2-alloc-discovery")
|
||||||
|
@ -69,7 +70,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
glog.Errorf("support for RDT L2 allocation was not detected: %v", err)
|
glog.Errorf("support for RDT L2 allocation was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT L2 cache allocation detected.
|
// RDT L2 cache allocation detected.
|
||||||
features = append(features, "RDTL2CA")
|
features["RDTL2CA"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command("bash", "-c", "mem-bandwidth-alloc-discovery")
|
cmd = exec.Command("bash", "-c", "mem-bandwidth-alloc-discovery")
|
||||||
|
@ -77,7 +78,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
glog.Errorf("support for RDT Memory bandwidth allocation was not detected: %v", err)
|
glog.Errorf("support for RDT Memory bandwidth allocation was not detected: %v", err)
|
||||||
} else {
|
} else {
|
||||||
// RDT Memory bandwidth allocation detected.
|
// RDT Memory bandwidth allocation detected.
|
||||||
features = append(features, "RDTMBA")
|
features["RDTMBA"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return features, nil
|
return features, nil
|
||||||
|
|
|
@ -17,23 +17,25 @@ limitations under the License.
|
||||||
package selinux
|
package selinux
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Source struct{}
|
type Source struct{}
|
||||||
|
|
||||||
func (s Source) Name() string { return "selinux" }
|
func (s Source) Name() string { return "selinux" }
|
||||||
|
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
status, err := ioutil.ReadFile("/host-sys/fs/selinux/enforce")
|
status, err := ioutil.ReadFile("/host-sys/fs/selinux/enforce")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to detect the status of selinux, please check if the system supports selinux and make sure /sys on the host is mounted into the container: %s", err.Error())
|
return nil, fmt.Errorf("Failed to detect the status of selinux, please check if the system supports selinux and make sure /sys on the host is mounted into the container: %s", err.Error())
|
||||||
}
|
}
|
||||||
if status[0] == byte('1') {
|
if status[0] == byte('1') {
|
||||||
// selinux is enabled.
|
// selinux is enabled.
|
||||||
features = append(features, "enabled")
|
features["enabled"] = true
|
||||||
}
|
}
|
||||||
return features, nil
|
return features, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,27 @@ limitations under the License.
|
||||||
|
|
||||||
package source
|
package source
|
||||||
|
|
||||||
|
// Value of a feature
|
||||||
|
type FeatureValue interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boolean feature value
|
||||||
|
type BoolFeatureValue bool
|
||||||
|
|
||||||
|
func (b BoolFeatureValue) String() string {
|
||||||
|
if b == true {
|
||||||
|
return "true"
|
||||||
|
}
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
type Features map[string]FeatureValue
|
||||||
|
|
||||||
// FeatureSource represents a source of a discovered node feature.
|
// FeatureSource represents a source of a discovered node feature.
|
||||||
type FeatureSource interface {
|
type FeatureSource interface {
|
||||||
// Name returns a friendly name for this source of node feature.
|
// Name returns a friendly name for this source of node feature.
|
||||||
Name() string
|
Name() string
|
||||||
|
|
||||||
// Discover returns discovered features for this node.
|
// Discover returns discovered features for this node.
|
||||||
Discover() ([]string, error)
|
Discover() (Features, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package storage
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/kubernetes-incubator/node-feature-discovery/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source implements FeatureSource.
|
// Source implements FeatureSource.
|
||||||
|
@ -28,8 +30,8 @@ type Source struct{}
|
||||||
func (s Source) Name() string { return "storage" }
|
func (s Source) Name() string { return "storage" }
|
||||||
|
|
||||||
// Discover returns feature names for storage: nonrotationaldisk if any SSD drive present.
|
// Discover returns feature names for storage: nonrotationaldisk if any SSD drive present.
|
||||||
func (s Source) Discover() ([]string, error) {
|
func (s Source) Discover() (source.Features, error) {
|
||||||
features := []string{}
|
features := source.Features{}
|
||||||
|
|
||||||
// Check if there is any non-rotational block devices attached to the node
|
// Check if there is any non-rotational block devices attached to the node
|
||||||
blockdevices, err := ioutil.ReadDir("/sys/block/")
|
blockdevices, err := ioutil.ReadDir("/sys/block/")
|
||||||
|
@ -42,7 +44,7 @@ func (s Source) Discover() ([]string, error) {
|
||||||
}
|
}
|
||||||
if bytes[0] == byte('0') {
|
if bytes[0] == byte('0') {
|
||||||
// Non-rotational storage is present, add label.
|
// Non-rotational storage is present, add label.
|
||||||
features = append(features, "nonrotationaldisk")
|
features["nonrotationaldisk"] = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue