Skip to content

CNTRLPLANE-3608: Add nested virtualization support for AWS EC2 NodePools - #8681

Open
jhjaggars wants to merge 11 commits into
openshift:mainfrom
jhjaggars:virt-on-new-aws-nodes
Open

CNTRLPLANE-3608: Add nested virtualization support for AWS EC2 NodePools#8681
jhjaggars wants to merge 11 commits into
openshift:mainfrom
jhjaggars:virt-on-new-aws-nodes

Conversation

@jhjaggars

@jhjaggars jhjaggars commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Adds support for enabling nested virtualization on AWS EC2 instances (C8i, M8i, R8i families) through the NodePool API. This allows running OpenShift Virtualization (KubeVirt) workloads on AWS-hosted clusters.

  • API: Add CpuOptions struct with NestedVirtualization field to AWSNodePoolPlatform
  • Vendor: Bump CAPA from v2.10.0 to v2.11.1 which includes upstream NestedVirtualization support in CPUOptions (PR kubernetes-sigs/cluster-api-provider-aws#5874)
  • CLI: Add --nested-virtualization flag to hypershift create cluster aws and hypershift create nodepool aws
  • Controller: Wire CpuOptions.NestedVirtualization from NodePool spec to CAPA AWSMachineTemplateSpec.CPUOptions
  • CPO fix: Prevent informer creation for unused platform-specific resources (e.g. SecretProviderClass on non-Azure clusters)
  • Built custom HO image and installed on management cluster
  • Created hosted cluster with --nested-virtualization enabled --instance-type c8i.2xlarge
  • Verified cpuOptions.nestedVirtualization: enabled propagates through: NodePool → AWSMachineTemplate → AWSMachine → EC2 instance
  • Confirmed EC2 CpuOptions.NestedVirtualization: enabled via AWS CLI
  • Confirmed vmx CPU flag present on guest nodes via /proc/cpuinfo
    N/A — new feature
  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

    • Added CPU options for AWS node pools with a nested-virtualization toggle (enabled/disabled).
  • Bug Fixes / Behavior

    • Node pool create/update now propagates nested-virtualization into AWS machine specs.
  • Tests

    • Added serialization compatibility and unit tests covering nested-virtualization handling.
  • Chores

    • Updated AWS SDK and AWS cluster-provider dependencies.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jhjaggars: This pull request explicitly references no jira issue.

Details

In response to this:

Adds support for enabling nested virtualization on AWS EC2 instances (C8i, M8i, R8i families) through the NodePool API. This allows running OpenShift Virtualization (KubeVirt) workloads on AWS-hosted clusters.

  • API: Add CpuOptions struct with NestedVirtualization field to AWSNodePoolPlatform
  • Vendor: Bump CAPA from v2.10.0 to v2.11.1 which includes upstream NestedVirtualization support in CPUOptions (PR kubernetes-sigs/cluster-api-provider-aws#5874)
  • CLI: Add --nested-virtualization flag to hypershift create cluster aws and hypershift create nodepool aws
  • Controller: Wire CpuOptions.NestedVirtualization from NodePool spec to CAPA AWSMachineTemplateSpec.CPUOptions
  • CPO fix: Prevent informer creation for unused platform-specific resources (e.g. SecretProviderClass on non-Azure clusters)
  • Built custom HO image and installed on management cluster
  • Created hosted cluster with --nested-virtualization enabled --instance-type c8i.2xlarge
  • Verified cpuOptions.nestedVirtualization: enabled propagates through: NodePool → AWSMachineTemplate → AWSMachine → EC2 instance
  • Confirmed EC2 CpuOptions.NestedVirtualization: enabled via AWS CLI
  • Confirmed vmx CPU flag present on guest nodes via /proc/cpuinfo
    N/A — new feature
  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 5, 2026
@openshift-ci

openshift-ci Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds an optional CpuOptions field to AWSNodePoolPlatform with a NestedVirtualization setting (enabled/disabled). The nodepool controller now maps that value into AWSMachineTemplateSpec.Template.Spec.CPUOptions.NestedVirtualization via applyAWSMachineOptions. Tests were added to verify JSON compatibility and controller behavior. go.mod dependency versions were bumped and a small CLI placeholder hunk appears.

Sequence Diagram(s)

sequenceDiagram
  participant NodePool
  participant NodePoolController
  participant AWSMachineTemplateSpec
  NodePool->>NodePoolController: spec.platform.aws.cpuOptions.nestedVirtualization
  NodePoolController->>AWSMachineTemplateSpec: set template.spec.CPUOptions.NestedVirtualization
Loading
🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning TestApplyAWSMachineOptions has 6 Gomega assertions lacking meaningful failure messages, violating codebase pattern where other tests include descriptions to aid debugging. Add assertion messages to all g.Expect() calls in TestApplyAWSMachineOptions, e.g., g.Expect(spec.Template.Spec.CPUOptions.NestedVirtualization).To(Equal(tc.expectedNestedVirtualization), "CPUOptions.NestedVirtualization mismatch").
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change—adding nested virtualization support for AWS EC2 NodePools—which aligns with the PR's primary objective and all substantive modifications across API, controller, and test files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The PR does not contain Ginkgo tests, only standard Go tests. The custom check for stable/deterministic Ginkgo test names is not applicable to this PR.
Topology-Aware Scheduling Compatibility ✅ Passed PR adds AWS EC2 nested virtualization API support (CpuOptions struct) and controller logic to propagate to CAPA specs. No deployment manifests, pod scheduling constraints, affinity rules, topology...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed This PR adds only standard Go unit tests (not Ginkgo e2e tests). The custom check applies only to "new Ginkgo e2e tests", so it is not applicable here.
No-Weak-Crypto ✅ Passed PR contains no weak cryptography: no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB usage, no custom crypto implementations, no insecure secret comparisons. The changes add nested virtualization config for EC2...
Container-Privileges ✅ Passed PR does not modify any container or Kubernetes manifests with privileged configurations. Changes are Go API/controller code for EC2 instance CPU options (nested virtualization), not container secur...
No-Sensitive-Data-In-Logs ✅ Passed PR adds nested virtualization support without logging sensitive data; applyAWSMachineOptions() function propagates config values without logging them.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@openshift-ci openshift-ci Bot added area/api Indicates the PR includes changes for the API area/cli Indicates the PR includes changes for CLI area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/documentation Indicates the PR includes changes for documentation area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform and removed do-not-merge/needs-area labels Jun 5, 2026
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 5, 2026 08:04 Inactive
@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.98%. Comparing base (47574c0) to head (9a1adc2).
⚠️ Report is 26 commits behind head on main.

Files with missing lines Patch % Lines
hypershift-operator/controllers/nodepool/aws.go 88.88% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8681      +/-   ##
==========================================
+ Coverage   45.97%   45.98%   +0.01%     
==========================================
  Files         781      781              
  Lines       98056    98082      +26     
==========================================
+ Hits        45079    45102      +23     
- Misses      49905    49908       +3     
  Partials     3072     3072              
Files with missing lines Coverage Δ
cmd/cluster/aws/create.go 46.62% <ø> (-0.12%) ⬇️
hypershift-operator/controllers/nodepool/aws.go 83.67% <88.88%> (+0.34%) ⬆️
Flag Coverage Δ
cmd-support 39.16% <ø> (-0.01%) ⬇️
cpo-hostedcontrolplane 48.22% <ø> (ø)
cpo-other 46.01% <ø> (ø)
hypershift-operator 57.19% <88.88%> (+0.03%) ⬆️
other 34.71% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/cluster/aws/create.go`:
- Around line 410-414: Validate o.NestedVirtualization at the CLI boundary by
checking its value against the documented allow-list and return an error
immediately if it's not allowed; then compute the effective instance type (use
o.InstanceType if set else the code's default m5.large/m6g.large) and verify
that this instance type's family is one of the supported families for nested
virtualization, returning a clear validation error if incompatible; update the
block that assigns nodePool.Spec.Platform.AWS.CpuOptions (where
o.NestedVirtualization is used) to perform both checks and fail fast instead of
setting an invalid value.

In `@cmd/nodepool/aws/create.go`:
- Around line 108-109: Add early validation for the nested virtualization flag
before the NodePool spec is written. Implement allow-list based validation that
checks two things: first, verify that the nested virtualization value is only
"enabled" or "disabled" (reject any arbitrary values), and second, validate that
the selected instance family is compatible with nested virtualization (only C8i,
M8i, and R8i families are supported, so reject incompatible defaults like
m5.large and m6g.large). This validation should be added at the trust boundary
where the flag is processed and should reject invalid combinations before any
NodePool spec is created. Apply the same validation logic to the other affected
code sections around lines 176-180.

In `@support/controlplane-component/controlplane-component.go`:
- Around line 208-211: The deletion logic currently returns early based only on
the volatile field c.hasBeenApplied; update the delete path in the component's
delete handler (the method using c.hasBeenApplied) to avoid relying on in-memory
state by first checking persistent cluster state or resource markers
instead—e.g., query the API/server for the component resource or its
finalizer/annotation via the controller client (use the existing client/get
method used elsewhere) and only skip deletion when the resource truly does not
exist or when a persistent “never-delete” marker is present; remove the early
return that depends solely on c.hasBeenApplied and replace it with a
cluster-existence check and/or persistent state check before deciding not to
delete.
- Around line 186-190: The code marks c.hasBeenApplied = true regardless of
whether c.update(cpContext) returned an error; change the logic so
c.hasBeenApplied is set only when the update succeeded: call reconcilationError
= c.update(cpContext) and then set c.hasBeenApplied = true only if
reconcilationError == nil (i.e., after a successful return from c.update),
leaving it false when c.update fails so downstream delete/cleanup behavior
remains correct.

In `@support/controlplane-component/generic-adapter.go`:
- Around line 54-57: The short-circuit using the process-local flag
ga.hasBeenApplied causes deletion to be skipped after a controller restart;
remove that reliance and instead detect resource existence/ownership at runtime
before skipping deletion: in the delete path (where ga.hasBeenApplied is
checked) call the appropriate lookup/delete logic (e.g., use the adapter's
client or ga.get/ga.getResource method) to query the cluster for the resource or
its ownership/annotation, attempt the deletion if the resource is present, and
only ignore errors that indicate "not found"; keep the operation idempotent and
remove the ga.hasBeenApplied-only return so cleanup runs across restarts.
- Around line 21-22: The hasBeenApplied boolean on genericAdapter is mutated on
a value copy (so updates are lost) and is only in-memory (lost on restart);
change manifestsAdapters from map[string]genericAdapter to
map[string]*genericAdapter and update update() and any retrieval sites to use
pointer semantics so genericAdapter.reconcile() sets the real struct's
hasBeenApplied; also remove sole reliance on the in-memory flag by deriving
applied state from the cluster (e.g., check the target resource
existence/owner/annotation) or persist the flag into the control-plane
workload's Status (add a field in the CR status and read/write it in
update()/reconcile()) so the predicate-based cleanup survives restarts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: fea52243-7df4-4f72-a4be-ab67d3321aaa

📥 Commits

Reviewing files that changed from the base of the PR and between f13c62d and 3668271.

⛔ Files ignored due to path filters (167)
  • api/hypershift/v1beta1/zz_generated.deepcopy.go is excluded by !**/zz_generated*.go, !**/zz_generated*
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • client/applyconfiguration/hypershift/v1beta1/awsnodepoolplatform.go is excluded by !client/**
  • client/applyconfiguration/hypershift/v1beta1/cpuoptions.go is excluded by !client/**
  • client/applyconfiguration/utils.go is excluded by !client/**
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsclusters.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachines.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • docs/content/reference/aggregated-docs.md is excluded by !docs/content/reference/aggregated-docs.md
  • docs/content/reference/api.md is excluded by !docs/content/reference/api.md
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_AttachVolume.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_CreateSecondaryNetwork.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_CreateSecondarySubnet.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DeleteSecondaryNetwork.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DeleteSecondarySubnet.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondaryInterfaces.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondaryNetworks.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondarySubnets.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DetachVolume.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceCpuOptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceMetadataDefaults.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceMetadataOptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_RunInstances.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_SearchTransitGatewayRoutes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/deserializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/generated.json is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/go_module_metadata.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/serializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/types/enums.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/validators.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/LICENSE.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_client.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateAccessPolicy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateEncryptionConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateIdentityProviderConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreatePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeletePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeregisterCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddonConfiguration.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddonVersions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeClusterVersions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeIdentityProviderConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeInsight.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeInsightsRefresh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeUpdate.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DisassociateAccessPolicy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAccessEntries.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAccessPolicies.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAddons.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAssociatedAccessPolicies.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListCapabilities.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListClusters.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListEksAnywhereSubscriptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListFargateProfiles.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListIdentityProviderConfigs.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListInsights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListNodegroups.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListPodIdentityAssociations.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListTagsForResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListUpdates.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_RegisterCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_StartInsightsRefresh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_TagResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UntagResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateClusterConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateClusterVersion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateNodegroupConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateNodegroupVersion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdatePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/auth.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/deserializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/doc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/endpoints.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/generated.json is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/go_module_metadata.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/internal/endpoints/endpoints.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/options.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/serializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/types/enums.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/types/errors.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/validators.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift-online/ocm-common/pkg/resource/validations/kms_arn_regex_validation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/aws.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated*
  • vendor/golang.org/x/crypto/blake2b/blake2b.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2b_generic.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2b_ref.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/blake2x.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/go125.go is excluded by !vendor/**, !**/vendor/**
  • vendor/golang.org/x/crypto/blake2b/register.go is excluded by !vendor/**, !**/vendor/**
  • vendor/modules.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1/awscluster_conversion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1/awsmachine_conversion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1/network_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1/zz_generated.conversion.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated*
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awscluster_defaults.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awscluster_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awscluster_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsclustercontrolleridentity_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsclusterroleidentity_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsclusterstaticidentity_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsclustertemplate_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachinetemplate_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/bastion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/defaults.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/network_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated*
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/rosa/api/v1beta2/rosacontrolplane_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/rosa/api/v1beta2/rosacontrolplane_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/controlplane/rosa/api/v1beta2/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated*
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/OWNERS is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/awsfargateprofile_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/awsmachinepool_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/awsmanagedmachinepool_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/rosamachinepool_defaults.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/rosamachinepool_types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/rosamachinepool_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/rosanetwork_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/rosaroleconfig_webhook.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/validation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2/zz_generated.deepcopy.go is excluded by !vendor/**, !**/vendor/**, !**/zz_generated*.go, !**/zz_generated*
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/pkg/eks/eks.go is excluded by !vendor/**, !**/vendor/**
  • vendor/sigs.k8s.io/cluster-api-provider-aws/v2/pkg/hash/base36.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (7)
  • api/hypershift/v1beta1/aws.go
  • cmd/cluster/aws/create.go
  • cmd/nodepool/aws/create.go
  • go.mod
  • hypershift-operator/controllers/nodepool/aws.go
  • support/controlplane-component/controlplane-component.go
  • support/controlplane-component/generic-adapter.go

Comment thread cmd/cluster/aws/create.go Outdated
Comment thread cmd/nodepool/aws/create.go Outdated
Comment thread support/controlplane-component/controlplane-component.go
Comment thread support/controlplane-component/controlplane-component.go Outdated
Comment thread support/controlplane-component/generic-adapter.go Outdated
Comment thread support/controlplane-component/generic-adapter.go Outdated
@jhjaggars jhjaggars changed the title NO-JIRA: Add nested virtualization support for AWS EC2 NodePools CNTRLPLANE-3608: Add nested virtualization support for AWS EC2 NodePools Jun 8, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 8, 2026

Copy link
Copy Markdown

@jhjaggars: This pull request references CNTRLPLANE-3608 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Adds support for enabling nested virtualization on AWS EC2 instances (C8i, M8i, R8i families) through the NodePool API. This allows running OpenShift Virtualization (KubeVirt) workloads on AWS-hosted clusters.

  • API: Add CpuOptions struct with NestedVirtualization field to AWSNodePoolPlatform
  • Vendor: Bump CAPA from v2.10.0 to v2.11.1 which includes upstream NestedVirtualization support in CPUOptions (PR kubernetes-sigs/cluster-api-provider-aws#5874)
  • CLI: Add --nested-virtualization flag to hypershift create cluster aws and hypershift create nodepool aws
  • Controller: Wire CpuOptions.NestedVirtualization from NodePool spec to CAPA AWSMachineTemplateSpec.CPUOptions
  • CPO fix: Prevent informer creation for unused platform-specific resources (e.g. SecretProviderClass on non-Azure clusters)
  • Built custom HO image and installed on management cluster
  • Created hosted cluster with --nested-virtualization enabled --instance-type c8i.2xlarge
  • Verified cpuOptions.nestedVirtualization: enabled propagates through: NodePool → AWSMachineTemplate → AWSMachine → EC2 instance
  • Confirmed EC2 CpuOptions.NestedVirtualization: enabled via AWS CLI
  • Confirmed vmx CPU flag present on guest nodes via /proc/cpuinfo
    N/A — new feature
  • Subject and description added to both, commit and PR.
  • Relevant issues have been referenced.
  • This change includes docs.
  • This change includes unit tests.

Summary by CodeRabbit

  • New Features

  • Added EC2 nested virtualization configuration option for AWS-backed node pools. Users can now enable or disable nested virtualization when creating or updating clusters and node pools using the new --nested-virtualization CLI flag.

  • Chores

  • Updated AWS EC2 SDK and Cluster API provider dependencies to latest versions.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@jhjaggars
jhjaggars force-pushed the virt-on-new-aws-nodes branch from 3668271 to 3657529 Compare June 10, 2026 14:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
api/hypershift/v1beta1/aws.go (1)

76-76: ⚡ Quick win

Remove redundant omitempty from JSON tag for consistency.

The omitempty tag doesn't omit empty structs (only pointers, maps, slices, strings, numbers). For value-type struct fields, omitzero is the correct tag. Line 126 demonstrates the correct pattern with SpotOptions:

Spot SpotOptions `json:"spot,omitzero"`
Proposed fix
-	CpuOptions CpuOptions `json:"cpuOptions,omitzero,omitempty"`
+	CpuOptions CpuOptions `json:"cpuOptions,omitzero"`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/hypershift/v1beta1/aws.go` at line 76, The JSON tag for the CpuOptions
field uses both "omitzero" and "omitempty" redundantly; update the CpuOptions
declaration (CpuOptions CpuOptions `json:"cpuOptions,omitzero,omitempty"`) to
remove "omitempty" so it matches the pattern used for Spot (e.g.,
`json:"spot,omitzero"`), leaving only "omitzero" to correctly omit zero-value
structs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/hypershift/v1beta1/aws.go`:
- Line 76: The JSON tag for the CpuOptions field uses both "omitzero" and
"omitempty" redundantly; update the CpuOptions declaration (CpuOptions
CpuOptions `json:"cpuOptions,omitzero,omitempty"`) to remove "omitempty" so it
matches the pattern used for Spot (e.g., `json:"spot,omitzero"`), leaving only
"omitzero" to correctly omit zero-value structs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: e6025936-e97d-42d1-81ad-6d25745be666

📥 Commits

Reviewing files that changed from the base of the PR and between 3668271 and 3657529.

⛔ Files ignored due to path filters (99)
  • api/hypershift/v1beta1/zz_generated.deepcopy.go is excluded by !**/zz_generated*.go, !**/zz_generated*
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OSStreams.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • client/applyconfiguration/hypershift/v1beta1/awsnodepoolplatform.go is excluded by !client/**
  • client/applyconfiguration/hypershift/v1beta1/cpuoptions.go is excluded by !client/**
  • client/applyconfiguration/utils.go is excluded by !client/**
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsclusters.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachines.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/cluster-api-provider-aws/infrastructure.cluster.x-k8s.io_awsmachinetemplates.yaml is excluded by !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/**, !cmd/install/assets/**/*.yaml
  • docs/content/reference/aggregated-docs.md is excluded by !docs/content/reference/aggregated-docs.md
  • docs/content/reference/api.md is excluded by !docs/content/reference/api.md
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_AttachVolume.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_CreateSecondaryNetwork.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_CreateSecondarySubnet.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DeleteSecondaryNetwork.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DeleteSecondarySubnet.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondaryInterfaces.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondaryNetworks.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DescribeSecondarySubnets.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_DetachVolume.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceCpuOptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceMetadataDefaults.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_ModifyInstanceMetadataOptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_RunInstances.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/api_op_SearchTransitGatewayRoutes.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/deserializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/generated.json is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/go_module_metadata.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/serializers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/types/enums.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/ec2/validators.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/LICENSE.txt is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_client.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateAccessPolicy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateEncryptionConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_AssociateIdentityProviderConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreateNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_CreatePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeleteNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeletePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DeregisterCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAccessEntry.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddon.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddonConfiguration.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeAddonVersions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeCapability.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeClusterVersions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeEksAnywhereSubscription.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeFargateProfile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeIdentityProviderConfig.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeInsight.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeInsightsRefresh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeNodegroup.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribePodIdentityAssociation.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DescribeUpdate.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_DisassociateAccessPolicy.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAccessEntries.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAccessPolicies.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAddons.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListAssociatedAccessPolicies.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListCapabilities.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListClusters.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListEksAnywhereSubscriptions.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListFargateProfiles.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListIdentityProviderConfigs.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListInsights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListNodegroups.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListPodIdentityAssociations.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListTagsForResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_ListUpdates.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_RegisterCluster.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_StartInsightsRefresh.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_TagResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UntagResource.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/aws/aws-sdk-go-v2/service/eks/api_op_UpdateAccessEntry.go is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (5)
  • api/hypershift/v1beta1/aws.go
  • cmd/cluster/aws/create.go
  • cmd/nodepool/aws/create.go
  • go.mod
  • hypershift-operator/controllers/nodepool/aws.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • hypershift-operator/controllers/nodepool/aws.go
  • cmd/nodepool/aws/create.go
  • go.mod
  • cmd/cluster/aws/create.go

@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 10, 2026 15:05 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
api/hypershift/v1beta1/nodepool_types_test.go (1)

19-24: ⚡ Quick win

Use an isolated N-1 subnet fixture type in the compatibility struct.

awsNodePoolPlatformNMinus1 currently embeds AWSResourceReference from the current API. That can mask nested-field compatibility regressions because the N-1 fixture evolves with current code. Prefer a local N-1 subnet struct (e.g., just id) to pin the previous wire contract independently.

Suggested change
+type awsResourceReferenceNMinus1 struct {
+	ID *string `json:"id,omitempty"`
+}
+
 type awsNodePoolPlatformNMinus1 struct {
 	// instanceType is the EC2 instance type.
 	InstanceType string `json:"instanceType"` //nolint:kubeapilinter // test-only N-1 compat struct
 	// subnet is the subnet reference.
-	Subnet AWSResourceReference `json:"subnet"` //nolint:kubeapilinter // test-only N-1 compat struct
+	Subnet awsResourceReferenceNMinus1 `json:"subnet"` //nolint:kubeapilinter // test-only N-1 compat struct
 }

As per coding guidelines, “When modifying API types, add serialization compatibility tests that define a struct matching the previous version of the type.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/hypershift/v1beta1/nodepool_types_test.go` around lines 19 - 24, The
compatibility struct awsNodePoolPlatformNMinus1 currently reuses the live
AWSResourceReference which can drift; replace the embedded AWSResourceReference
in awsNodePoolPlatformNMinus1 with a local N-1 subnet fixture struct (e.g., type
with just `ID string` tagged `json:"id"`) and change the Subnet field's type to
that local struct so the test pins the previous wire contract independently
(update any test serializers/deserializers referencing
awsNodePoolPlatformNMinus1/Subnet accordingly).

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/hypershift/v1beta1/nodepool_types_test.go`:
- Around line 19-24: The compatibility struct awsNodePoolPlatformNMinus1
currently reuses the live AWSResourceReference which can drift; replace the
embedded AWSResourceReference in awsNodePoolPlatformNMinus1 with a local N-1
subnet fixture struct (e.g., type with just `ID string` tagged `json:"id"`) and
change the Subnet field's type to that local struct so the test pins the
previous wire contract independently (update any test serializers/deserializers
referencing awsNodePoolPlatformNMinus1/Subnet accordingly).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 7c57b3b1-4e5a-4c38-9013-c81ecaf79699

📥 Commits

Reviewing files that changed from the base of the PR and between 3657529 and 825b2ee.

⛔ Files ignored due to path filters (2)
  • cmd/install/assets/crds/hypershift-operator/tests/nodepools.hypershift.openshift.io/stable.nodepools.aws.testsuite.yaml is excluded by !cmd/install/assets/**/*.yaml
  • docs/content/reference/aggregated-docs.md is excluded by !docs/content/reference/aggregated-docs.md
📒 Files selected for processing (3)
  • api/hypershift/v1beta1/nodepool_types_test.go
  • cmd/cluster/aws/create.go
  • hypershift-operator/controllers/nodepool/aws_test.go
💤 Files with no reviewable changes (1)
  • cmd/cluster/aws/create.go

@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 10, 2026 17:44 Inactive
@jhjaggars
jhjaggars force-pushed the virt-on-new-aws-nodes branch from 825b2ee to c16401a Compare June 10, 2026 18:33
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 10, 2026 18:39 Inactive
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 11, 2026 13:53 Inactive
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 June 11, 2026 15:31 Inactive
@jhjaggars
jhjaggars force-pushed the virt-on-new-aws-nodes branch from f22e45f to f453ef0 Compare July 7, 2026 16:10
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 7, 2026
@openshift-ci-robot openshift-ci-robot removed the verified Signifies that the PR passed pre-merge verification criteria label Aug 12, 2026
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 August 12, 2026 14:43 Inactive
@jhjaggars
jhjaggars force-pushed the virt-on-new-aws-nodes branch from 6489b5f to 7f5671b Compare August 13, 2026 13:29
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 August 13, 2026 13:35 Inactive
Comment thread api/hypershift/v1beta1/aws.go
@jhjaggars

Copy link
Copy Markdown
Contributor Author

Thanks all for the review — pushed 937c622 addressing @muraee's request for validation on nested virtualization instance-type compatibility (a new check in validateAWSPlatformConfig, surfaced via the ValidPlatformConfig NodePool condition, rejecting nestedVirtualizationPolicy: Enabled on instance types outside the C8i/M8i/R8i families and their -flex variants).

@clebs re: commit history cleanup — agreed it'd be cleaner, but since this will be squash-merged the intermediate history won't matter in the final commit. Leaving as-is unless there's a reason to tidy it before merge.

All other review threads addressed and resolved.

@openshift-ci

openshift-ci Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: jhjaggars
Once this PR has been reviewed and has the lgtm label, please assign enxebre for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-8681 August 18, 2026 18:24 Inactive
@jhjaggars

Copy link
Copy Markdown
Contributor Author

/retest ci/prow/verify

@jhjaggars

Copy link
Copy Markdown
Contributor Author

/test verify

type CPUOptions struct {
// nestedVirtualizationPolicy indicates whether to enable nested virtualization on the instance.
// Supported on C8i, M8i, and R8i instance families.
// When omitted, nested virtualization is not enabled (AWS default behavior).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last godoc change from the API perspective: enums should document possibly values and their usage, for example, something like

  // Valid values are "Enabled" and "Disabled".
  // When set to "Enabled", nested virtualization is enabled on the instance.
  // When set to "Disabled", nested virtualization is explicitly disabled on the instance.

jhjaggars and others added 11 commits August 21, 2026 12:19
…tform

Add CpuOptions struct with NestedVirtualization field to
AWSNodePoolPlatform for configuring nested virtualization on
EC2 instances (C8i, M8i, R8i families).

- Add CpuOptions type with omitzero value semantics
- Add MinProperties=1 validation marker
- Regenerate deepcopy and featuregated CRD manifests

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…ool creation

Add --nested-virtualization flag to hypershift create cluster aws
and hypershift create nodepool aws commands. When set, configures
CpuOptions.NestedVirtualization on the NodePool's AWS platform spec.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
…nested virtualization

Propagate CpuOptions.NestedVirtualization from NodePool spec to
CAPA AWSMachineTemplateSpec.CPUOptions during AWSMachineTemplate
reconciliation.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Regenerate aggregated-docs.md and api.md to include the new
CpuOptions type and NestedVirtualization field documentation.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Remove the AWS create-time nested virtualization flags so this option is only
set through rendered manifests where the instance type can be reviewed.

Add API compatibility, controller, and envtest coverage for CpuOptions so the
new field is protected against regressions.

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
…ller

Replace raw string with typed NestedVirtualizationPolicy constants
(enabled/disabled) for CpuOptions.NestedVirtualization. Add nil-guard
for AWS platform in applyAWSMachineOptions. Expand test coverage with
disabled and nil-platform cases in unit tests and CEL envtest suite.
Regenerate client apply config and API docs.
- Remove redundant omitempty from CpuOptions JSON tag (omitzero suffices
  for zero-value struct omission, matching SpotOptions pattern)
- Add descriptive failure messages to all Gomega assertions in
  TestApplyAWSMachineOptions for easier debugging
…onventions

Rename CpuOptions to CPUOptions per Go acronym convention.
Rename NestedVirtualization field to NestedVirtualizationPolicy
to match the type name. Change enum values from lowercase
enabled/disabled to PascalCase Enabled/Disabled per OpenShift
API convention. Add explicit mapping in the controller between
HyperShift and CAPA enum values.

Add godoc comments documenting default behavior when cpuOptions
is omitted and noting that reverting requires removing the entire
cpuOptions field.

Split applyAWSMachineOptions back into applyAWSPlacementOptions
and a new applyAWSCPUOptions for better separation of concerns.

Regenerate CRDs, deepcopy, client, and API docs.

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
… instance families

Add a check to validateAWSPlatformConfig (surfaced via the ValidPlatformConfig
NodePool condition) that rejects cpuOptions.nestedVirtualizationPolicy=Enabled
when instanceType isn't a C8i, M8i, or R8i family (including their -flex
variants), matching AWS's documented CPU options support matrix. This fails
fast with a clear condition message instead of only failing later at the AWS
API when the instance is actually launched.

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
Fix minor gofmt column-alignment drift in the CPUOptions applyconfiguration
struct and pick up unrelated API doc updates (Azure/monitoring/encryption
types) that had fallen behind main since this branch was last rebased.

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@clebs

clebs commented Aug 24, 2026

Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 24, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-5-0
/test e2e-aws-5-0
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-azure-self-managed
/test e2e-v2-gke

@clebs

clebs commented Aug 25, 2026

Copy link
Copy Markdown
Member

/test e2e-v2-azure-self-managed

@openshift-ci

openshift-ci Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

@jhjaggars: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-v2-azure-self-managed 9a1adc2 link true /test e2e-v2-azure-self-managed

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api Indicates the PR includes changes for the API area/cli Indicates the PR includes changes for CLI area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/documentation Indicates the PR includes changes for documentation area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants