From 075d136259a8d71178e84f67f0bf346bf1b2c42d Mon Sep 17 00:00:00 2001 From: David Joshy Date: Fri, 27 Feb 2026 10:12:28 -0500 Subject: [PATCH] manifests: add Azure/vSphere MCO manifest --- pkg/asset/manifests/mco.go | 37 ++++++++++++++++++ pkg/asset/manifests/mco_test.go | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/pkg/asset/manifests/mco.go b/pkg/asset/manifests/mco.go index 5582f2d5e08..78c284f4462 100644 --- a/pkg/asset/manifests/mco.go +++ b/pkg/asset/manifests/mco.go @@ -8,7 +8,9 @@ import ( "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/aws" + "github.com/openshift/installer/pkg/types/azure" "github.com/openshift/installer/pkg/types/gcp" + "github.com/openshift/installer/pkg/types/vsphere" ) func generateMCOManifest(installConfig *types.InstallConfig, template []*asset.File) []*asset.File { @@ -35,8 +37,12 @@ func customBootImages(ic *types.InstallConfig) (customCPImg, customWImg bool) { switch ic.Platform.Name() { case aws.Name: customCPImg, customWImg = awsBootImages(ic) + case azure.Name: + customCPImg, customWImg = azureBootImages(ic) case gcp.Name: customCPImg, customWImg = gcpBootImages(ic) + case vsphere.Name: + customCPImg, customWImg = vsphereBootImages(ic) default: // We do not need to consider other platforms, because default boot image management has not been enabled yet. return @@ -76,3 +82,34 @@ func gcpBootImages(ic *types.InstallConfig) (cpImg bool, wImg bool) { } return } + +func azureBootImages(ic *types.InstallConfig) (cpImg bool, wImg bool) { + var emptyOSImage azure.OSImage + if dmp := ic.Azure.DefaultMachinePlatform; dmp != nil && dmp.OSImage != emptyOSImage { + return true, true + } + + if cp := ic.ControlPlane; cp != nil && cp.Platform.Azure != nil && cp.Platform.Azure.OSImage != emptyOSImage { + cpImg = true + } + + for _, computeMP := range ic.Compute { + if azurePlatform := computeMP.Platform.Azure; azurePlatform != nil && azurePlatform.OSImage != emptyOSImage { + wImg = true + } + } + return +} + +func vsphereBootImages(ic *types.InstallConfig) (cpImg bool, wImg bool) { + if ic.VSphere.ClusterOSImage != "" { + return true, true + } + + for _, failureDomain := range ic.VSphere.FailureDomains { + if failureDomain.Topology.Template != "" { + return true, true + } + } + return +} diff --git a/pkg/asset/manifests/mco_test.go b/pkg/asset/manifests/mco_test.go index da31cdeca48..3828472fc40 100644 --- a/pkg/asset/manifests/mco_test.go +++ b/pkg/asset/manifests/mco_test.go @@ -12,7 +12,9 @@ import ( "github.com/openshift/installer/pkg/asset" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/aws" + azuretypes "github.com/openshift/installer/pkg/types/azure" "github.com/openshift/installer/pkg/types/gcp" + "github.com/openshift/installer/pkg/types/vsphere" ) func TestGenerateMCO(t *testing.T) { @@ -50,6 +52,31 @@ func TestGenerateMCO(t *testing.T) { installConfig: icBuild.build(icBuild.withGCPComputeAMI()), expectedMCO: mcoBuild.build(mcoBuild.withComputeBootImageMgmtDisabled()), }, + { + name: "vanilla azure produces no mco cfg", + installConfig: icBuild.build(icBuild.forAzure()), + expectedMCO: nil, + }, + { + name: "azure with a custom compute image disables mco management", + installConfig: icBuild.build(icBuild.withAzureComputeOSImage()), + expectedMCO: mcoBuild.build(mcoBuild.withComputeBootImageMgmtDisabled()), + }, + { + name: "vanilla vsphere produces no mco cfg", + installConfig: icBuild.build(icBuild.forVSphere()), + expectedMCO: nil, + }, + { + name: "vsphere with a custom cluster OS image disables mco management", + installConfig: icBuild.build(icBuild.withVSphereClusterOSImage()), + expectedMCO: mcoBuild.build(mcoBuild.withComputeBootImageMgmtDisabled()), + }, + { + name: "vsphere with a failuredomain template disables mco management", + installConfig: icBuild.build(icBuild.withVSphereFailureDomainTemplate()), + expectedMCO: mcoBuild.build(mcoBuild.withComputeBootImageMgmtDisabled()), + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { @@ -169,3 +196,43 @@ func (b icBuildNamespace) withGCPComputeAMI() icOption { } } } + +func (b icBuildNamespace) withAzureComputeOSImage() icOption { + return func(ic *types.InstallConfig) { + b.forAzure()(ic) + ic.Compute = []types.MachinePool{ + { + Platform: types.MachinePoolPlatform{ + Azure: &azuretypes.MachinePool{ + OSImage: azuretypes.OSImage{ + Publisher: "RedHat", + Offer: "rhcos", + SKU: "rhcos", + Version: "latest", + }, + }, + }, + }, + } + } +} + +func (b icBuildNamespace) withVSphereClusterOSImage() icOption { + return func(ic *types.InstallConfig) { + b.forVSphere()(ic) + ic.VSphere.ClusterOSImage = "https://example.com/rhcos.ova" + } +} + +func (b icBuildNamespace) withVSphereFailureDomainTemplate() icOption { + return func(ic *types.InstallConfig) { + b.forVSphere()(ic) + ic.VSphere.FailureDomains = []vsphere.FailureDomain{ + { + Topology: vsphere.Topology{ + Template: "rhcos-template", + }, + }, + } + } +}