feat: implement device selector for 'physical'
Closes #8090 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
This commit is contained in:
parent
7d11172896
commit
d677901b67
@ -25,6 +25,12 @@ runc: 1.1.11
|
||||
Flannel: 0.24.1
|
||||
|
||||
Talos is built with Go 1.21.6.
|
||||
"""
|
||||
|
||||
[notes.device_selectors]
|
||||
title = "Device Selectors"
|
||||
description = """\
|
||||
Talos Linux now supports `physical: true` qualifier for device selectors, it selects non-virtual network interfaces (i.e. `en0` is selected, while `bond0` is not).
|
||||
"""
|
||||
|
||||
[make_deps]
|
||||
|
@ -210,7 +210,7 @@ func (ctrl *DeviceConfigController) selectDevices(selector talosconfig.NetworkDe
|
||||
for iter := links.Iterator(); iter.Next(); {
|
||||
linkStatus := iter.Value().TypedSpec()
|
||||
|
||||
match := false
|
||||
var match optional.Optional[bool]
|
||||
|
||||
for _, pair := range [][]string{
|
||||
{selector.HardwareAddress(), linkStatus.HardwareAddr.String()},
|
||||
@ -223,15 +223,19 @@ func (ctrl *DeviceConfigController) selectDevices(selector talosconfig.NetworkDe
|
||||
}
|
||||
|
||||
if !glob.Glob(pair[0], pair[1]) {
|
||||
match = false
|
||||
match = optional.Some(false)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
match = true
|
||||
match = optional.Some(true)
|
||||
}
|
||||
|
||||
if match {
|
||||
if selector.Physical() != nil && match.ValueOr(true) {
|
||||
match = optional.Some(*selector.Physical() == linkStatus.Physical())
|
||||
}
|
||||
|
||||
if match.ValueOrZero() {
|
||||
result = append(result, iter.Value())
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
|
||||
"github.com/siderolabs/gen/maps"
|
||||
"github.com/siderolabs/go-pointer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
@ -108,6 +109,13 @@ func (suite *DeviceConfigSpecSuite) TestSelectors() {
|
||||
},
|
||||
DeviceAddresses: []string{"192.168.5.0/24"},
|
||||
},
|
||||
// device selector which matches physical interfaces
|
||||
{
|
||||
DeviceSelector: &v1alpha1.NetworkDeviceSelector{
|
||||
NetworkDevicePhysical: pointer.To(true),
|
||||
},
|
||||
DeviceAddresses: []string{"192.168.6.0/24"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -119,6 +127,7 @@ func (suite *DeviceConfigSpecSuite) TestSelectors() {
|
||||
status := network.NewLinkStatus(network.NamespaceName, "eth0")
|
||||
status.TypedSpec().Driver = kernelDriver
|
||||
status.TypedSpec().BusPath = "0000:01:00.0"
|
||||
status.TypedSpec().Type = nethelpers.LinkEther // physical
|
||||
suite.Require().NoError(suite.State().Create(suite.Ctx(), status))
|
||||
|
||||
status = network.NewLinkStatus(network.NamespaceName, "eth1")
|
||||
@ -143,6 +152,12 @@ func (suite *DeviceConfigSpecSuite) TestSelectors() {
|
||||
assert.Equal([]string{"192.168.5.0/24"}, r.TypedSpec().Device.Addresses())
|
||||
},
|
||||
)
|
||||
|
||||
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []string{"eth0/004"},
|
||||
func(r *network.DeviceConfigSpec, assert *assert.Assertions) {
|
||||
assert.Equal([]string{"192.168.6.0/24"}, r.TypedSpec().Device.Addresses())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (suite *DeviceConfigSpecSuite) TestBondSelectors() {
|
||||
|
@ -291,6 +291,7 @@ type NetworkDeviceSelector interface {
|
||||
HardwareAddress() string
|
||||
PCIID() string
|
||||
KernelDriver() string
|
||||
Physical() *bool
|
||||
}
|
||||
|
||||
// Time defines the requirements for a config that pertains to time related
|
||||
|
@ -838,6 +838,11 @@ func (s *NetworkDeviceSelector) KernelDriver() string {
|
||||
return s.NetworkDeviceKernelDriver
|
||||
}
|
||||
|
||||
// Physical implements config.NetworkDeviceSelector interface.
|
||||
func (s *NetworkDeviceSelector) Physical() *bool {
|
||||
return s.NetworkDevicePhysical
|
||||
}
|
||||
|
||||
// Network implements the MachineNetwork interface.
|
||||
func (r *Route) Network() string {
|
||||
return r.RouteNetwork
|
||||
|
@ -2289,6 +2289,8 @@ type NetworkDeviceSelector struct {
|
||||
NetworkDevicePCIID string `yaml:"pciID,omitempty"`
|
||||
// description: Kernel driver, supports matching by wildcard.
|
||||
NetworkDeviceKernelDriver string `yaml:"driver,omitempty"`
|
||||
// description: Select only physical devices.
|
||||
NetworkDevicePhysical *bool `yaml:"physical,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterDiscoveryConfig struct configures cluster membership discovery.
|
||||
|
@ -3658,6 +3658,13 @@ func (NetworkDeviceSelector) Doc() *encoder.Doc {
|
||||
Description: "Kernel driver, supports matching by wildcard.",
|
||||
Comments: [3]string{"" /* encoder.HeadComment */, "Kernel driver, supports matching by wildcard." /* encoder.LineComment */, "" /* encoder.FootComment */},
|
||||
},
|
||||
{
|
||||
Name: "physical",
|
||||
Type: "bool",
|
||||
Note: "",
|
||||
Description: "Select only physical devices.",
|
||||
Comments: [3]string{"" /* encoder.HeadComment */, "Select only physical devices." /* encoder.LineComment */, "" /* encoder.FootComment */},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,9 @@ func (in *Bond) DeepCopyInto(out *Bond) {
|
||||
if in.BondDeviceSelectors != nil {
|
||||
in, out := &in.BondDeviceSelectors, &out.BondDeviceSelectors
|
||||
*out = make([]NetworkDeviceSelector, len(*in))
|
||||
copy(*out, *in)
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.BondARPIPTarget != nil {
|
||||
in, out := &in.BondARPIPTarget, &out.BondARPIPTarget
|
||||
@ -586,7 +588,7 @@ func (in *Device) DeepCopyInto(out *Device) {
|
||||
if in.DeviceSelector != nil {
|
||||
in, out := &in.DeviceSelector, &out.DeviceSelector
|
||||
*out = new(NetworkDeviceSelector)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DeviceAddresses != nil {
|
||||
in, out := &in.DeviceAddresses, &out.DeviceAddresses
|
||||
@ -1101,7 +1103,7 @@ func (in *IfaceSelector) DeepCopyInto(out *IfaceSelector) {
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(NetworkDeviceSelector)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -1856,6 +1858,11 @@ func (in NetworkDeviceList) DeepCopy() NetworkDeviceList {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NetworkDeviceSelector) DeepCopyInto(out *NetworkDeviceSelector) {
|
||||
*out = *in
|
||||
if in.NetworkDevicePhysical != nil {
|
||||
in, out := &in.NetworkDevicePhysical, &out.NetworkDevicePhysical
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1175,6 +1175,7 @@ machine:
|
||||
|`hardwareAddr` |string |Device hardware address, supports matching by wildcard. | |
|
||||
|`pciID` |string |PCI ID (vendor ID, product ID), supports matching by wildcard. | |
|
||||
|`driver` |string |Kernel driver, supports matching by wildcard. | |
|
||||
|`physical` |bool |Select only physical devices. | |
|
||||
|
||||
|
||||
|
||||
@ -1322,6 +1323,7 @@ machine:
|
||||
|`hardwareAddr` |string |Device hardware address, supports matching by wildcard. | |
|
||||
|`pciID` |string |PCI ID (vendor ID, product ID), supports matching by wildcard. | |
|
||||
|`driver` |string |Kernel driver, supports matching by wildcard. | |
|
||||
|`physical` |bool |Select only physical devices. | |
|
||||
|
||||
|
||||
|
||||
|
@ -39,6 +39,16 @@ spec:
|
||||
pciID: 1969:E0B1
|
||||
```
|
||||
|
||||
The following qualifiers are available:
|
||||
|
||||
- `driver` - matches a device by its driver name
|
||||
- `hardwareAddr` - matches a device by its hardware address
|
||||
- `busPath` - matches a device by its PCI bus path
|
||||
- `pciID` - matches a device by its PCI vendor and device ID
|
||||
- `physical` - matches only physical devices (vs. virtual devices, e.g. bonds and VLANs)
|
||||
|
||||
All qualifiers except for `physical` support wildcard matching using `*` character.
|
||||
|
||||
## Using Device Selector for Bonding
|
||||
|
||||
Device selectors can be used to configure bonded interfaces:
|
||||
|
@ -95,7 +95,7 @@ machine:
|
||||
network:
|
||||
interfaces:
|
||||
- deviceSelector:
|
||||
busPath: "0*" # should select any hardware network device, if you have just one, it will be selected
|
||||
physical: true # should select any hardware network device, if you have just one, it will be selected
|
||||
dhcp: true
|
||||
vip:
|
||||
ip: 192.168.0.15
|
||||
|
Loading…
x
Reference in New Issue
Block a user