mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-08 16:16:12 +02:00
Bump copyright for conformance to 2026 Signed-off-by: Edward Sammut Alessi <edward.sammutalessi@siderolabs.com>
144 lines
5.0 KiB
Go
144 lines
5.0 KiB
Go
// Copyright (c) 2026 Sidero Labs, Inc.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the LICENSE file.
|
|
|
|
//go:build integration
|
|
|
|
package integration_test
|
|
|
|
import (
|
|
"context"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/blang/semver/v4"
|
|
"github.com/cosi-project/runtime/pkg/resource"
|
|
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
|
|
"github.com/cosi-project/runtime/pkg/safe"
|
|
"github.com/cosi-project/runtime/pkg/state"
|
|
xmaps "github.com/siderolabs/gen/maps"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/siderolabs/omni/client/pkg/omni/resources/omni"
|
|
)
|
|
|
|
func testKernelArgsUpdate(t *testing.T, options *TestOptions) {
|
|
ctx, cancel := context.WithTimeout(t.Context(), 15*time.Minute)
|
|
defer cancel()
|
|
|
|
options.claimMachines(t, 2)
|
|
|
|
clusterName := "integration-kernel-args-update"
|
|
|
|
version, err := semver.ParseTolerant(options.MachineOptions.TalosVersion)
|
|
require.NoError(t, err)
|
|
|
|
// Create a cluster to make sure that we have Talos installed on a machine
|
|
t.Run(
|
|
"ClusterShouldBeCreated",
|
|
CreateCluster(t.Context(), options.omniClient, ClusterOptions{
|
|
Name: clusterName,
|
|
ControlPlanes: 1,
|
|
Workers: 1,
|
|
|
|
MachineOptions: options.MachineOptions,
|
|
ScalingTimeout: options.ScalingTimeout,
|
|
|
|
SkipExtensionCheckOnCreate: options.SkipExtensionsCheckOnCreate,
|
|
|
|
// Pick two machines depending on the Talos version:
|
|
// - 1.12 or later; one booted with UKI and another booted with non-UKI, as kernel args upgrades are supported with Talos 1.12 and later.
|
|
// - earlier versions; pick machines booted with UKI, because they are the only ones that support kernel args upgrades.
|
|
PickFilterFunc: func(ms *omni.MachineStatus, alreadyPicked []*omni.MachineStatus) bool {
|
|
canUseUKICmdline := version.Major > 1 || (version.Major == 1 && version.Minor >= 12)
|
|
|
|
// If we can't let grub to use UKI cmdline, we can only pick machines with UKI.
|
|
if !canUseUKICmdline {
|
|
return ms.TypedSpec().Value.GetSecurityState().GetBootedWithUki()
|
|
}
|
|
|
|
alreadyPickedUKI := slices.ContainsFunc(alreadyPicked, func(m *omni.MachineStatus) bool { return m.TypedSpec().Value.GetSecurityState().GetBootedWithUki() })
|
|
alreadyPickedNonUKI := slices.ContainsFunc(alreadyPicked, func(m *omni.MachineStatus) bool { return !m.TypedSpec().Value.GetSecurityState().GetBootedWithUki() })
|
|
|
|
if alreadyPickedUKI && alreadyPickedNonUKI {
|
|
return true
|
|
}
|
|
|
|
isUKI := ms.TypedSpec().Value.GetSecurityState().GetBootedWithUki()
|
|
if isUKI && !alreadyPickedUKI {
|
|
return true
|
|
}
|
|
|
|
return !isUKI && !alreadyPickedNonUKI
|
|
},
|
|
}),
|
|
)
|
|
|
|
assertClusterAndAPIReady(t, clusterName, options)
|
|
|
|
omniState := options.omniClient.Omni().State()
|
|
|
|
kernelArgsMap := make(map[string]*omni.KernelArgs, 2)
|
|
|
|
t.Run("ClusterMachineKernelArgsShouldBeUpdated", func(t *testing.T) {
|
|
clusterMachines, err := safe.StateListAll[*omni.ClusterMachine](ctx, omniState, state.WithLabelQuery(resource.LabelEqual(omni.LabelCluster, clusterName)))
|
|
require.NoError(t, err)
|
|
|
|
for machine := range clusterMachines.All() {
|
|
machineID := machine.Metadata().ID()
|
|
|
|
t.Logf("picked machine ID: %s", machineID)
|
|
|
|
kernelArgs, err := safe.StateModifyWithResult(ctx, omniState, omni.NewKernelArgs(machineID), func(res *omni.KernelArgs) error {
|
|
// make sure that we actually change the args by checking the existing value
|
|
args1 := []string{"foo=bar", "baz=qux"}
|
|
args2 := []string{"baz=qux", "foo=bar"}
|
|
|
|
if slices.Equal(res.TypedSpec().Value.Args, args1) {
|
|
res.TypedSpec().Value.Args = args2
|
|
|
|
return nil
|
|
}
|
|
|
|
res.TypedSpec().Value.Args = args1
|
|
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
kernelArgsMap[machineID] = kernelArgs
|
|
}
|
|
|
|
// verify that the new kernel args appear in the kernel cmdline
|
|
rtestutils.AssertResources(ctx, t, omniState, xmaps.Keys(kernelArgsMap), func(r *omni.MachineStatus, assert *assert.Assertions) {
|
|
assert.Contains(r.TypedSpec().Value.KernelCmdline, strings.Join(kernelArgsMap[r.Metadata().ID()].TypedSpec().Value.Args, " "), resourceDetails(r))
|
|
})
|
|
})
|
|
|
|
t.Run("ClusterShouldBeDestroyed", AssertDestroyCluster(t.Context(), options.omniClient.Omni().State(), clusterName, false, false))
|
|
|
|
updatedKernelArgsMap := make(map[string]*omni.KernelArgs, 2)
|
|
|
|
t.Run("MachineKernelArgsShouldBeUpdatedInMaintenance", func(t *testing.T) {
|
|
for machineID := range kernelArgsMap {
|
|
updatedKernelArgs, err := safe.StateModifyWithResult(ctx, omniState, omni.NewKernelArgs(machineID), func(res *omni.KernelArgs) error {
|
|
res.TypedSpec().Value.Args = []string{"maintenance=true"}
|
|
|
|
return nil
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
updatedKernelArgsMap[machineID] = updatedKernelArgs
|
|
}
|
|
|
|
// verify that the new kernel args appear in the kernel cmdline
|
|
rtestutils.AssertResources(ctx, t, omniState, xmaps.Keys(updatedKernelArgsMap), func(r *omni.MachineStatus, assert *assert.Assertions) {
|
|
assert.Contains(r.TypedSpec().Value.KernelCmdline, strings.Join(updatedKernelArgsMap[r.Metadata().ID()].TypedSpec().Value.Args, " "), resourceDetails(r))
|
|
})
|
|
})
|
|
}
|