fix: make upgrade work with SELinux enforcing=1

Add a test for this case

Signed-off-by: Dmitrii Sharshakov <dmitry.sharshakov@siderolabs.com>

Co-authored-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
(cherry picked from commit 3dfa4d6e40dcae2db47e89443568be3ae48b3ae1)
This commit is contained in:
Dmitrii Sharshakov 2025-12-17 13:10:13 +01:00 committed by Mateusz Urbanek
parent ac91ade2c7
commit a3e90e445f
No known key found for this signature in database
GPG Key ID: F16F84591E26D77F
6 changed files with 94 additions and 2 deletions

View File

@ -23,6 +23,7 @@ import (
"github.com/siderolabs/go-blockdevice/v2/encryption"
"github.com/siderolabs/go-kubernetes/kubernetes/upgrade"
"github.com/siderolabs/go-pointer"
"github.com/siderolabs/go-procfs/procfs"
"github.com/siderolabs/go-retry/retry"
sideronet "github.com/siderolabs/net"
"github.com/stretchr/testify/suite"
@ -440,6 +441,8 @@ type clusterOptions struct {
ControlplaneNodes int
WorkerNodes int
InjectExtraKernelArgs *procfs.Cmdline
SourceKernelPath string
SourceInitramfsPath string
SourceDiskImagePath string
@ -648,7 +651,8 @@ func (suite *BaseSuite) setupCluster(options clusterOptions) {
Size: DefaultSettings.DiskGB * 1024 * 1024 * 1024,
},
},
Config: suite.configBundle.ControlPlane(),
Config: suite.configBundle.ControlPlane(),
SDStubKernelArgs: options.InjectExtraKernelArgs,
},
)
}
@ -667,7 +671,8 @@ func (suite *BaseSuite) setupCluster(options clusterOptions) {
Size: DefaultSettings.DiskGB * 1024 * 1024 * 1024,
},
},
Config: suite.configBundle.Worker(),
Config: suite.configBundle.Worker(),
SDStubKernelArgs: options.InjectExtraKernelArgs,
},
)
}

View File

