1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-28 02:37:11 +00:00

Merge pull request #318 from marquiz/devel/sysfs

source: parametrise host directory paths
This commit is contained in:
Kubernetes Prow Robot 2020-05-20 13:04:20 -07:00 committed by GitHub
commit e09db73614
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 72 additions and 28 deletions

View file

@ -12,9 +12,10 @@ RUN go mod download
COPY . /go/node-feature-discovery
ARG NFD_VERSION
ARG HOSTMOUNT_PREFIX
RUN go install \
-ldflags "-s -w -X sigs.k8s.io/node-feature-discovery/pkg/version.version=$NFD_VERSION" \
-ldflags "-s -w -X sigs.k8s.io/node-feature-discovery/pkg/version.version=$NFD_VERSION -X sigs.k8s.io/node-feature-discovery/source.pathPrefix=$HOSTMOUNT_PREFIX" \
./cmd/*
RUN install -D -m644 nfd-worker.conf.example /etc/kubernetes/node-feature-discovery/nfd-worker.conf

View file

@ -16,6 +16,7 @@ IMAGE_TAG_NAME := $(VERSION)
IMAGE_REPO := $(IMAGE_REGISTRY)/$(IMAGE_NAME)
IMAGE_TAG := $(IMAGE_REPO):$(IMAGE_TAG_NAME)
K8S_NAMESPACE := kube-system
HOSTMOUNT_PREFIX := /host-
KUBECONFIG :=
E2E_TEST_CONFIG :=
@ -26,6 +27,7 @@ all: image
image: yamls
$(IMAGE_BUILD_CMD) --build-arg NFD_VERSION=$(VERSION) \
--build-arg HOSTMOUNT_PREFIX=$(HOSTMOUNT_PREFIX) \
-t $(IMAGE_TAG) \
$(IMAGE_BUILD_EXTRA_OPTS) ./
@ -38,6 +40,7 @@ yamls: $(yaml_instances)
-e s',^(\s*)name: node-feature-discovery # NFD namespace,\1name: ${K8S_NAMESPACE},' \
-e s',^(\s*)image:.+$$,\1image: ${IMAGE_TAG},' \
-e s',^(\s*)namespace:.+$$,\1namespace: ${K8S_NAMESPACE},' \
-e s',^(\s*)mountPath: "/host-,\1mountPath: "${HOSTMOUNT_PREFIX},' \
$< > $@
mock:

39
source/config.go Normal file
View file

@ -0,0 +1,39 @@
/*
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 source
import (
"path/filepath"
)
var (
pathPrefix = "/"
// BootPath is where the /boot directory of the system to be inspected is located
BootDir = HostDir(pathPrefix + "boot")
// EtcPath is where the /etc directory of the system to be inspected is located
EtcDir = HostDir(pathPrefix + "etc")
// SysfsPath is where the /sys directory of the system to be inspected is located
SysfsDir = HostDir(pathPrefix + "sys")
)
// HostDir is a helper for handling host system directories
type HostDir string
// Path returns a full path to a file under HostDir
func (d HostDir) Path(elem ...string) string {
return filepath.Join(append([]string{string(d)}, elem...)...)
}

View file

@ -19,15 +19,10 @@ package cpu
import (
"io/ioutil"
"log"
"path"
"sigs.k8s.io/node-feature-discovery/source"
)
const (
cpuDevicesBaseDir = "/sys/bus/cpu/devices"
)
// Configuration file options
type cpuidConfig struct {
AttributeBlacklist []string `json:"attributeBlacklist,omitempty"`
@ -137,14 +132,15 @@ func (s Source) Discover() (source.Features, error) {
// Check if any (online) CPUs have thread siblings
func haveThreadSiblings() (bool, error) {
files, err := ioutil.ReadDir(cpuDevicesBaseDir)
files, err := ioutil.ReadDir(source.SysfsDir.Path("bus/cpu/devices"))
if err != nil {
return false, err
}
for _, file := range files {
// Try to read siblings from topology
siblings, err := ioutil.ReadFile(path.Join(cpuDevicesBaseDir, file.Name(), "topology/thread_siblings_list"))
siblings, err := ioutil.ReadFile(source.SysfsDir.Path("bus/cpu/devices", file.Name(), "topology/thread_siblings_list"))
if err != nil {
return false, err
}

View file

@ -20,11 +20,11 @@ import (
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
"sigs.k8s.io/node-feature-discovery/pkg/cpuid"
"sigs.k8s.io/node-feature-discovery/source"
)
const (
@ -38,13 +38,14 @@ func discoverSSTBF() (bool, error) {
nominalBaseFrequency := int(freqInfo.EAX)
// Loop over all CPUs in the system
files, err := ioutil.ReadDir(cpuDevicesBaseDir)
files, err := ioutil.ReadDir(source.SysfsDir.Path("bus/cpu/devices"))
if err != nil {
return false, err
}
for _, file := range files {
// Try to read effective base frequency of each cpu in the system
filePath := path.Join(cpuDevicesBaseDir, file.Name(), "cpufreq/base_frequency")
filePath := source.SysfsDir.Path("bus/cpu/devices", file.Name(), "cpufreq/base_frequency")
data, err := ioutil.ReadFile(filePath)
if os.IsNotExist(err) {
// Ignore missing file and continue to check other CPUs

View file

@ -20,6 +20,8 @@ import (
"fmt"
"io/ioutil"
"runtime"
"sigs.k8s.io/node-feature-discovery/source"
)
// Discover p-state related features such as turbo boost.
@ -31,7 +33,7 @@ func detectPstate() (map[string]string, error) {
}
// Only looking for turbo boost for now...
bytes, err := ioutil.ReadFile("/sys/devices/system/cpu/intel_pstate/no_turbo")
bytes, err := ioutil.ReadFile(source.SysfsDir.Path("devices/system/cpu/intel_pstate/no_turbo"))
if err != nil {
return nil, fmt.Errorf("can't detect whether turbo boost is enabled: %s", err.Error())
}

View file

@ -22,6 +22,8 @@ import (
"log"
"path"
"strings"
"sigs.k8s.io/node-feature-discovery/source"
)
type PciDeviceInfo map[string]string
@ -72,10 +74,10 @@ func readPciDevInfo(devPath string, deviceAttrSpec map[string]bool) (PciDeviceIn
// "class" attribute is considered mandatory.
// DetectPci() will fail if the retrieval of a mandatory attribute fails.
func DetectPci(deviceAttrSpec map[string]bool) (map[string][]PciDeviceInfo, error) {
const basePath = "/sys/bus/pci/devices/"
sysfsBasePath := source.SysfsDir.Path("bus/pci/devices")
devInfo := make(map[string][]PciDeviceInfo)
devices, err := ioutil.ReadDir(basePath)
devices, err := ioutil.ReadDir(sysfsBasePath)
if err != nil {
return nil, err
}
@ -84,7 +86,7 @@ func DetectPci(deviceAttrSpec map[string]bool) (map[string][]PciDeviceInfo, erro
// Iterate over devices
for _, device := range devices {
info, err := readPciDevInfo(path.Join(basePath, device.Name()), deviceAttrSpec)
info, err := readPciDevInfo(path.Join(sysfsBasePath, device.Name()), deviceAttrSpec)
if err != nil {
log.Print(err)
continue

View file

@ -32,7 +32,7 @@ func (s Source) Discover() (source.Features, error) {
features := source.Features{}
// Check if any iommu devices are available
devices, err := ioutil.ReadDir("/sys/class/iommu/")
devices, err := ioutil.ReadDir(source.SysfsDir.Path("class/iommu/"))
if err != nil {
return nil, fmt.Errorf("Failed to check for IOMMU support: %v", err)
}

View file

@ -167,7 +167,7 @@ func parseKconfig() (map[string]string, error) {
return nil, err
}
// Read kconfig
raw, err = ioutil.ReadFile("/host-boot/config-" + uname)
raw, err = ioutil.ReadFile(source.BootDir.Path("config-" + uname))
if err != nil {
return nil, err
}

View file

@ -19,11 +19,13 @@ package kernel
import (
"fmt"
"io/ioutil"
"sigs.k8s.io/node-feature-discovery/source"
)
// Detect if selinux has been enabled in the kernel
func SelinuxEnabled() (bool, error) {
status, err := ioutil.ReadFile("/host-sys/fs/selinux/enforce")
status, err := ioutil.ReadFile(source.SysfsDir.Path("fs/selinux/enforce"))
if err != nil {
return false, 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())
}

View file

@ -60,7 +60,7 @@ func (s Source) Discover() (source.Features, error) {
func isNuma() (bool, error) {
// Find out how many nodes are online
// Multiple nodes is a sign of NUMA
bytes, err := ioutil.ReadFile("/sys/devices/system/node/online")
bytes, err := ioutil.ReadFile(source.SysfsDir.Path("devices/system/node/online"))
if err != nil {
return false, err
}
@ -81,7 +81,7 @@ func detectNvdimm() (map[string]bool, error) {
features := make(map[string]bool)
// Check presence of physical devices
devices, err := ioutil.ReadDir("/sys/class/nd/")
devices, err := ioutil.ReadDir(source.SysfsDir.Path("class/nd"))
if err == nil {
if len(devices) > 0 {
features["present"] = true
@ -93,7 +93,7 @@ func detectNvdimm() (map[string]bool, error) {
}
// Check presence of DAX-configured regions
devices, err = ioutil.ReadDir("/sys/bus/nd/devices/")
devices, err = ioutil.ReadDir(source.SysfsDir.Path("bus/nd/devices"))
if err == nil {
for _, d := range devices {
if strings.HasPrefix(d.Name(), "dax") {

View file

@ -44,8 +44,7 @@ func (s Source) Discover() (source.Features, error) {
// iterating through network interfaces to obtain their respective number of virtual functions
for _, netInterface := range netInterfaces {
if strings.Contains(netInterface.Flags.String(), "up") && !strings.Contains(netInterface.Flags.String(), "loopback") {
totalVfsPath := "/sys/class/net/" + netInterface.Name + "/device/sriov_totalvfs"
totalBytes, err := ioutil.ReadFile(totalVfsPath)
totalBytes, err := ioutil.ReadFile(source.SysfsDir.Path("class/net", netInterface.Name, "device/sriov_totalvfs"))
if err != nil {
log.Printf("SR-IOV not supported for network interface: %s: %v", netInterface.Name, err)
continue
@ -60,8 +59,7 @@ func (s Source) Discover() (source.Features, error) {
log.Printf("SR-IOV capability is detected on the network interface: %s", netInterface.Name)
log.Printf("%d maximum supported number of virtual functions on network interface: %s", t, netInterface.Name)
features["sriov.capable"] = true
numVfsPath := "/sys/class/net/" + netInterface.Name + "/device/sriov_numvfs"
numBytes, err := ioutil.ReadFile(numVfsPath)
numBytes, err := ioutil.ReadFile(source.SysfsDir.Path("class/net", netInterface.Name, "device/sriov_numvfs"))
if err != nil {
log.Printf("SR-IOV not configured for network interface: %s: %s", netInterface.Name, err)
continue

View file

@ -34,10 +34,10 @@ func (s Source) Discover() (source.Features, error) {
features := source.Features{}
// Check if there is any non-rotational block devices attached to the node
blockdevices, err := ioutil.ReadDir("/sys/block/")
blockdevices, err := ioutil.ReadDir(source.SysfsDir.Path("block"))
if err == nil {
for _, bdev := range blockdevices {
fname := "/sys/block/" + bdev.Name() + "/queue/rotational"
fname := source.SysfsDir.Path("block", bdev.Name(), "queue/rotational")
bytes, err := ioutil.ReadFile(fname)
if err != nil {
return nil, fmt.Errorf("can't read rotational status: %s", err.Error())

View file

@ -66,7 +66,7 @@ func (s Source) Discover() (source.Features, error) {
func parseOSRelease() (map[string]string, error) {
release := map[string]string{}
f, err := os.Open("/host-etc/os-release")
f, err := os.Open(source.EtcDir.Path("os-release"))
if err != nil {
return nil, err
}