mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-08 07:37:06 +02:00
See https://github.com/siderolabs/ethtool - our fork. This PR covers only configuring rings, follow-up PRs will address other pieces: channels and features. Example: ``` node: 172.20.0.5 metadata: namespace: network type: EthernetStatuses.net.talos.dev id: enp0s2 version: 4 owner: network.EthernetStatusController phase: running created: 2025-02-04T16:03:14Z updated: 2025-02-04T16:04:12Z spec: linkState: true port: Other duplex: Unknown rings: rx-max: 256 tx-max: 256 rx: 128 tx: 128 tx-push: false rx-push: false ``` Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
133 lines
3.9 KiB
Go
133 lines
3.9 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
//go:build integration_api
|
|
|
|
package api
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/cosi-project/runtime/pkg/resource"
|
|
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
|
|
"github.com/cosi-project/runtime/pkg/safe"
|
|
"github.com/siderolabs/go-pointer"
|
|
"github.com/stretchr/testify/assert"
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"github.com/siderolabs/talos/internal/integration/base"
|
|
"github.com/siderolabs/talos/pkg/machinery/client"
|
|
networkconfig "github.com/siderolabs/talos/pkg/machinery/config/types/network"
|
|
"github.com/siderolabs/talos/pkg/machinery/resources/network"
|
|
)
|
|
|
|
// EthernetSuite ...
|
|
type EthernetSuite struct {
|
|
base.APISuite
|
|
|
|
ctx context.Context //nolint:containedctx
|
|
ctxCancel context.CancelFunc
|
|
}
|
|
|
|
// SuiteName ...
|
|
func (suite *EthernetSuite) SuiteName() string {
|
|
return "api.EthernetSuite"
|
|
}
|
|
|
|
// SetupTest ...
|
|
func (suite *EthernetSuite) SetupTest() {
|
|
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 1*time.Minute)
|
|
|
|
if suite.Cluster == nil || suite.Cluster.Provisioner() != base.ProvisionerQEMU {
|
|
suite.T().Skip("skipping ethernet test since provisioner is not qemu")
|
|
}
|
|
}
|
|
|
|
// TearDownTest ...
|
|
func (suite *EthernetSuite) TearDownTest() {
|
|
if suite.ctxCancel != nil {
|
|
suite.ctxCancel()
|
|
}
|
|
}
|
|
|
|
// TestEthernetConfig verifies changing Ethernet settings.
|
|
func (suite *EthernetSuite) TestEthernetConfig() {
|
|
// pick up a random node to test the Ethernet on, and use it throughout the test
|
|
node := suite.RandomDiscoveredNodeInternalIP()
|
|
|
|
suite.T().Logf("testing Ethernet on node %s", node)
|
|
|
|
// build a Talos API context which is tied to the node
|
|
nodeCtx := client.WithNode(suite.ctx, node)
|
|
|
|
// pick a Ethernet links
|
|
ethStatuses, err := safe.StateListAll[*network.EthernetStatus](nodeCtx, suite.Client.COSI)
|
|
suite.Require().NoError(err)
|
|
|
|
var (
|
|
linkName string
|
|
prevRingConfig *network.EthernetRingsStatus
|
|
)
|
|
|
|
for ethStatus := range ethStatuses.All() {
|
|
if ethStatus.TypedSpec().Rings != nil && ethStatus.TypedSpec().Rings.RXMax != nil {
|
|
linkName = ethStatus.Metadata().ID()
|
|
prevRingConfig = ethStatus.TypedSpec().Rings
|
|
|
|
marshaled, err := resource.MarshalYAML(ethStatus)
|
|
suite.Require().NoError(err)
|
|
|
|
out, err := yaml.Marshal(marshaled)
|
|
suite.Require().NoError(err)
|
|
|
|
suite.T().Logf("found link %s with: %s", linkName, string(out))
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
suite.Require().NotEmpty(linkName, "no link provides RX rings")
|
|
|
|
if os.Getenv("CI") != "" {
|
|
suite.T().Skip("skipping ethtool test in CI, as QEMU version doesn't support updating RX rings for virtio")
|
|
}
|
|
|
|
// first, adjust RX rings to be 50% of what it was before
|
|
newRX := pointer.SafeDeref(prevRingConfig.RXMax) / 2
|
|
|
|
cfgDocument := networkconfig.NewEthernetConfigV1Alpha1(linkName)
|
|
cfgDocument.RingsConfig = &networkconfig.EthernetRingsConfig{
|
|
RX: pointer.To(newRX),
|
|
}
|
|
suite.PatchMachineConfig(nodeCtx, cfgDocument)
|
|
|
|
// now EthernetStatus should reflect the new RX rings
|
|
rtestutils.AssertResource(nodeCtx, suite.T(), suite.Client.COSI, linkName,
|
|
func(ethStatus *network.EthernetStatus, asrt *assert.Assertions) {
|
|
asrt.Equal(newRX, pointer.SafeDeref(ethStatus.TypedSpec().Rings.RX))
|
|
},
|
|
)
|
|
|
|
// now, let's revert the RX rings to what it was before
|
|
cfgDocument.RingsConfig.RX = prevRingConfig.RX
|
|
|
|
suite.PatchMachineConfig(nodeCtx, cfgDocument)
|
|
|
|
// now EthernetStatus should reflect the new RX rings
|
|
rtestutils.AssertResource(nodeCtx, suite.T(), suite.Client.COSI, linkName,
|
|
func(ethStatus *network.EthernetStatus, asrt *assert.Assertions) {
|
|
asrt.Equal(pointer.SafeDeref(prevRingConfig.RX), pointer.SafeDeref(ethStatus.TypedSpec().Rings.RX))
|
|
},
|
|
)
|
|
|
|
// remove the config document
|
|
suite.RemoveMachineConfigDocuments(nodeCtx, cfgDocument.MetaKind)
|
|
}
|
|
|
|
func init() {
|
|
allSuites = append(allSuites, new(EthernetSuite))
|
|
}
|