@ -10,16 +10,24 @@ import (
"fmt"
"path/filepath"
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
"github.com/siderolabs/go-procfs/procfs"
"github.com/stretchr/testify/assert"
"github.com/siderolabs/talos/cmd/talosctl/pkg/mgmt/helpers"
"github.com/siderolabs/talos/pkg/images"
talosclient "github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
)
//nolint:maligned
type upgradeSpec struct {
ShortName string
InjectExtraKernelArgs *procfs.Cmdline
SourceKernelPath string
SourceInitramfsPath string
SourceDiskImagePath string
@ -42,6 +50,7 @@ type upgradeSpec struct {
WithEncryption bool
WithBios bool
WithApplyConfig bool
WithEnforcing bool
}
const (
@ -226,6 +235,38 @@ func upgradeCurrentToCurrentNewCmdline() upgradeSpec {
}
}
func upgradeCurrentToCurrentEnforcing() upgradeSpec {
installerImage := fmt.Sprintf(
"%s/%s:%s",
DefaultSettings.TargetInstallImageRegistry,
images.DefaultInstallerImageName,
DefaultSettings.CurrentVersion,
)
return upgradeSpec{
ShortName: fmt.Sprintf("%s-same-ver-enforcing", DefaultSettings.CurrentVersion),
InjectExtraKernelArgs: procfs.NewCmdline("enforcing=1"),
SourceISOPath: helpers.ArtifactPath("metal-amd64.iso"),
SourceInstallerImage: installerImage,
SourceVersion: DefaultSettings.CurrentVersion,
SourceK8sVersion: currentK8sVersion,
TargetInstallerImage: installerImage,
TargetVersion: DefaultSettings.CurrentVersion,
TargetK8sVersion: currentK8sVersion,
ControlplaneNodes: 1,
WorkerNodes: 0,
TargetCmdlineContains: "enforcing=1",
WithApplyConfig: true,
WithEnforcing: true,
}
}
// UpgradeSuite ...
type UpgradeSuite struct {
BaseSuite
@ -264,6 +305,8 @@ func (suite *UpgradeSuite) TestRolling() {
ControlplaneNodes: suite.spec.ControlplaneNodes,
WorkerNodes: suite.spec.WorkerNodes,
InjectExtraKernelArgs: suite.spec.InjectExtraKernelArgs,
SourceKernelPath: suite.spec.SourceKernelPath,
SourceInitramfsPath: suite.spec.SourceInitramfsPath,
SourceDiskImagePath: suite.spec.SourceDiskImagePath,
@ -283,6 +326,18 @@ func (suite *UpgradeSuite) TestRolling() {
// verify initial cluster version
suite.assertSameVersionCluster(client, suite.spec.SourceVersion)
// verify enforcing state
for _, node := range suite.Cluster.Info().Nodes {
rtestutils.AssertResource(
talosclient.WithNode(suite.ctx, node.IPs[0].String()),
suite.T(), client.COSI,
runtime.SecurityStateID,
func(r *runtime.SecurityState, asrt *assert.Assertions) {
asrt.Equal(suite.spec.WithEnforcing, r.TypedSpec().SELinuxState == runtime.SELinuxStateEnforcing)
},
)
}
options := upgradeOptions{
TargetInstallerImage: suite.spec.TargetInstallerImage,
UpgradeStage: suite.spec.UpgradeStage,
@ -306,6 +361,18 @@ func (suite *UpgradeSuite) TestRolling() {
// verify final cluster version
suite.assertSameVersionCluster(client, suite.spec.TargetVersion)
// verify enforcing state
for _, node := range suite.Cluster.Info().Nodes {
rtestutils.AssertResource(
talosclient.WithNode(suite.ctx, node.IPs[0].String()),
suite.T(), client.COSI,
runtime.SecurityStateID,
func(r *runtime.SecurityState, asrt *assert.Assertions) {
asrt.Equal(suite.spec.WithEnforcing, r.TypedSpec().SELinuxState == runtime.SELinuxStateEnforcing)
},
)
}
// upgrade Kubernetes if required
suite.upgradeKubernetes(suite.spec.SourceK8sVersion, suite.spec.TargetK8sVersion, suite.spec.SkipKubeletUpgrade)
@ -337,5 +404,6 @@ func init() {
&UpgradeSuite{specGen: upgradeCurrentToCurrentBios, track: 0},
&UpgradeSuite{specGen: upgradeStableToCurrentPreserveStage, track: 1},
&UpgradeSuite{specGen: upgradeCurrentToCurrentNewCmdline, track: 2},
&UpgradeSuite{specGen: upgradeCurrentToCurrentEnforcing, track: 1},
)
}

View File

@ -16,6 +16,7 @@ import (
"github.com/containerd/errdefs"
"github.com/siderolabs/talos/internal/pkg/containers/image"
"github.com/siderolabs/talos/internal/pkg/selinux"
"github.com/siderolabs/talos/pkg/machinery/constants"
)
@ -67,6 +68,10 @@ func PullAndValidateInstallerImage(ctx context.Context, registryBuilder image.Re
oci.WithProcessArgs(args...),
}
if selinux.IsEnabled() {
specOpts = append(specOpts, oci.WithSelinuxLabel(constants.SelinuxLabelInstaller))
}
containerOpts := []containerd.NewContainerOpts{
containerd.WithImage(img),
containerd.WithNewSnapshot(containerID, img),

View File

@ -43,6 +43,7 @@ type LaunchConfig struct {
ExtraISOPath string
PFlashImages []string
KernelArgs string
SDStubKernelArgs string
MonitorPath string
DefaultBootOrder string
BootloaderEnabled bool
@ -458,6 +459,10 @@ func patchKernelArgs(config *LaunchConfig, httpServerAddr net.Addr) error {
config.sdStubExtraCmdline = "console=ttyS0"
if config.SDStubKernelArgs != "" {
config.sdStubExtraCmdline += " " + config.SDStubKernelArgs
}
if strings.Contains(config.KernelArgs, "{TALOS_CONFIG_URL}") {
config.KernelArgs = strings.ReplaceAll(config.KernelArgs, "{TALOS_CONFIG_URL}", fmt.Sprintf("http://%s/config.yaml", configServerAddr))
config.sdStubExtraCmdlineConfig = fmt.Sprintf(" talos.config=http://%s/config.yaml", httpServerAddr)

View File

@ -221,6 +221,10 @@ func (p *provisioner) createNode(ctx context.Context, state *provision.State, cl
launchConfig.Network.Hostname = nodeReq.Name
}
if nodeReq.SDStubKernelArgs != nil {
launchConfig.SDStubKernelArgs = nodeReq.SDStubKernelArgs.String()
}
if !nodeReq.PXEBooted && launchConfig.IPXEBootFileName == "" {
launchConfig.KernelImagePath = strings.ReplaceAll(clusterReq.KernelPath, constants.ArchVariable, opts.TargetArch)
launchConfig.InitrdPath = strings.ReplaceAll(clusterReq.InitramfsPath, constants.ArchVariable, opts.TargetArch)

View File

@ -218,6 +218,11 @@ type NodeRequest struct {
// This doesn't apply to boots from ISO or from the disk image.
ExtraKernelArgs *procfs.Cmdline
// SDStubKernelArgs passes additional kernel args via the systemd-stub.
//
// This applies to boots from ISO and from the disk image.
SDStubKernelArgs *procfs.Cmdline
// UUID allows to specify the UUID of the node (VMs only).
//
// If not specified, a random UUID will be generated.