Skip to content

Commit

Permalink
feat: implement device selector for 'physical'
Browse files Browse the repository at this point in the history
Closes #8090

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
  • Loading branch information
smira committed Jan 23, 2024
1 parent 7d11172 commit d677901
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 8 deletions.
6 changes: 6 additions & 0 deletions hack/release.toml
Expand Up @@ -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]
Expand Down
12 changes: 8 additions & 4 deletions internal/app/machined/pkg/controllers/network/device_config.go
Expand Up @@ -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()},
Expand All @@ -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())
}
}
Expand Down
Expand Up @@ -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"

Expand Down Expand Up @@ -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"},
},
},
},
},
Expand All @@ -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")
Expand All @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions pkg/machinery/config/config/machine.go
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions pkg/machinery/config/types/v1alpha1/v1alpha1_types.go
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions pkg/machinery/config/types/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -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. | |



Expand Down Expand Up @@ -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. | |



Expand Down
10 changes: 10 additions & 0 deletions website/content/v1.7/talos-guides/network/device-selector.md
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion website/content/v1.7/talos-guides/network/vip.md
Expand Up @@ -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
Expand Down

0 comments on commit d677901

Please sign in to comment.