diff --git a/cmd/sriov-network-config-daemon/service.go b/cmd/sriov-network-config-daemon/service.go index f86151cb7..afa5a5582 100644 --- a/cmd/sriov-network-config-daemon/service.go +++ b/cmd/sriov-network-config-daemon/service.go @@ -146,9 +146,9 @@ func phasePre(setupLog logr.Logger, conf *systemd.SriovConfig, hostHelpers helpe return fmt.Errorf("failed to remove sriov result file: %v", err) } - _, err := hostHelpers.TryEnableRdma() + _, err := hostHelpers.CheckRDMAEnabled() if err != nil { - setupLog.Error(err, "warning, failed to enable RDMA") + setupLog.Error(err, "warning, failed to check RDMA state") } hostHelpers.TryEnableTun() hostHelpers.TryEnableVhostNet() diff --git a/cmd/sriov-network-config-daemon/service_test.go b/cmd/sriov-network-config-daemon/service_test.go index 629949060..d7b9134f8 100644 --- a/cmd/sriov-network-config-daemon/service_test.go +++ b/cmd/sriov-network-config-daemon/service_test.go @@ -158,7 +158,7 @@ var _ = Describe("Service", func() { "/etc/sriov-operator/sriov-interface-result.yaml": []byte("something"), }, }) - hostHelpers.EXPECT().TryEnableRdma().Return(true, nil) + hostHelpers.EXPECT().CheckRDMAEnabled().Return(true, nil) hostHelpers.EXPECT().TryEnableTun().Return() hostHelpers.EXPECT().TryEnableVhostNet().Return() hostHelpers.EXPECT().DiscoverSriovDevices(hostHelpers).Return([]sriovnetworkv1.InterfaceExt{{ @@ -183,7 +183,7 @@ var _ = Describe("Service", func() { "/etc/sriov-operator/sriov-interface-result.yaml": []byte("something"), }, }) - hostHelpers.EXPECT().TryEnableRdma().Return(true, nil) + hostHelpers.EXPECT().CheckRDMAEnabled().Return(true, nil) hostHelpers.EXPECT().TryEnableTun().Return() hostHelpers.EXPECT().TryEnableVhostNet().Return() @@ -211,7 +211,7 @@ var _ = Describe("Service", func() { "/etc/sriov-operator/sriov-interface-result.yaml": []byte("something"), }, }) - hostHelpers.EXPECT().TryEnableRdma().Return(true, nil) + hostHelpers.EXPECT().CheckRDMAEnabled().Return(true, nil) hostHelpers.EXPECT().TryEnableTun().Return() hostHelpers.EXPECT().TryEnableVhostNet().Return() hostHelpers.EXPECT().DiscoverSriovDevices(hostHelpers).Return([]sriovnetworkv1.InterfaceExt{{ diff --git a/doc/quickstart.md b/doc/quickstart.md index f3f352bb5..18d686741 100644 --- a/doc/quickstart.md +++ b/doc/quickstart.md @@ -5,6 +5,7 @@ 1. A supported SRIOV hardware on the cluster nodes. Supported models can be found [here](https://github.com/k8snetworkplumbingwg/sriov-network-operator/blob/master/doc/supported-hardware.md). 2. Kubernetes or Openshift cluster running on bare metal nodes. 3. Multus-cni is deployed as default CNI plugin, and there is a default CNI plugin (flannel, openshift-sdn etc.) available for Multus-cni. +4. On RedHat Enterprise Linux and Ubuntu operating systems, the `rdma-core` package must be installed to support RDMA resource provisioning. On RedHat CoreOS the package installation is not required. ## Installation diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 0fd1ec2cb..4af9958f7 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -129,7 +129,7 @@ func (dn *Daemon) Run(stopCh <-chan struct{}, exitCh <-chan error) error { if !vars.UsingSystemdMode { log.Log.V(0).Info("Run(): daemon running in daemon mode") - dn.HostHelpers.TryEnableRdma() + dn.HostHelpers.CheckRDMAEnabled() dn.HostHelpers.TryEnableTun() dn.HostHelpers.TryEnableVhostNet() err := systemd.CleanSriovFilesFromHost(vars.ClusterType == consts.ClusterTypeOpenshift) diff --git a/pkg/daemon/daemon_test.go b/pkg/daemon/daemon_test.go index a1e29dcb2..ce932a1f1 100644 --- a/pkg/daemon/daemon_test.go +++ b/pkg/daemon/daemon_test.go @@ -145,7 +145,7 @@ var _ = Describe("Config Daemon", func() { platformHelper.EXPECT().IsHypershift().Return(false).AnyTimes() vendorHelper := mock_helper.NewMockHostHelpersInterface(mockCtrl) - vendorHelper.EXPECT().TryEnableRdma().Return(true, nil).AnyTimes() + vendorHelper.EXPECT().CheckRDMAEnabled().Return(true, nil).AnyTimes() vendorHelper.EXPECT().TryEnableVhostNet().AnyTimes() vendorHelper.EXPECT().TryEnableTun().AnyTimes() vendorHelper.EXPECT().PrepareNMUdevRule([]string{"0x1014", "0x154c"}).Return(nil).AnyTimes() diff --git a/pkg/helper/mock/mock_helper.go b/pkg/helper/mock/mock_helper.go index 23b32a1d4..baf48f2e3 100644 --- a/pkg/helper/mock/mock_helper.go +++ b/pkg/helper/mock/mock_helper.go @@ -122,6 +122,21 @@ func (mr *MockHostHelpersInterfaceMockRecorder) BindDriverByBusAndDevice(bus, de return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindDriverByBusAndDevice", reflect.TypeOf((*MockHostHelpersInterface)(nil).BindDriverByBusAndDevice), bus, device, driver) } +// CheckRDMAEnabled mocks base method. +func (m *MockHostHelpersInterface) CheckRDMAEnabled() (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckRDMAEnabled") + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckRDMAEnabled indicates an expected call of CheckRDMAEnabled. +func (mr *MockHostHelpersInterfaceMockRecorder) CheckRDMAEnabled() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRDMAEnabled", reflect.TypeOf((*MockHostHelpersInterface)(nil).CheckRDMAEnabled)) +} + // Chroot mocks base method. func (m *MockHostHelpersInterface) Chroot(arg0 string) (func() error, error) { m.ctrl.T.Helper() @@ -279,36 +294,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) EnableHwTcOffload(ifaceName inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableHwTcOffload", reflect.TypeOf((*MockHostHelpersInterface)(nil).EnableHwTcOffload), ifaceName) } -// EnableRDMA mocks base method. -func (m *MockHostHelpersInterface) EnableRDMA(conditionFilePath, serviceName, packageManager string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnableRDMA", conditionFilePath, serviceName, packageManager) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// EnableRDMA indicates an expected call of EnableRDMA. -func (mr *MockHostHelpersInterfaceMockRecorder) EnableRDMA(conditionFilePath, serviceName, packageManager interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableRDMA", reflect.TypeOf((*MockHostHelpersInterface)(nil).EnableRDMA), conditionFilePath, serviceName, packageManager) -} - -// EnableRDMAOnRHELMachine mocks base method. -func (m *MockHostHelpersInterface) EnableRDMAOnRHELMachine() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnableRDMAOnRHELMachine") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// EnableRDMAOnRHELMachine indicates an expected call of EnableRDMAOnRHELMachine. -func (mr *MockHostHelpersInterfaceMockRecorder) EnableRDMAOnRHELMachine() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableRDMAOnRHELMachine", reflect.TypeOf((*MockHostHelpersInterface)(nil).EnableRDMAOnRHELMachine)) -} - // EnableService mocks base method. func (m *MockHostHelpersInterface) EnableService(service *types.Service) error { m.ctrl.T.Helper() @@ -527,21 +512,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) GetNicSriovMode(pciAddr interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNicSriovMode", reflect.TypeOf((*MockHostHelpersInterface)(nil).GetNicSriovMode), pciAddr) } -// GetOSPrettyName mocks base method. -func (m *MockHostHelpersInterface) GetOSPrettyName() (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOSPrettyName") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOSPrettyName indicates an expected call of GetOSPrettyName. -func (mr *MockHostHelpersInterfaceMockRecorder) GetOSPrettyName() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOSPrettyName", reflect.TypeOf((*MockHostHelpersInterface)(nil).GetOSPrettyName)) -} - // GetPciAddressFromInterfaceName mocks base method. func (m *MockHostHelpersInterface) GetPciAddressFromInterfaceName(interfaceName string) (string, error) { m.ctrl.T.Helper() @@ -602,35 +572,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) HasDriver(pciAddr interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasDriver", reflect.TypeOf((*MockHostHelpersInterface)(nil).HasDriver), pciAddr) } -// InstallRDMA mocks base method. -func (m *MockHostHelpersInterface) InstallRDMA(packageManager string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InstallRDMA", packageManager) - ret0, _ := ret[0].(error) - return ret0 -} - -// InstallRDMA indicates an expected call of InstallRDMA. -func (mr *MockHostHelpersInterfaceMockRecorder) InstallRDMA(packageManager interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallRDMA", reflect.TypeOf((*MockHostHelpersInterface)(nil).InstallRDMA), packageManager) -} - -// IsCoreOS mocks base method. -func (m *MockHostHelpersInterface) IsCoreOS() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsCoreOS") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsCoreOS indicates an expected call of IsCoreOS. -func (mr *MockHostHelpersInterfaceMockRecorder) IsCoreOS() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsCoreOS", reflect.TypeOf((*MockHostHelpersInterface)(nil).IsCoreOS)) -} - // IsKernelArgsSet mocks base method. func (m *MockHostHelpersInterface) IsKernelArgsSet(cmdLine, karg string) bool { m.ctrl.T.Helper() @@ -674,21 +615,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) IsKernelModuleLoaded(name interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsKernelModuleLoaded", reflect.TypeOf((*MockHostHelpersInterface)(nil).IsKernelModuleLoaded), name) } -// IsRHELSystem mocks base method. -func (m *MockHostHelpersInterface) IsRHELSystem() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsRHELSystem") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsRHELSystem indicates an expected call of IsRHELSystem. -func (mr *MockHostHelpersInterfaceMockRecorder) IsRHELSystem() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRHELSystem", reflect.TypeOf((*MockHostHelpersInterface)(nil).IsRHELSystem)) -} - // IsServiceEnabled mocks base method. func (m *MockHostHelpersInterface) IsServiceEnabled(servicePath string) (bool, error) { m.ctrl.T.Helper() @@ -733,21 +659,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) IsSwitchdev(name interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSwitchdev", reflect.TypeOf((*MockHostHelpersInterface)(nil).IsSwitchdev), name) } -// IsUbuntuSystem mocks base method. -func (m *MockHostHelpersInterface) IsUbuntuSystem() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsUbuntuSystem") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsUbuntuSystem indicates an expected call of IsUbuntuSystem. -func (mr *MockHostHelpersInterfaceMockRecorder) IsUbuntuSystem() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsUbuntuSystem", reflect.TypeOf((*MockHostHelpersInterface)(nil).IsUbuntuSystem)) -} - // LoadKernelModule mocks base method. func (m *MockHostHelpersInterface) LoadKernelModule(name string, args ...string) error { m.ctrl.T.Helper() @@ -855,21 +766,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) PrepareVFRepUdevRule() *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareVFRepUdevRule", reflect.TypeOf((*MockHostHelpersInterface)(nil).PrepareVFRepUdevRule)) } -// RdmaIsLoaded mocks base method. -func (m *MockHostHelpersInterface) RdmaIsLoaded() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RdmaIsLoaded") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RdmaIsLoaded indicates an expected call of RdmaIsLoaded. -func (mr *MockHostHelpersInterfaceMockRecorder) RdmaIsLoaded() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RdmaIsLoaded", reflect.TypeOf((*MockHostHelpersInterface)(nil).RdmaIsLoaded)) -} - // ReadService mocks base method. func (m *MockHostHelpersInterface) ReadService(servicePath string) (*types.Service, error) { m.ctrl.T.Helper() @@ -929,20 +825,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) RebindVfToDefaultDriver(pciAddr return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebindVfToDefaultDriver", reflect.TypeOf((*MockHostHelpersInterface)(nil).RebindVfToDefaultDriver), pciAddr) } -// ReloadDriver mocks base method. -func (m *MockHostHelpersInterface) ReloadDriver(driver string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReloadDriver", driver) - ret0, _ := ret[0].(error) - return ret0 -} - -// ReloadDriver indicates an expected call of ReloadDriver. -func (mr *MockHostHelpersInterfaceMockRecorder) ReloadDriver(driver interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReloadDriver", reflect.TypeOf((*MockHostHelpersInterface)(nil).ReloadDriver), driver) -} - // RemoveDisableNMUdevRule mocks base method. func (m *MockHostHelpersInterface) RemoveDisableNMUdevRule(pfPciAddress string) error { m.ctrl.T.Helper() @@ -1118,35 +1000,6 @@ func (mr *MockHostHelpersInterfaceMockRecorder) SetVfAdminMac(vfAddr, pfLink, vf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetVfAdminMac", reflect.TypeOf((*MockHostHelpersInterface)(nil).SetVfAdminMac), vfAddr, pfLink, vfLink) } -// TriggerUdevEvent mocks base method. -func (m *MockHostHelpersInterface) TriggerUdevEvent() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TriggerUdevEvent") - ret0, _ := ret[0].(error) - return ret0 -} - -// TriggerUdevEvent indicates an expected call of TriggerUdevEvent. -func (mr *MockHostHelpersInterfaceMockRecorder) TriggerUdevEvent() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerUdevEvent", reflect.TypeOf((*MockHostHelpersInterface)(nil).TriggerUdevEvent)) -} - -// TryEnableRdma mocks base method. -func (m *MockHostHelpersInterface) TryEnableRdma() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TryEnableRdma") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// TryEnableRdma indicates an expected call of TryEnableRdma. -func (mr *MockHostHelpersInterfaceMockRecorder) TryEnableRdma() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryEnableRdma", reflect.TypeOf((*MockHostHelpersInterface)(nil).TryEnableRdma)) -} - // TryEnableTun mocks base method. func (m *MockHostHelpersInterface) TryEnableTun() { m.ctrl.T.Helper() diff --git a/pkg/host/internal/common.go b/pkg/host/internal/common.go deleted file mode 100644 index b32d2cd93..000000000 --- a/pkg/host/internal/common.go +++ /dev/null @@ -1,19 +0,0 @@ -package internal - -import ( - "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" -) - -const ( - HostPathFromDaemon = consts.Host - RedhatReleaseFile = "/etc/redhat-release" - RhelRDMAConditionFile = "/usr/libexec/rdma-init-kernel" - RhelRDMAServiceName = "rdma" - RhelPackageManager = "yum" - - UbuntuRDMAConditionFile = "/usr/sbin/rdma-ndd" - UbuntuRDMAServiceName = "rdma-ndd" - UbuntuPackageManager = "apt-get" - - GenericOSReleaseFile = "/etc/os-release" -) diff --git a/pkg/host/internal/kernel/kernel.go b/pkg/host/internal/kernel/kernel.go index 958f2590a..95a5c44a5 100644 --- a/pkg/host/internal/kernel/kernel.go +++ b/pkg/host/internal/kernel/kernel.go @@ -11,7 +11,6 @@ import ( sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts" - "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/internal" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/types" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils" "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars" @@ -259,320 +258,43 @@ func (k *kernel) GetDriverByBusAndDevice(bus, device string) (string, error) { return getDriverByBusAndDevice(bus, device) } -func (k *kernel) TryEnableRdma() (bool, error) { - log.Log.V(2).Info("tryEnableRdma()") +// CheckRDMAEnabled returns true if RDMA modules are loaded on host +func (k *kernel) CheckRDMAEnabled() (bool, error) { + log.Log.V(2).Info("CheckRDMAEnabled()") chrootDefinition := utils.GetChrootExtension() - // check if the driver is already loaded in to the system - _, stderr, mlx4Err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("grep --quiet 'mlx4_en' <(%s lsmod)", chrootDefinition)) - if mlx4Err != nil && len(stderr) != 0 { - log.Log.Error(mlx4Err, "tryEnableRdma(): failed to check for kernel module 'mlx4_en'", "stderr", stderr) - return false, fmt.Errorf(stderr) - } - - _, stderr, mlx5Err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("grep --quiet 'mlx5_core' <(%s lsmod)", chrootDefinition)) + _, stderr, mlx5Err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("%s lsmod | grep --quiet 'mlx5_core'", chrootDefinition)) if mlx5Err != nil && len(stderr) != 0 { - log.Log.Error(mlx5Err, "tryEnableRdma(): failed to check for kernel module 'mlx5_core'", "stderr", stderr) + log.Log.Error(mlx5Err, "CheckRDMAEnabled(): failed to check for kernel module 'mlx5_core'", "stderr", stderr) return false, fmt.Errorf(stderr) } - if mlx4Err != nil && mlx5Err != nil { - log.Log.Error(nil, "tryEnableRdma(): no RDMA capable devices") + if mlx5Err != nil { + log.Log.Error(nil, "CheckRDMAEnabled(): no RDMA capable devices") return false, nil } - - isRhelSystem, err := k.IsRHELSystem() - if err != nil { - log.Log.Error(err, "tryEnableRdma(): failed to check if the machine is base on RHEL") - return false, err - } - - // RHEL check - if isRhelSystem { - return k.EnableRDMAOnRHELMachine() - } - - isUbuntuSystem, err := k.IsUbuntuSystem() - if err != nil { - log.Log.Error(err, "tryEnableRdma(): failed to check if the machine is base on Ubuntu") - return false, err - } - - if isUbuntuSystem { - return k.EnableRDMAOnUbuntuMachine() - } - - osName, err := k.GetOSPrettyName() - if err != nil { - log.Log.Error(err, "tryEnableRdma(): failed to check OS name") - return false, err - } - - log.Log.Error(nil, "tryEnableRdma(): Unsupported OS", "name", osName) - return false, fmt.Errorf("unable to load RDMA unsupported OS: %s", osName) -} - -func (k *kernel) EnableRDMAOnRHELMachine() (bool, error) { - log.Log.Info("EnableRDMAOnRHELMachine()") - isCoreOsSystem, err := k.IsCoreOS() - if err != nil { - log.Log.Error(err, "EnableRDMAOnRHELMachine(): failed to check if the machine runs CoreOS") - return false, err - } - - // CoreOS check - if isCoreOsSystem { - isRDMALoaded, err := k.RdmaIsLoaded() - if err != nil { - log.Log.Error(err, "EnableRDMAOnRHELMachine(): failed to check if RDMA kernel modules are loaded") - return false, err - } - - return isRDMALoaded, nil - } - - // RHEL - log.Log.Info("EnableRDMAOnRHELMachine(): enabling RDMA on RHEL machine") - isRDMAEnable, err := k.EnableRDMA(internal.RhelRDMAConditionFile, internal.RhelRDMAServiceName, internal.RhelPackageManager) - if err != nil { - log.Log.Error(err, "EnableRDMAOnRHELMachine(): failed to enable RDMA on RHEL machine") - return false, err - } - - // check if we need to install rdma-core package - if isRDMAEnable { - isRDMALoaded, err := k.RdmaIsLoaded() - if err != nil { - log.Log.Error(err, "EnableRDMAOnRHELMachine(): failed to check if RDMA kernel modules are loaded") - return false, err - } - - // if ib kernel module is not loaded trigger a loading - if isRDMALoaded { - err = k.TriggerUdevEvent() - if err != nil { - log.Log.Error(err, "EnableRDMAOnRHELMachine() failed to trigger udev event") - return false, err - } - } - } - - return true, nil -} - -func (k *kernel) EnableRDMAOnUbuntuMachine() (bool, error) { - log.Log.Info("EnableRDMAOnUbuntuMachine(): enabling RDMA on RHEL machine") - isRDMAEnable, err := k.EnableRDMA(internal.UbuntuRDMAConditionFile, internal.UbuntuRDMAServiceName, internal.UbuntuPackageManager) - if err != nil { - log.Log.Error(err, "EnableRDMAOnUbuntuMachine(): failed to enable RDMA on Ubuntu machine") - return false, err - } - - // check if we need to install rdma-core package - if isRDMAEnable { - isRDMALoaded, err := k.RdmaIsLoaded() - if err != nil { - log.Log.Error(err, "EnableRDMAOnUbuntuMachine(): failed to check if RDMA kernel modules are loaded") - return false, err - } - - // if ib kernel module is not loaded trigger a loading - if isRDMALoaded { - err = k.TriggerUdevEvent() - if err != nil { - log.Log.Error(err, "EnableRDMAOnUbuntuMachine() failed to trigger udev event") - return false, err - } - } - } - - return true, nil -} - -func (k *kernel) IsRHELSystem() (bool, error) { - log.Log.Info("IsRHELSystem(): checking for RHEL machine") - path := internal.RedhatReleaseFile - if !vars.UsingSystemdMode { - path = filepath.Join(internal.HostPathFromDaemon, path) - } - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - log.Log.V(2).Info("IsRHELSystem() not a RHEL machine") - return false, nil - } - - log.Log.Error(err, "IsRHELSystem() failed to check for os release file", "path", path) - return false, err - } - - return true, nil -} - -func (k *kernel) IsCoreOS() (bool, error) { - log.Log.Info("IsCoreOS(): checking for CoreOS machine") - path := internal.RedhatReleaseFile - if !vars.UsingSystemdMode { - path = filepath.Join(internal.HostPathFromDaemon, path) - } - - data, err := os.ReadFile(path) - if err != nil { - log.Log.Error(err, "IsCoreOS(): failed to read RHEL release file on path", "path", path) - return false, err - } - - if strings.Contains(string(data), "CoreOS") { - return true, nil - } - - return false, nil -} - -func (k *kernel) IsUbuntuSystem() (bool, error) { - log.Log.Info("IsUbuntuSystem(): checking for Ubuntu machine") - path := internal.GenericOSReleaseFile - if !vars.UsingSystemdMode { - path = filepath.Join(internal.HostPathFromDaemon, path) - } - - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - log.Log.Error(nil, "IsUbuntuSystem() os-release on path doesn't exist", "path", path) - return false, err - } - - log.Log.Error(err, "IsUbuntuSystem() failed to check for os release file", "path", path) - return false, err - } - - stdout, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("grep -i --quiet 'ubuntu' %s", path)) - if err != nil && len(stderr) != 0 { - log.Log.Error(err, "IsUbuntuSystem(): failed to check for ubuntu operating system name in os-releasae file", "stderr", stderr) - return false, fmt.Errorf(stderr) - } - - if len(stdout) > 0 { - return true, nil - } - - return false, nil + return k.rdmaModulesAreLoaded() } -func (k *kernel) RdmaIsLoaded() (bool, error) { - log.Log.V(2).Info("RdmaIsLoaded()") +func (k *kernel) rdmaModulesAreLoaded() (bool, error) { + log.Log.V(2).Info("rdmaModulesAreLoaded()") chrootDefinition := utils.GetChrootExtension() // check if the driver is already loaded in to the system - _, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("grep --quiet '\\(^ib\\|^rdma\\)' <(%s lsmod)", chrootDefinition)) + _, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("%s lsmod | grep --quiet '\\(^ib\\|^rdma\\)'", chrootDefinition)) if err != nil && len(stderr) != 0 { - log.Log.Error(err, "RdmaIsLoaded(): fail to check if ib and rdma kernel modules are loaded", "stderr", stderr) + log.Log.Error(err, "rdmaModulesAreLoaded(): fail to check if ib and rdma kernel modules are loaded", "stderr", stderr) return false, fmt.Errorf(stderr) } if err != nil { + log.Log.Error(nil, "rdmaModulesAreLoaded(): RDMA modules are not loaded, you may need to install rdma-core package") return false, nil } - + log.Log.V(2).Info("rdmaModulesAreLoaded(): RDMA modules are loaded") return true, nil } -func (k *kernel) EnableRDMA(conditionFilePath, serviceName, packageManager string) (bool, error) { - path := conditionFilePath - if !vars.UsingSystemdMode { - path = filepath.Join(internal.HostPathFromDaemon, path) - } - log.Log.Info("EnableRDMA(): checking for service file", "path", path) - - if _, err := os.Stat(path); err != nil { - if os.IsNotExist(err) { - log.Log.V(2).Info("EnableRDMA(): RDMA server doesn't exist") - err = k.InstallRDMA(packageManager) - if err != nil { - log.Log.Error(err, "EnableRDMA() failed to install RDMA package") - return false, err - } - - err = k.TriggerUdevEvent() - if err != nil { - log.Log.Error(err, "EnableRDMA() failed to trigger udev event") - return false, err - } - - return false, nil - } - - log.Log.Error(err, "EnableRDMA() failed to check for os release file", "path", path) - return false, err - } - - log.Log.Info("EnableRDMA(): service installed", "name", serviceName) - return true, nil -} - -func (k *kernel) InstallRDMA(packageManager string) error { - log.Log.Info("InstallRDMA(): installing RDMA") - chrootDefinition := utils.GetChrootExtension() - - stdout, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("%s %s install -y rdma-core", chrootDefinition, packageManager)) - if err != nil && len(stderr) != 0 { - log.Log.Error(err, "InstallRDMA(): failed to install RDMA package", "stdout", stdout, "stderr", stderr) - return err - } - - return nil -} - -func (k *kernel) TriggerUdevEvent() error { - log.Log.Info("TriggerUdevEvent(): installing RDMA") - - err := k.ReloadDriver("mlx4_en") - if err != nil { - return err - } - - err = k.ReloadDriver("mlx5_core") - if err != nil { - return err - } - - return nil -} - -func (k *kernel) ReloadDriver(driverName string) error { - log.Log.Info("ReloadDriver(): reload driver", "name", driverName) - chrootDefinition := utils.GetChrootExtension() - - _, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("%s modprobe -r %s && %s modprobe %s", chrootDefinition, driverName, chrootDefinition, driverName)) - if err != nil && len(stderr) != 0 { - log.Log.Error(err, "ReloadDriver(): failed to reload kernel module", - "name", driverName, "stderr", stderr) - return err - } - - return nil -} - -func (k *kernel) GetOSPrettyName() (string, error) { - path := internal.GenericOSReleaseFile - if !vars.UsingSystemdMode { - path = filepath.Join(internal.HostPathFromDaemon, path) - } - - log.Log.Info("GetOSPrettyName(): getting os name from os-release file") - - stdout, stderr, err := k.utilsHelper.RunCommand("/bin/sh", "-c", fmt.Sprintf("cat %s | grep PRETTY_NAME | cut -c 13-", path)) - if err != nil && len(stderr) != 0 { - log.Log.Error(err, "GetOSPrettyName(): failed to check for operating system name in os-release file", "stderr", stderr) - return "", fmt.Errorf(stderr) - } - - if len(stdout) > 0 { - return stdout, nil - } - - return "", fmt.Errorf("failed to find pretty operating system name") -} - // IsKernelLockdownMode returns true when kernel lockdown mode is enabled // TODO: change this to return error func (k *kernel) IsKernelLockdownMode() bool { diff --git a/pkg/host/mock/mock_host.go b/pkg/host/mock/mock_host.go index 72155f557..36c96b69a 100644 --- a/pkg/host/mock/mock_host.go +++ b/pkg/host/mock/mock_host.go @@ -121,6 +121,21 @@ func (mr *MockHostManagerInterfaceMockRecorder) BindDriverByBusAndDevice(bus, de return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindDriverByBusAndDevice", reflect.TypeOf((*MockHostManagerInterface)(nil).BindDriverByBusAndDevice), bus, device, driver) } +// CheckRDMAEnabled mocks base method. +func (m *MockHostManagerInterface) CheckRDMAEnabled() (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckRDMAEnabled") + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckRDMAEnabled indicates an expected call of CheckRDMAEnabled. +func (mr *MockHostManagerInterfaceMockRecorder) CheckRDMAEnabled() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRDMAEnabled", reflect.TypeOf((*MockHostManagerInterface)(nil).CheckRDMAEnabled)) +} + // CompareServices mocks base method. func (m *MockHostManagerInterface) CompareServices(serviceA, serviceB *types.Service) (bool, error) { m.ctrl.T.Helper() @@ -249,36 +264,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) EnableHwTcOffload(ifaceName inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableHwTcOffload", reflect.TypeOf((*MockHostManagerInterface)(nil).EnableHwTcOffload), ifaceName) } -// EnableRDMA mocks base method. -func (m *MockHostManagerInterface) EnableRDMA(conditionFilePath, serviceName, packageManager string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnableRDMA", conditionFilePath, serviceName, packageManager) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// EnableRDMA indicates an expected call of EnableRDMA. -func (mr *MockHostManagerInterfaceMockRecorder) EnableRDMA(conditionFilePath, serviceName, packageManager interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableRDMA", reflect.TypeOf((*MockHostManagerInterface)(nil).EnableRDMA), conditionFilePath, serviceName, packageManager) -} - -// EnableRDMAOnRHELMachine mocks base method. -func (m *MockHostManagerInterface) EnableRDMAOnRHELMachine() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EnableRDMAOnRHELMachine") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// EnableRDMAOnRHELMachine indicates an expected call of EnableRDMAOnRHELMachine. -func (mr *MockHostManagerInterfaceMockRecorder) EnableRDMAOnRHELMachine() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableRDMAOnRHELMachine", reflect.TypeOf((*MockHostManagerInterface)(nil).EnableRDMAOnRHELMachine)) -} - // EnableService mocks base method. func (m *MockHostManagerInterface) EnableService(service *types.Service) error { m.ctrl.T.Helper() @@ -451,21 +436,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) GetNicSriovMode(pciAddr interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNicSriovMode", reflect.TypeOf((*MockHostManagerInterface)(nil).GetNicSriovMode), pciAddr) } -// GetOSPrettyName mocks base method. -func (m *MockHostManagerInterface) GetOSPrettyName() (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOSPrettyName") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOSPrettyName indicates an expected call of GetOSPrettyName. -func (mr *MockHostManagerInterfaceMockRecorder) GetOSPrettyName() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOSPrettyName", reflect.TypeOf((*MockHostManagerInterface)(nil).GetOSPrettyName)) -} - // GetPciAddressFromInterfaceName mocks base method. func (m *MockHostManagerInterface) GetPciAddressFromInterfaceName(interfaceName string) (string, error) { m.ctrl.T.Helper() @@ -526,35 +496,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) HasDriver(pciAddr interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasDriver", reflect.TypeOf((*MockHostManagerInterface)(nil).HasDriver), pciAddr) } -// InstallRDMA mocks base method. -func (m *MockHostManagerInterface) InstallRDMA(packageManager string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InstallRDMA", packageManager) - ret0, _ := ret[0].(error) - return ret0 -} - -// InstallRDMA indicates an expected call of InstallRDMA. -func (mr *MockHostManagerInterfaceMockRecorder) InstallRDMA(packageManager interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallRDMA", reflect.TypeOf((*MockHostManagerInterface)(nil).InstallRDMA), packageManager) -} - -// IsCoreOS mocks base method. -func (m *MockHostManagerInterface) IsCoreOS() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsCoreOS") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsCoreOS indicates an expected call of IsCoreOS. -func (mr *MockHostManagerInterfaceMockRecorder) IsCoreOS() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsCoreOS", reflect.TypeOf((*MockHostManagerInterface)(nil).IsCoreOS)) -} - // IsKernelArgsSet mocks base method. func (m *MockHostManagerInterface) IsKernelArgsSet(cmdLine, karg string) bool { m.ctrl.T.Helper() @@ -598,21 +539,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) IsKernelModuleLoaded(name interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsKernelModuleLoaded", reflect.TypeOf((*MockHostManagerInterface)(nil).IsKernelModuleLoaded), name) } -// IsRHELSystem mocks base method. -func (m *MockHostManagerInterface) IsRHELSystem() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsRHELSystem") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsRHELSystem indicates an expected call of IsRHELSystem. -func (mr *MockHostManagerInterfaceMockRecorder) IsRHELSystem() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRHELSystem", reflect.TypeOf((*MockHostManagerInterface)(nil).IsRHELSystem)) -} - // IsServiceEnabled mocks base method. func (m *MockHostManagerInterface) IsServiceEnabled(servicePath string) (bool, error) { m.ctrl.T.Helper() @@ -657,21 +583,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) IsSwitchdev(name interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSwitchdev", reflect.TypeOf((*MockHostManagerInterface)(nil).IsSwitchdev), name) } -// IsUbuntuSystem mocks base method. -func (m *MockHostManagerInterface) IsUbuntuSystem() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsUbuntuSystem") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IsUbuntuSystem indicates an expected call of IsUbuntuSystem. -func (mr *MockHostManagerInterfaceMockRecorder) IsUbuntuSystem() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsUbuntuSystem", reflect.TypeOf((*MockHostManagerInterface)(nil).IsUbuntuSystem)) -} - // LoadKernelModule mocks base method. func (m *MockHostManagerInterface) LoadKernelModule(name string, args ...string) error { m.ctrl.T.Helper() @@ -733,21 +644,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) PrepareVFRepUdevRule() *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareVFRepUdevRule", reflect.TypeOf((*MockHostManagerInterface)(nil).PrepareVFRepUdevRule)) } -// RdmaIsLoaded mocks base method. -func (m *MockHostManagerInterface) RdmaIsLoaded() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RdmaIsLoaded") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RdmaIsLoaded indicates an expected call of RdmaIsLoaded. -func (mr *MockHostManagerInterfaceMockRecorder) RdmaIsLoaded() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RdmaIsLoaded", reflect.TypeOf((*MockHostManagerInterface)(nil).RdmaIsLoaded)) -} - // ReadService mocks base method. func (m *MockHostManagerInterface) ReadService(servicePath string) (*types.Service, error) { m.ctrl.T.Helper() @@ -807,20 +703,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) RebindVfToDefaultDriver(pciAddr return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebindVfToDefaultDriver", reflect.TypeOf((*MockHostManagerInterface)(nil).RebindVfToDefaultDriver), pciAddr) } -// ReloadDriver mocks base method. -func (m *MockHostManagerInterface) ReloadDriver(driver string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReloadDriver", driver) - ret0, _ := ret[0].(error) - return ret0 -} - -// ReloadDriver indicates an expected call of ReloadDriver. -func (mr *MockHostManagerInterfaceMockRecorder) ReloadDriver(driver interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReloadDriver", reflect.TypeOf((*MockHostManagerInterface)(nil).ReloadDriver), driver) -} - // RemoveDisableNMUdevRule mocks base method. func (m *MockHostManagerInterface) RemoveDisableNMUdevRule(pfPciAddress string) error { m.ctrl.T.Helper() @@ -947,35 +829,6 @@ func (mr *MockHostManagerInterfaceMockRecorder) SetVfAdminMac(vfAddr, pfLink, vf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetVfAdminMac", reflect.TypeOf((*MockHostManagerInterface)(nil).SetVfAdminMac), vfAddr, pfLink, vfLink) } -// TriggerUdevEvent mocks base method. -func (m *MockHostManagerInterface) TriggerUdevEvent() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TriggerUdevEvent") - ret0, _ := ret[0].(error) - return ret0 -} - -// TriggerUdevEvent indicates an expected call of TriggerUdevEvent. -func (mr *MockHostManagerInterfaceMockRecorder) TriggerUdevEvent() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerUdevEvent", reflect.TypeOf((*MockHostManagerInterface)(nil).TriggerUdevEvent)) -} - -// TryEnableRdma mocks base method. -func (m *MockHostManagerInterface) TryEnableRdma() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TryEnableRdma") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// TryEnableRdma indicates an expected call of TryEnableRdma. -func (mr *MockHostManagerInterfaceMockRecorder) TryEnableRdma() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryEnableRdma", reflect.TypeOf((*MockHostManagerInterface)(nil).TryEnableRdma)) -} - // TryEnableTun mocks base method. func (m *MockHostManagerInterface) TryEnableTun() { m.ctrl.T.Helper() diff --git a/pkg/host/types/interfaces.go b/pkg/host/types/interfaces.go index ea2944938..5918dca34 100644 --- a/pkg/host/types/interfaces.go +++ b/pkg/host/types/interfaces.go @@ -12,12 +12,8 @@ type KernelInterface interface { TryEnableTun() // TryEnableVhostNet load the vhost-net kernel module TryEnableVhostNet() - // TryEnableRdma tries to enable RDMA on the machine base on the operating system - // if the package doesn't exist it will also will try to install it - // supported operating systems are RHEL RHCOS and ubuntu - TryEnableRdma() (bool, error) - // TriggerUdevEvent triggers a udev event - TriggerUdevEvent() error + // CheckRDMAEnabled returns true if RDMA modules are loaded on host + CheckRDMAEnabled() (bool, error) // GetCurrentKernelArgs reads the /proc/cmdline to check the current kernel arguments GetCurrentKernelArgs() (string, error) // IsKernelArgsSet check is the requested kernel arguments are set @@ -52,26 +48,8 @@ type KernelInterface interface { LoadKernelModule(name string, args ...string) error // IsKernelModuleLoaded returns try if the requested kernel module is loaded IsKernelModuleLoaded(name string) (bool, error) - // ReloadDriver reloads a requested driver - ReloadDriver(driver string) error // IsKernelLockdownMode returns true if the kernel is in lockdown mode IsKernelLockdownMode() bool - // IsRHELSystem returns try if the system is a RHEL base - IsRHELSystem() (bool, error) - // IsUbuntuSystem returns try if the system is an ubuntu base - IsUbuntuSystem() (bool, error) - // IsCoreOS returns true if the system is a CoreOS or RHCOS base - IsCoreOS() (bool, error) - // RdmaIsLoaded returns try if RDMA kernel modules are loaded - RdmaIsLoaded() (bool, error) - // EnableRDMA enable RDMA on the system - EnableRDMA(conditionFilePath, serviceName, packageManager string) (bool, error) - // InstallRDMA install RDMA packages on the system - InstallRDMA(packageManager string) error - // EnableRDMAOnRHELMachine enable RDMA on a RHEL base system - EnableRDMAOnRHELMachine() (bool, error) - // GetOSPrettyName returns OS name - GetOSPrettyName() (string, error) } type NetworkInterface interface {