-
Notifications
You must be signed in to change notification settings - Fork 567
OCPSTRAT-1677: feat: allow for aws spot market options on node pools #6707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,8 +59,21 @@ type AWSNodePoolPlatform struct { | |
| Placement *PlacementOptions `json:"placement,omitempty"` | ||
| } | ||
|
|
||
| // AWSSpotMarketOptions defines configuration for AWS Spot instances | ||
| type AWSSpotMarketOptions struct { | ||
| // maxPrice defines the maximum price (USD per instance‑hour) you are willing to pay for a Spot instance. | ||
| // If omitted, the On‑Demand price is used as the ceiling. | ||
| // Example: "0.0739" | ||
| // Format: up to 10 integer digits and up to 6 fractional digits; no leading zeros unless the value is "0"; scientific notation is not allowed. | ||
| // +optional | ||
| // +kubebuilder:validation:Pattern=`^(0|[1-9][0-9]{0,9})(\.[0-9]{1,6})?$` | ||
| // +kubebuilder:validation:MaxLength=17 | ||
| MaxPrice *string `json:"maxPrice,omitempty"` | ||
| } | ||
|
|
||
| // PlacementOptions specifies the placement options for the EC2 instances. | ||
| // +kubebuilder:validation:XValidation:rule="has(self.tenancy) && self.tenancy == 'host' ? !has(self.capacityReservation) : true", message="AWS Capacity Reservations cannot be used with Dedicated Hosts (tenancy 'host')" | ||
| // +kubebuilder:validation:XValidation:rule="has(self.spotMarketOptions) ? (!has(self.capacityReservation) && (!has(self.tenancy) || self.tenancy == 'default')) : true", message="spotMarketOptions is incompatible with capacityReservation and requires tenancy to be 'default' or unset (not 'dedicated' or 'host')" | ||
| type PlacementOptions struct { | ||
| // tenancy indicates if instance should run on shared or single-tenant hardware. | ||
| // | ||
|
|
@@ -83,6 +96,12 @@ type PlacementOptions struct { | |
| // | ||
| // +optional | ||
| CapacityReservation *CapacityReservationOptions `json:"capacityReservation,omitempty"` | ||
|
|
||
| // spotMarketOptions specifies options for using AWS Spot instances. | ||
| // When specified, instances will be launched as Spot instances with the given configuration. | ||
| // Mutually exclusive with capacityReservation, and tenancy must be unset or set to "default". | ||
| // +optional | ||
| SpotMarketOptions *AWSSpotMarketOptions `json:"spotMarketOptions,omitempty"` | ||
|
Comment on lines
+100
to
+104
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it's copying a very old API which I suspect wouldn't be the way we would recommend implementing this API if we were to go through the API review process today In particular, it's awkward to use Really you need a discriminated union, which would include the capacity reservation options as well. If you look at the way MAPI implements this, we have one of the The ideal here would have been I'm not sure why MarketType ended up inside the CapacityReservationOptions here, we really should have looked at how this looked in MAPI and predicted this need 🤔
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can either keep it as in the PR or mark CapacityReservation.MarketType as deprecated and expose a new one within PlacementOptions.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're happy with a deprecated field, I think it would make more sense to restructure this slightly. We should be able to validate at admission time that the two fields are not different if the existing
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me know what is the direction to follow on this, I agree having the market type directly on placement makes more sense as well |
||
| } | ||
|
|
||
| // MarketType describes the market type of the CapacityReservation for an Instance. | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -487,6 +487,22 @@ spec: | |
| requires a Capacity Reservation ID | ||
| rule: 'has(self.marketType) && self.marketType == ''CapacityBlocks'' | ||
| ? has(self.id) : true' | ||
| spotMarketOptions: | ||
| description: |- | ||
| spotMarketOptions specifies options for using AWS Spot instances. | ||
| When specified, instances will be launched as Spot instances with the given configuration. | ||
| Mutually exclusive with capacityReservation, and tenancy must be unset or set to "default". | ||
| properties: | ||
| maxPrice: | ||
| description: |- | ||
| maxPrice defines the maximum price (USD per instance‑hour) you are willing to pay for a Spot instance. | ||
| If omitted, the On‑Demand price is used as the ceiling. | ||
| Example: "0.0739" | ||
| Format: up to 10 integer digits and up to 6 fractional digits; no leading zeros unless the value is "0"; scientific notation is not allowed. | ||
| maxLength: 17 | ||
| pattern: ^(0|[1-9][0-9]{0,9})(\.[0-9]{1,6})?$ | ||
| type: string | ||
| type: object | ||
|
Comment on lines
+490
to
+505
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainNon-ASCII hyphens in descriptions (“instance‑hour”, “On‑Demand”). Replace U+2011/U+2013 style hyphens with ASCII "-" in the Go API comments (api/hypershift/v1beta1/aws.go), then regenerate CRDs to avoid encoding issues in tooling. Apply in api/hypershift/v1beta1/aws.go: -// maxPrice defines the maximum price (USD per instance‑hour) you are willing to pay for a Spot instance.
-// If omitted, the On‑Demand price is used as the ceiling.
+// maxPrice defines the maximum price (USD per instance-hour) you are willing to pay for a Spot instance.
+// If omitted, the On-Demand price is used as the ceiling.Then run codegen and verify no non-ASCII hyphens remain: 🏁 Script executed: #!/bin/bash
rg -nU "[\u2010-\u2015]" cmd/install/assets/hypershift-operator/zz_generated.crd-manifests || trueLength of output: 1397 Fix non-ASCII hyphens and regenerate CRDs The following generated CRDs still contain non-ASCII hyphens at lines 498–499:
Apply the diff in api/hypershift/v1beta1/aws.go, rerun codegen, then verify no non-ASCII hyphens remain: rg -nU "[\u2010-\u2015]" cmd/install/assets/hypershift-operator/zz_generated.crd-manifests || true🤖 Prompt for AI Agents |
||
| tenancy: | ||
| description: |- | ||
| tenancy indicates if instance should run on shared or single-tenant hardware. | ||
|
|
@@ -509,6 +525,12 @@ spec: | |
| Hosts (tenancy 'host') | ||
| rule: 'has(self.tenancy) && self.tenancy == ''host'' ? !has(self.capacityReservation) | ||
| : true' | ||
| - message: spotMarketOptions is incompatible with capacityReservation | ||
| and requires tenancy to be 'default' or unset (not 'dedicated' | ||
| or 'host') | ||
| rule: 'has(self.spotMarketOptions) ? (!has(self.capacityReservation) | ||
| && (!has(self.tenancy) || self.tenancy == ''default'')) | ||
| : true' | ||
| resourceTags: | ||
| description: |- | ||
| resourceTags is an optional list of additional tags to apply to AWS node | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can I express intent for this with this API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, I was thinking of omitzero. I guess this is a legit case to use omitempty and not omitzero cc @JoelSpeed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Historically, spot markets could exceed the on-demand price, is that still the case?
What is the use case for
0for the maximum price? Does AWS allow a0max price?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"If you specify a maximum price, it must be more than USD $0.001. Specifying a value below USD $0.001 will result in an InvalidParameterValue error message."
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotMarketOptions.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your pattern presently allows
0as a valid choice, please update to remove that