From 1819c9902e8879a4591e191978e0f5b79a9e3424 Mon Sep 17 00:00:00 2001 From: Anand Nekkunti Date: Tue, 8 Jul 2025 12:41:14 +0000 Subject: [PATCH] Add corresponding s390x architecture support in HCO for KubeVirt PR #15017 This commit introduces s390x-specific architecture configuration support in HCO, aligning with the upstream KubeVirt change proposed in https://github.com/kubevirt/kubevirt/pull/15017. Key updates: - Adds support for S390X_MACHINETYPE environment variable - Sets default values for s390x OVMFPath and EmulatedMachines - Updates unit tests to verify s390x-specific configuration - Temporarily patches vendor/kubevirt.io/api with 's390x' field in ArchConfiguration TODO: The vendor patch will be removed once the s390x support is officially released in KubeVirt and the go.mod reference is updated. Signed-off-by: Anand Nekkunti --- controllers/operands/kubevirt.go | 15 +++++++++++++++ controllers/operands/kubevirt_test.go | 14 ++++++++++++++ go.mod | 2 +- .../kubevirt.io/api/core/v1/deepcopy_generated.go | 6 ++++++ vendor/kubevirt.io/api/core/v1/types.go | 1 + 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/controllers/operands/kubevirt.go b/controllers/operands/kubevirt.go index b390ce3e32..693792c4ba 100644 --- a/controllers/operands/kubevirt.go +++ b/controllers/operands/kubevirt.go @@ -40,13 +40,16 @@ const ( machineTypeEnvName = "MACHINETYPE" amd64MachineTypeEnvName = "AMD64_MACHINETYPE" arm64MachineTypeEnvName = "ARM64_MACHINETYPE" + s390xMachineTypeEnvName = "S390X_MACHINETYPE" ) const ( DefaultAMD64OVMFPath = "/usr/share/OVMF" DefaultARM64OVMFPath = "/usr/share/AAVMF" + DefaultS390xOVMFPath = "" DefaultAMD64EmulatedMachines = "q35*,pc-q35*" DefaultARM64EmulatedMachines = "virt*" + DefaultS390XEmulatedMachines = "s390-ccw-virtio*" ) const primaryUDNNetworkBindingName = "l2bridge" @@ -488,6 +491,18 @@ func getKVConfig(hc *hcov1beta1.HyperConverged) (*kubevirtcorev1.KubeVirtConfigu } } } + if s390xMachineType, ok := os.LookupEnv(s390xMachineTypeEnvName); ok { + if s390xMachineType = strings.TrimSpace(s390xMachineType); s390xMachineType != "" { + if config.ArchitectureConfiguration == nil { + config.ArchitectureConfiguration = &kubevirtcorev1.ArchConfiguration{} + } + config.ArchitectureConfiguration.S390x = &kubevirtcorev1.ArchSpecificConfiguration{ + MachineType: s390xMachineType, + OVMFPath: DefaultS390xOVMFPath, + EmulatedMachines: strings.Split(DefaultS390XEmulatedMachines, ","), + } + } + } if hc.Spec.DefaultCPUModel != nil { config.CPUModel = *hc.Spec.DefaultCPUModel diff --git a/controllers/operands/kubevirt_test.go b/controllers/operands/kubevirt_test.go index 6f47543518..990fd08e7a 100644 --- a/controllers/operands/kubevirt_test.go +++ b/controllers/operands/kubevirt_test.go @@ -261,6 +261,7 @@ Version: 1.2.3`)).To(Succeed()) Expect(os.Setenv(amd64MachineTypeEnvName, "q35")).To(Succeed()) Expect(os.Setenv(arm64MachineTypeEnvName, "virt")).To(Succeed()) + Expect(os.Setenv(s390xMachineTypeEnvName, "s390-ccw-virtio")).To(Succeed()) Expect(os.Setenv(kvmEmulationEnvName, "false")).To(Succeed()) DeferCleanup(func() { @@ -268,6 +269,7 @@ Version: 1.2.3`)).To(Succeed()) Expect(os.Unsetenv(machineTypeEnvName)).To(Succeed()) Expect(os.Unsetenv(amd64MachineTypeEnvName)).To(Succeed()) Expect(os.Unsetenv(arm64MachineTypeEnvName)).To(Succeed()) + Expect(os.Unsetenv(s390xMachineTypeEnvName)).To(Succeed()) Expect(os.Unsetenv(kvmEmulationEnvName)).To(Succeed()) }) }) @@ -320,6 +322,8 @@ Version: 1.2.3`)).To(Succeed()) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Amd64.OVMFPath).To(Equal(DefaultAMD64OVMFPath)) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Arm64.MachineType).To(Equal("virt")) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Arm64.OVMFPath).To(Equal(DefaultARM64OVMFPath)) + Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.S390x.MachineType).To(Equal("s390-ccw-virtio")) + Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.S390x.OVMFPath).To(Equal(DefaultS390xOVMFPath)) Expect(foundResource.Spec.Configuration.SMBIOSConfig).ToNot(BeNil()) Expect(foundResource.Spec.Configuration.SMBIOSConfig.Family).To(Equal("smbios family")) @@ -458,6 +462,7 @@ Sku: 1.2.3 Version: 1.2.3`) os.Setenv(amd64MachineTypeEnvName, "q35") os.Setenv(arm64MachineTypeEnvName, "virt") + os.Setenv(s390xMachineTypeEnvName, "s390-ccw-virtio") existKv, err := NewKubeVirt(hco, commontestutils.Namespace) Expect(err).ToNot(HaveOccurred()) @@ -471,6 +476,9 @@ Version: 1.2.3`) Arm64: &kubevirtcorev1.ArchSpecificConfiguration{ MachineType: "wrong arm64 machine type", }, + S390x: &kubevirtcorev1.ArchSpecificConfiguration{ + MachineType: "wrong s390x machine type", + }, } existKv.Spec.Configuration.SMBIOSConfig = &kubevirtcorev1.SMBiosConfiguration{ Family: "wrong family", @@ -528,6 +536,8 @@ Version: 1.2.3`) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Amd64.OVMFPath).To(Equal(DefaultAMD64OVMFPath)) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Arm64.MachineType).To(Equal("virt")) Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.Arm64.OVMFPath).To(Equal(DefaultARM64OVMFPath)) + Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.S390x.MachineType).To(Equal("s390-ccw-virtio")) + Expect(foundResource.Spec.Configuration.ArchitectureConfiguration.S390x.OVMFPath).To(Equal(DefaultS390xOVMFPath)) Expect(foundResource.Spec.Configuration.SMBIOSConfig).ToNot(BeNil()) Expect(foundResource.Spec.Configuration.SMBIOSConfig.Family).To(Equal("smbios family")) @@ -558,6 +568,7 @@ Version: 1.2.3`) os.Setenv(machineTypeEnvName, "legacy") os.Setenv(amd64MachineTypeEnvName, "q35") os.Unsetenv(arm64MachineTypeEnvName) + os.Unsetenv(s390xMachineTypeEnvName) kv, err := NewKubeVirt(hco, commontestutils.Namespace) Expect(err).ToNot(HaveOccurred()) @@ -566,12 +577,14 @@ Version: 1.2.3`) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Amd64.MachineType).To(Equal("legacy")) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Amd64.OVMFPath).To(Equal(DefaultAMD64OVMFPath)) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Arm64).To(BeNil()) + Expect(kv.Spec.Configuration.ArchitectureConfiguration.S390x).To(BeNil()) }) It("should not use legacy MACHINETYPE env if empty", func() { os.Setenv(machineTypeEnvName, "") os.Setenv(amd64MachineTypeEnvName, "q35") os.Unsetenv(arm64MachineTypeEnvName) + os.Unsetenv(s390xMachineTypeEnvName) kv, err := NewKubeVirt(hco, commontestutils.Namespace) Expect(err).ToNot(HaveOccurred()) @@ -580,6 +593,7 @@ Version: 1.2.3`) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Amd64.MachineType).To(Equal("q35")) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Amd64.OVMFPath).To(Equal(DefaultAMD64OVMFPath)) Expect(kv.Spec.Configuration.ArchitectureConfiguration.Arm64).To(BeNil()) + Expect(kv.Spec.Configuration.ArchitectureConfiguration.S390x).To(BeNil()) }) It("should fail if the SMBIOS is wrongly formatted mandatory configurations", func() { diff --git a/go.mod b/go.mod index 60e9206bce..404b170958 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( k8s.io/component-helpers v0.33.2 k8s.io/kube-openapi v0.33.2 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 - kubevirt.io/api v1.5.0 + kubevirt.io/api v1.5.0 // TODO: Update version when kube-vert released with s390x Arch chnages . kubevirt.io/application-aware-quota v1.4.0 kubevirt.io/containerized-data-importer-api v1.62.0 kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4 diff --git a/vendor/kubevirt.io/api/core/v1/deepcopy_generated.go b/vendor/kubevirt.io/api/core/v1/deepcopy_generated.go index b32e9f44bd..82aa230c20 100644 --- a/vendor/kubevirt.io/api/core/v1/deepcopy_generated.go +++ b/vendor/kubevirt.io/api/core/v1/deepcopy_generated.go @@ -135,6 +135,12 @@ func (in *ArchConfiguration) DeepCopyInto(out *ArchConfiguration) { *out = new(ArchSpecificConfiguration) (*in).DeepCopyInto(*out) } + // TODO: Remove this after https://github.com/kubevirt/kubevirt/tree/v1.5.0/staging/src/kubevirt.io/api release (1.6 release) includes deepcopy for S390x , + if in.S390x != nil { + in, out := &in.S390x, &out.S390x + *out = new(ArchSpecificConfiguration) + (*in).DeepCopyInto(*out) + } return } diff --git a/vendor/kubevirt.io/api/core/v1/types.go b/vendor/kubevirt.io/api/core/v1/types.go index 5f465db43e..3d8d78b54c 100644 --- a/vendor/kubevirt.io/api/core/v1/types.go +++ b/vendor/kubevirt.io/api/core/v1/types.go @@ -2628,6 +2628,7 @@ type ArchConfiguration struct { Amd64 *ArchSpecificConfiguration `json:"amd64,omitempty"` Arm64 *ArchSpecificConfiguration `json:"arm64,omitempty"` Ppc64le *ArchSpecificConfiguration `json:"ppc64le,omitempty"` + S390x *ArchSpecificConfiguration `json:"s390x,omitempty"` //TODO: done this for testing, Remove this once kubevirt got releases and updated ver in go mod DefaultArchitecture string `json:"defaultArchitecture,omitempty"` }