diff --git a/data/data/rhcos-amd64.json b/data/data/rhcos-amd64.json new file mode 100644 index 00000000000..f6bc31e91c2 --- /dev/null +++ b/data/data/rhcos-amd64.json @@ -0,0 +1,135 @@ +{ + "amis": { + "ap-northeast-1": { + "hvm": "ami-02bb6c599c86663bd" + }, + "ap-northeast-2": { + "hvm": "ami-03dd9e368f20dbc76" + }, + "ap-south-1": { + "hvm": "ami-0192efd438962e43a" + }, + "ap-southeast-1": { + "hvm": "ami-0fc688622e368c765" + }, + "ap-southeast-2": { + "hvm": "ami-083ae473d8d6b7771" + }, + "ca-central-1": { + "hvm": "ami-0e3eba4d065f52d54" + }, + "eu-central-1": { + "hvm": "ami-03c14a5bb0eadf4e3" + }, + "eu-north-1": { + "hvm": "ami-027eb49da627f8899" + }, + "eu-west-1": { + "hvm": "ami-0fda05c1fd2f78f3d" + }, + "eu-west-2": { + "hvm": "ami-0fd3f4561265de484" + }, + "eu-west-3": { + "hvm": "ami-05ee3993a0d19102e" + }, + "me-south-1": { + "hvm": "ami-013932b8aad1e340f" + }, + "sa-east-1": { + "hvm": "ami-000abe9467b83a7db" + }, + "us-east-1": { + "hvm": "ami-07b760584db62cbb2" + }, + "us-east-2": { + "hvm": "ami-005141ec3f197b7be" + }, + "us-west-1": { + "hvm": "ami-05bd75163809cc646" + }, + "us-west-2": { + "hvm": "ami-0a2ce8ff0118b47a7" + } + }, + "azure": { + "image": "rhcos-44.81.202001030903.0-azure.x86_64.vhd", + "url": "https://rhcos.blob.core.windows.net/imagebucket/rhcos-44.81.202001030903.0-azure.x86_64.vhd" + }, + "baseURI": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.4/44.81.202001030903.0/x86_64/", + "buildid": "44.81.202001030903.0", + "gcp": { + "image": "rhcos-44-81-202001030903-0", + "url": "https://storage.googleapis.com/rhcos/rhcos/44.81.202001030903.0.tar.gz" + }, + "images": { + "aws": { + "path": "rhcos-44.81.202001030903.0-aws.x86_64.vmdk.gz", + "sha256": "8990547b4054331c97dc60a6049be028a77e1a4e2863b3bfa6e6c07247a7d536", + "size": 880505842, + "uncompressed-sha256": "b92479b7e7c463d9f6691f3c48142e7d6bb10618b744247610437ce2ca59447c", + "uncompressed-size": 898413056 + }, + "azure": { + "path": "rhcos-44.81.202001030903.0-azure.x86_64.vhd.gz", + "sha256": "91db5303c622d6abea7e53285919d734756c0b48352f0ee115467b472d138297", + "size": 864719805, + "uncompressed-sha256": "b2010101bae959dc2b1804b5c94a6241a1ee90f9e3dd57bf19091b5044cf0b57", + "uncompressed-size": 2445911552 + }, + "gcp": { + "path": "rhcos-44.81.202001030903.0-gcp.x86_64.tar.gz", + "sha256": "8d98df8e41fdcc85522d73cb12222efdb6f6b0caa1819840e41a83f141c08946", + "size": 864325555 + }, + "initramfs": { + "path": "rhcos-44.81.202001030903.0-installer-initramfs.x86_64.img", + "sha256": "e2f04edf65f8c261d54e3dab8851936520fe50dcf776ceed346d8a8d2cf1e9c8" + }, + "iso": { + "path": "rhcos-44.81.202001030903.0-installer.x86_64.iso", + "sha256": "070b394db3fa7d7806c6e5fcb22f84224863ac029acf455a458815aebbb70da6" + }, + "kernel": { + "path": "rhcos-44.81.202001030903.0-installer-kernel-x86_64", + "sha256": "7ace7ebdb828e1dc4d242b2fb8a360e7b97da7748d2fde4ffa3bd30232c04865" + }, + "metal": { + "path": "rhcos-44.81.202001030903.0-metal.x86_64.raw.gz", + "sha256": "b691bb5bb57f7eb4bab045c1c8704d2d8f331b6b4ef409bed6e60809e031900b", + "size": 865812126, + "uncompressed-sha256": "6d17bbda7ae37487d94949c3d3bbf211963965d1dd172fa44e4a87b46091060e", + "uncompressed-size": 3711959040 + }, + "openstack": { + "path": "rhcos-44.81.202001030903.0-openstack.x86_64.qcow2.gz", + "sha256": "7e24f818051923d910bb0fe40f0a29430a27b94ab55a4de5313a5890784b50bd", + "size": 866385074, + "uncompressed-sha256": "f596e42ace6b426cddc83e3314aa7daf6e4aa1f106688760d2e9bf4cc6910674", + "uncompressed-size": 2396192768 + }, + "ostree": { + "path": "rhcos-44.81.202001030903.0-ostree.x86_64.tar", + "sha256": "f5e4c94577df4293f1d3ed09d6bf3518093329dd746882986a5e78ba8d305e51", + "size": 785018880 + }, + "qemu": { + "path": "rhcos-44.81.202001030903.0-qemu.x86_64.qcow2.gz", + "sha256": "8c5754bbfa5eb4bc7a8034f3d4ff16e08844bdc8d07c24bea7c3cf6cda523c61", + "size": 866375740, + "uncompressed-sha256": "a7931dc062f4dcd1f614e487bac8c53699d54c78c84caa7b528a52f6788b5504", + "uncompressed-size": 2396127232 + }, + "vmware": { + "path": "rhcos-44.81.202001030903.0-vmware.x86_64.ova", + "sha256": "fd152e94eb510a85d64f29702397ef280acc0e8dcb8e67d1a28f5564ce8da01a", + "size": 898426880 + } + }, + "oscontainer": { + "digest": "sha256:1f4f5f75678e11f603daa821d0f2d562a0b50ad8e22cbc14500ac45572bca592", + "image": "quay.io/openshift-release-dev/ocp-v4.0-art-dev" + }, + "ostree-commit": "5e9e3468f5191d08c594311ef309b6f344c52ac1144fc4aec5af64a0d0eed084", + "ostree-version": "44.81.202001030903.0" +} \ No newline at end of file diff --git a/docs/user/customization.md b/docs/user/customization.md index d655684b902..2a9ca6e2ea4 100644 --- a/docs/user/customization.md +++ b/docs/user/customization.md @@ -69,6 +69,8 @@ For example, 10.0.0.0/16 represents IP addresses 10.0.0.0 through 10.0.255.255. The following machine-pool properties are available: +* `architecture` (optional string): Determines the instruction set architecture of the machines in the pool. Currently, heteregeneous clusters are not supported, so all pools must specify the same architecture. + Valid values are `amd64` (the default). * `hyperthreading` (optional string): Determines the mode of hyperthreading that machines in the pool will utilize. Valid values are `Enabled` (the default) and `Disabled`. * `name` (required string): The name of the machine pool. diff --git a/hack/update-rhcos-bootimage.py b/hack/update-rhcos-bootimage.py index 97e84c1845d..56da03a33b7 100755 --- a/hack/update-rhcos-bootimage.py +++ b/hack/update-rhcos-bootimage.py @@ -1,5 +1,5 @@ -#!/usr/bin/python3 -# Usage: ./hack/update-rhcos-bootimage.py https://releases-art-rhcos.svc.ci.openshift.org/storage/releases/ootpa/410.8.20190401.0/meta.json +#!/usr/bin/env python3 +# Usage: ./hack/update-rhcos-bootimage.py https://releases-art-rhcos.svc.ci.openshift.org/storage/releases/ootpa/410.8.20190401.0/meta.json amd64 import codecs,os,sys,json,argparse import urllib.parse import urllib.request @@ -8,12 +8,13 @@ # builds. Do not try to e.g. point to RHT-internal endpoints. RHCOS_RELEASES_APP = 'https://releases-art-rhcos.svc.ci.openshift.org' -dn = os.path.abspath(os.path.dirname(sys.argv[0])) - parser = argparse.ArgumentParser() parser.add_argument("meta", action='store') +parser.add_argument("arch", action='store', choices=['amd64']) args = parser.parse_args() +metadata_dir = os.path.join(os.path.dirname(sys.argv[0]), "../data/data") + if not args.meta.startswith(RHCOS_RELEASES_APP): raise SystemExit("URL must start with: " + RHCOS_RELEASES_APP) @@ -32,5 +33,14 @@ for entry in meta['amis'] } newmeta['baseURI'] = urllib.parse.urljoin(args.meta, '.') -with open(os.path.join(dn, "../data/data/rhcos.json"), 'w') as f: + +with open(os.path.join(metadata_dir, f"rhcos-{args.arch}.json"), 'w') as f: json.dump(newmeta, f, sort_keys=True, indent=4) + +# Continue to populate the legacy metadata file because there are still +# processes consuming this file directly. This normally could just be a symlink +# but some of these processes reference raw.githubusercontent.com which doesn't +# follow symlinks. +if args.arch == 'amd64': + with open(os.path.join(metadata_dir, "rhcos.json"), 'w') as f: + json.dump(newmeta, f, sort_keys=True, indent=4) diff --git a/pkg/asset/installconfig/installconfig_test.go b/pkg/asset/installconfig/installconfig_test.go index 5be5ae82dfd..345c9c01ebd 100644 --- a/pkg/asset/installconfig/installconfig_test.go +++ b/pkg/asset/installconfig/installconfig_test.go @@ -81,12 +81,14 @@ func TestInstallConfigGenerate_FillsInDefaults(t *testing.T) { Name: "master", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, Compute: []types.MachinePool{ { Name: "worker", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, }, Platform: types.Platform{ @@ -145,12 +147,14 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" Name: "master", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, Compute: []types.MachinePool{ { Name: "worker", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, }, Platform: types.Platform{ @@ -229,12 +233,14 @@ network: Name: "master", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, Compute: []types.MachinePool{ { Name: "worker", Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, }, }, Platform: types.Platform{ diff --git a/pkg/asset/manifests/operators_test.go b/pkg/asset/manifests/operators_test.go index 25cc50b7635..ba7bc3877cd 100644 --- a/pkg/asset/manifests/operators_test.go +++ b/pkg/asset/manifests/operators_test.go @@ -35,13 +35,15 @@ func TestRedactedInstallConfig(t *testing.T) { ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("1.2.3.4/5")}, }, ControlPlane: &types.MachinePool{ - Name: "control-plane", - Replicas: pointer.Int64Ptr(3), + Name: "control-plane", + Replicas: pointer.Int64Ptr(3), + Architecture: types.ArchitectureAMD64, }, Compute: []types.MachinePool{ { - Name: "compute", - Replicas: pointer.Int64Ptr(3), + Name: "compute", + Replicas: pointer.Int64Ptr(3), + Architecture: types.ArchitectureAMD64, }, }, Platform: types.Platform{ @@ -59,10 +61,12 @@ func TestRedactedInstallConfig(t *testing.T) { expectedConfig := createInstallConfig() expectedYaml := `baseDomain: test-domain compute: -- name: compute +- architecture: amd64 + name: compute platform: {} replicas: 3 controlPlane: + architecture: amd64 name: control-plane platform: {} replicas: 3 diff --git a/pkg/asset/rhcos/bootstrap_image.go b/pkg/asset/rhcos/bootstrap_image.go index f8c5805fad1..6fde584b5ba 100644 --- a/pkg/asset/rhcos/bootstrap_image.go +++ b/pkg/asset/rhcos/bootstrap_image.go @@ -51,7 +51,7 @@ func (i *BootstrapImage) Generate(p asset.Parents) error { // Baremetal IPI launches a local VM for the bootstrap node // Hence requires the QEMU image to use the libvirt backend - osimage, err = rhcos.QEMU(ctx) + osimage, err = rhcos.QEMU(ctx, config.ControlPlane.Architecture) default: // other platforms use the same image for all nodes osimage, err = osImage(config) diff --git a/pkg/asset/rhcos/image.go b/pkg/asset/rhcos/image.go index 7d2b92ba8b1..2e87d1cb1a8 100644 --- a/pkg/asset/rhcos/image.go +++ b/pkg/asset/rhcos/image.go @@ -63,6 +63,8 @@ func (i *Image) Generate(p asset.Parents) error { } func osImage(config *types.InstallConfig) (string, error) { + arch := config.ControlPlane.Architecture + var osimage string var err error ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) @@ -73,15 +75,15 @@ func osImage(config *types.InstallConfig) (string, error) { osimage = config.Platform.AWS.AMIID break } - osimage, err = rhcos.AMI(ctx, config.Platform.AWS.Region) + osimage, err = rhcos.AMI(ctx, arch, config.Platform.AWS.Region) case gcp.Name: - osimage, err = rhcos.GCP(ctx) + osimage, err = rhcos.GCP(ctx, arch) case libvirt.Name: - osimage, err = rhcos.QEMU(ctx) + osimage, err = rhcos.QEMU(ctx, arch) case openstack.Name, ovirt.Name: - osimage, err = rhcos.OpenStack(ctx) + osimage, err = rhcos.OpenStack(ctx, arch) case azure.Name: - osimage, err = rhcos.VHD(ctx) + osimage, err = rhcos.VHD(ctx, arch) case baremetal.Name: // Check for RHCOS image URL override if oi := config.Platform.BareMetal.ClusterOSImage; oi != "" { @@ -92,7 +94,7 @@ func osImage(config *types.InstallConfig) (string, error) { // Note that baremetal IPI currently uses the OpenStack image // because this contains the necessary ironic config drive // ignition support, which isn't enabled in the UPI BM images - osimage, err = rhcos.OpenStack(ctx) + osimage, err = rhcos.OpenStack(ctx, arch) case none.Name, vsphere.Name: default: diff --git a/pkg/rhcos/ami.go b/pkg/rhcos/ami.go index f6d76767b33..625ba9e80ac 100644 --- a/pkg/rhcos/ami.go +++ b/pkg/rhcos/ami.go @@ -4,11 +4,13 @@ import ( "context" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // AMI fetches the HVM AMI ID of the Red Hat Enterprise Linux CoreOS release. -func AMI(ctx context.Context, region string) (string, error) { - meta, err := fetchRHCOSBuild(ctx) +func AMI(ctx context.Context, arch types.Architecture, region string) (string, error) { + meta, err := fetchRHCOSBuild(ctx, arch) if err != nil { return "", errors.Wrap(err, "failed to fetch RHCOS metadata") } diff --git a/pkg/rhcos/azure.go b/pkg/rhcos/azure.go index 63176489d71..14e8fc30bb2 100644 --- a/pkg/rhcos/azure.go +++ b/pkg/rhcos/azure.go @@ -4,11 +4,13 @@ import ( "context" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // VHD fetches the URL of the public Azure storage bucket containing the RHCOS image -func VHD(ctx context.Context) (string, error) { - meta, err := fetchRHCOSBuild(ctx) +func VHD(ctx context.Context, arch types.Architecture) (string, error) { + meta, err := fetchRHCOSBuild(ctx, arch) if err != nil { return "", errors.Wrap(err, "failed to fetch RHCOS metadata") } diff --git a/pkg/rhcos/builds.go b/pkg/rhcos/builds.go index 4bf6b30038b..eaaf2a2558b 100644 --- a/pkg/rhcos/builds.go +++ b/pkg/rhcos/builds.go @@ -3,10 +3,18 @@ package rhcos import ( "context" "encoding/json" + "fmt" "io/ioutil" + "os" "github.com/openshift/installer/data" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" +) + +var ( + errInvalidArch = fmt.Errorf("no build metadata for given architecture") ) type metadata struct { @@ -37,15 +45,17 @@ type metadata struct { OSTreeVersion string `json:"ostree-version"` } -func fetchRHCOSBuild(ctx context.Context) (*metadata, error) { - file, err := data.Assets.Open("rhcos.json") +func fetchRHCOSBuild(ctx context.Context, arch types.Architecture) (*metadata, error) { + file, err := data.Assets.Open(fmt.Sprintf("rhcos-%s.json", arch)) if err != nil { return nil, err } defer file.Close() body, err := ioutil.ReadAll(file) - if err != nil { + if os.IsNotExist(err) { + return nil, errInvalidArch + } else if err != nil { return nil, err } diff --git a/pkg/rhcos/gcp.go b/pkg/rhcos/gcp.go index 782ceba15a2..e1dc4df66cb 100644 --- a/pkg/rhcos/gcp.go +++ b/pkg/rhcos/gcp.go @@ -4,11 +4,13 @@ import ( "context" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // GCP fetches the URL of the public GCP storage bucket containing the RHCOS image -func GCP(ctx context.Context) (string, error) { - meta, err := fetchRHCOSBuild(ctx) +func GCP(ctx context.Context, arch types.Architecture) (string, error) { + meta, err := fetchRHCOSBuild(ctx, arch) if err != nil { return "", errors.Wrap(err, "failed to fetch RHCOS metadata") } diff --git a/pkg/rhcos/openstack.go b/pkg/rhcos/openstack.go index d5485ef40bf..7f25ac7d815 100644 --- a/pkg/rhcos/openstack.go +++ b/pkg/rhcos/openstack.go @@ -5,12 +5,14 @@ import ( "net/url" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // OpenStack fetches the URL of the Red Hat Enterprise Linux CoreOS release, // for the openstack platform -func OpenStack(ctx context.Context) (string, error) { - meta, err := fetchRHCOSBuild(ctx) +func OpenStack(ctx context.Context, arch types.Architecture) (string, error) { + meta, err := fetchRHCOSBuild(ctx, arch) if err != nil { return "", errors.Wrap(err, "failed to fetch RHCOS metadata") } diff --git a/pkg/rhcos/qemu.go b/pkg/rhcos/qemu.go index 5ada808d48c..f0c0026cc80 100644 --- a/pkg/rhcos/qemu.go +++ b/pkg/rhcos/qemu.go @@ -5,11 +5,13 @@ import ( "net/url" "github.com/pkg/errors" + + "github.com/openshift/installer/pkg/types" ) // QEMU fetches the URL of the Red Hat Enterprise Linux CoreOS release. -func QEMU(ctx context.Context) (string, error) { - meta, err := fetchRHCOSBuild(ctx) +func QEMU(ctx context.Context, arch types.Architecture) (string, error) { + meta, err := fetchRHCOSBuild(ctx, arch) if err != nil { return "", errors.Wrap(err, "failed to fetch RHCOS metadata") } diff --git a/pkg/types/defaults/machinepools.go b/pkg/types/defaults/machinepools.go index e9810c2e9c5..9573e7950b9 100644 --- a/pkg/types/defaults/machinepools.go +++ b/pkg/types/defaults/machinepools.go @@ -17,4 +17,7 @@ func SetMachinePoolDefaults(p *types.MachinePool, platform string) { if p.Hyperthreading == "" { p.Hyperthreading = types.HyperthreadingEnabled } + if p.Architecture == "" { + p.Architecture = types.ArchitectureAMD64 + } } diff --git a/pkg/types/defaults/machinepools_test.go b/pkg/types/defaults/machinepools_test.go index 4746ca72df5..9eb1e43fd16 100644 --- a/pkg/types/defaults/machinepools_test.go +++ b/pkg/types/defaults/machinepools_test.go @@ -14,6 +14,7 @@ func defaultMachinePool(name string) *types.MachinePool { Name: name, Replicas: pointer.Int64Ptr(3), Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, } } diff --git a/pkg/types/machinepools.go b/pkg/types/machinepools.go index cd1d721f585..d42c083279a 100644 --- a/pkg/types/machinepools.go +++ b/pkg/types/machinepools.go @@ -21,6 +21,14 @@ const ( HyperthreadingDisabled HyperthreadingMode = "Disabled" ) +// Architecture is the instruction set architecture for the machines in a pool. +type Architecture string + +const ( + // ArchitectureAMD64 indicates AMD64 (x86_64). + ArchitectureAMD64 = "amd64" +) + // MachinePool is a pool of machines to be installed. type MachinePool struct { // Name is the name of the machine pool. @@ -39,6 +47,10 @@ type MachinePool struct { // +optional // Default is for hyperthreading to be enabled. Hyperthreading HyperthreadingMode `json:"hyperthreading,omitempty"` + + // Architecture is the instruction set architecture of the machine pool. + // Defaults to amd64. + Architecture Architecture `json:"architecture,omitempty"` } // MachinePoolPlatform is the platform-specific configuration for a machine diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index fcab7c5a2a1..cbb9399caa9 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -90,7 +90,7 @@ func ValidateInstallConfig(c *types.InstallConfig, openStackValidValuesFetcher o } else { allErrs = append(allErrs, field.Required(field.NewPath("controlPlane"), "controlPlane is required")) } - allErrs = append(allErrs, validateCompute(&c.Platform, c.Compute, field.NewPath("compute"))...) + allErrs = append(allErrs, validateCompute(&c.Platform, c.ControlPlane, c.Compute, field.NewPath("compute"))...) if err := validate.ImagePullSecret(c.PullSecret); err != nil { allErrs = append(allErrs, field.Invalid(field.NewPath("pullSecret"), c.PullSecret, err.Error())) } @@ -310,7 +310,7 @@ func validateControlPlane(platform *types.Platform, pool *types.MachinePool, fld return allErrs } -func validateCompute(platform *types.Platform, pools []types.MachinePool, fldPath *field.Path) field.ErrorList { +func validateCompute(platform *types.Platform, control *types.MachinePool, pools []types.MachinePool, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} poolNames := map[string]bool{} for i, p := range pools { @@ -322,6 +322,9 @@ func validateCompute(platform *types.Platform, pools []types.MachinePool, fldPat allErrs = append(allErrs, field.Duplicate(poolFldPath.Child("name"), p.Name)) } poolNames[p.Name] = true + if control != nil && control.Architecture != p.Architecture { + allErrs = append(allErrs, field.Invalid(poolFldPath.Child("architecture"), p.Architecture, "heteregeneous multi-arch is not supported; compute pool architecture must match control plane")) + } allErrs = append(allErrs, ValidateMachinePool(platform, &p, poolFldPath)...) } return allErrs diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index 3a905fb9da1..8b07541345d 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -904,6 +904,7 @@ func TestValidateInstallConfig(t *testing.T) { return c }(), }, + // TODO(crawford): add a test to validate that homogeneous clusters are enforced once an additional architecture is added } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/types/validation/machinepools.go b/pkg/types/validation/machinepools.go index 33867a09c14..6c9ed452458 100644 --- a/pkg/types/validation/machinepools.go +++ b/pkg/types/validation/machinepools.go @@ -31,6 +31,18 @@ var ( } return v }() + + validArchitectures = map[types.Architecture]bool{ + types.ArchitectureAMD64: true, + } + + validArchitectureValues = func() []string { + v := make([]string, 0, len(validArchitectures)) + for m := range validArchitectures { + v = append(v, string(m)) + } + return v + }() ) // ValidateMachinePool checks that the specified machine pool is valid. @@ -46,6 +58,9 @@ func ValidateMachinePool(platform *types.Platform, p *types.MachinePool, fldPath if !validHyperthreadingModes[p.Hyperthreading] { allErrs = append(allErrs, field.NotSupported(fldPath.Child("hyperthreading"), p.Hyperthreading, validHyperthreadingModeValues)) } + if !validArchitectures[p.Architecture] { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("architecture"), p.Architecture, validArchitectureValues)) + } allErrs = append(allErrs, validateMachinePoolPlatform(platform, &p.Platform, fldPath.Child("platform"))...) return allErrs } diff --git a/pkg/types/validation/machinepools_test.go b/pkg/types/validation/machinepools_test.go index 44517d78c01..0aaf503a875 100644 --- a/pkg/types/validation/machinepools_test.go +++ b/pkg/types/validation/machinepools_test.go @@ -19,6 +19,7 @@ func validMachinePool(name string) *types.MachinePool { Name: name, Replicas: pointer.Int64Ptr(1), Hyperthreading: types.HyperthreadingDisabled, + Architecture: types.ArchitectureAMD64, } }