Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ linters:
# Ref: https://go.dev/doc/effective_go#redeclaration
- path: (.+)\.go$
text: declaration of "err" shadows declaration at
# FailoverReservations are deprecated in favor of FailoverHostReservations,
# but remain in active use during the transition. Ignore the deprecation
# warning until the old type is fully removed.
- linters:
- staticcheck
text: "SA1019:.*FailoverReservations will be replaced with FailoverHostReservations"
- linters:
- goconst
path: (.+)_test\.go
Expand Down
130 changes: 120 additions & 10 deletions api/v1alpha1/reservation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,45 @@ type ReservationType string
const (
// ReservationTypeCommittedResource is a reservation for committed/reserved capacity.
ReservationTypeCommittedResource ReservationType = "CommittedResourceReservation"

// ReservationTypeFailover is a reservation for failover capacity.
//
// Deprecated: FailoverReservations will be replaced with
// FailoverHostReservations. See ReservationTypeFailoverHost.
ReservationTypeFailover ReservationType = "FailoverReservation"

// ReservationTypeInFlight is a reservation that blocks capacity for virtual
// machines that are currently being scheduled, to avoid double-booking.
ReservationTypeInFlight ReservationType = "InFlightReservation"

// ReservationTypeFailoverHost is a reservation that blocks an entire
// host for failover purposes, so that another host can gang-evacuate
// its workloads to a designated spot. If this type is set, the reservation
// will follow this lifecycle:
//
// 1. Designation. The reservation has been created on a host. There may be
// virtual machines running on this host that need live migration away. As
// long as not all virtual machines can be migrated away from the host, the
// reservation stays in this state. For pipeline: no new virtual machine
// onto this host.
//
// 2. Active. No more virtual machines on this host. On evacuation this
// space can be used.
//
// 3. Failed. The descheduling failed repeatedly or takes too long, the host
// is marked for a certain time to not be designated again.
//
// 4. In Use. Ongoing gang evacuation onto this host, which will be reused
// by subsequent failover events until the evacuation is completed.
//
// 5. Revoked (=Deleted). The reservation is no longer valid because it no
// longer matches any failover partition. This may be because the host has
// been marked as no longer schedulable or has been otherwise changed.
//
// 6. Used (=Deleted). The failover event has been completed. The
// reservation is no longer valid and the host is transformed back into
// a regular host.
ReservationTypeFailoverHost ReservationType = "FailoverHostReservation"
)

// Label keys for Reservation metadata.
Expand All @@ -39,6 +73,7 @@ const (
ReservationTypeLabelCommittedResource = "committed-resource"
ReservationTypeLabelFailover = "failover"
ReservationTypeLabelInFlight = "in-flight"
ReservationTypeLabelFailoverHost = "failover-host"
)

// Annotation keys for Reservation metadata.
Expand Down Expand Up @@ -101,7 +136,15 @@ type CommittedResourceReservationSpec struct {
Allocations map[string]CommittedResourceAllocation `json:"allocations,omitempty"`
}

// MatchesGroup reports whether the reservation targets the given project and resource group.
func (s *CommittedResourceReservationSpec) MatchesGroup(projectID, resourceGroup string) bool {
return s.ProjectID == projectID && s.ResourceGroup == resourceGroup
}

// FailoverReservationSpec defines the spec fields specific to failover reservations.
//
// Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
// See FailoverHostReservationSpec.
type FailoverReservationSpec struct {
// ResourceGroup is the group/category of the resource (e.g., "hana_medium_v2").
// +kubebuilder:validation:Optional
Expand All @@ -128,10 +171,20 @@ type InFlightReservationSpec struct {
Intent SchedulingIntent `json:"intent"`
}

// FailoverHostReservationSpec defines the spec fields specific to failover
// host reservations. See ReservationTypeFailoverHost.
type FailoverHostReservationSpec struct {
// SourceHosts is a list of hosts inside the same failover partition from
// which a failover event towards the target host may originate.
// See Spec.TargetHost for the target host of the failover reservation.
// +kubebuilder:validation:Optional
SourceHosts []string `json:"sourceHosts,omitempty"`
}

// ReservationSpec defines the desired state of Reservation.
type ReservationSpec struct {
// Type of reservation.
// +kubebuilder:validation:Enum=CommittedResourceReservation;FailoverReservation;InFlightReservation
// +kubebuilder:validation:Enum=CommittedResourceReservation;FailoverReservation;InFlightReservation;FailoverHostReservation
// +kubebuilder:validation:Required
Type ReservationType `json:"type"`

Expand Down Expand Up @@ -170,12 +223,19 @@ type ReservationSpec struct {

// FailoverReservation contains fields specific to failover reservations.
// Only used when Type is FailoverReservation.
//
// Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
// +kubebuilder:validation:Optional
FailoverReservation *FailoverReservationSpec `json:"failoverReservation,omitempty"`

// InFlightReservation specifies which kind of virtual machine is expected
// to land on the reserved slot. Set when Type is InFlightReservation.
InFlightReservation *InFlightReservationSpec `json:"inFlightReservation,omitempty"`

// FailoverHostReservation contains fields specific to failover host reservations.
// Only used when Type is FailoverHostReservation.
// +kubebuilder:validation:Optional
FailoverHostReservation *FailoverHostReservationSpec `json:"failoverHostReservation,omitempty"`
}

const (
Expand All @@ -198,6 +258,9 @@ type CommittedResourceReservationStatus struct {
}

// FailoverReservationStatus defines the status fields specific to failover reservations.
//
// Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
// See FailoverHostReservationStatus.
type FailoverReservationStatus struct {
// Allocations maps VM/instance UUIDs to the host they are currently allocated on.
// Key: VM/instance UUID, Value: Host name where the VM is currently running.
Expand All @@ -221,6 +284,51 @@ type FailoverReservationStatus struct {
// in-flight reservations.
type InFlightReservationStatus struct{} // No captured state for now.

// FailoverHostReservationStatus defines the status fields specific to failover
// host reservations.
type FailoverHostReservationStatus struct {
// SourceHost is the actual host from which the failover event originates.
// Only set when the condition ConditionTypeFailoverHostInUse is True.
// +kubebuilder:validation:Optional
SourceHost string `json:"sourceHost,omitempty"`
}

// ReservationConditionType represents the type of condition for a reservation.
type ReservationConditionType = string

const (
// ConditionTypeFailoverHostDesignated indicates that the reservation has
// been created on a host. There may be virtual machines running on this
// host that need live migration away. As long as not all virtual machines
// can be migrated away from the host, the reservation stays in this state.
// For pipeline: no new virtual machine onto this host.
//
// status=Unknown: It is unknown if the failover host has been designated.
// status=False: The failover host has not been designated (there was an error).
// status=True: The failover host has been designated successfully.
ConditionTypeFailoverHostDesignated ReservationConditionType = "FailoverHostDesignated"

// ConditionTypeFailoverHostActive indicates that the failover host is
// active and ready to accept evacuations. No more virtual machines have
// been seen on this host, so it is empty and ready to receive all vms
// from another host.
//
// status=Unknown: The failover host is not yet ready to be used.
// status=False: There has been some error or issue preventing the failover
// host from being active.
// status=True: The failover host is active and ready to accept evacuations.
ConditionTypeFailoverHostActive ReservationConditionType = "FailoverHostActive"

// ConditionTypeFailoverHostInUse indicates that the failover host reservation
// is currently being used by an ongoing evacuation event with inbound
// virtual machines being evacuated.
//
// status=Unknown: It is unknown if the failover host is currently in use.
// status=False: The failover host is not currently in use.
// status=True: The failover host is currently in use.
ConditionTypeFailoverHostInUse ReservationConditionType = "FailoverHostInUse"
)

// ReservationStatus defines the observed state of Reservation.
type ReservationStatus struct {
// The current status conditions of the reservation.
Expand Down Expand Up @@ -249,13 +357,20 @@ type ReservationStatus struct {

// FailoverReservation contains status fields specific to failover reservations.
// Only used when Type is FailoverReservation.
//
// Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
// +kubebuilder:validation:Optional
FailoverReservation *FailoverReservationStatus `json:"failoverReservation,omitempty"`

// InFlightReservation contains status fields specific to in-flight reservations.
// Only used when Type is InFlightReservation.
// +kubebuilder:validation:Optional
InFlightReservation *InFlightReservationStatus `json:"inFlightReservation,omitempty"`

// FailoverHostReservation contains status fields specific to failover
// host reservations. Only used when Type is FailoverHostReservation.
// +kubebuilder:validation:Optional
FailoverHostReservation *FailoverHostReservationStatus `json:"failoverHostReservation,omitempty"`
}

// +kubebuilder:object:root=true
Expand All @@ -264,12 +379,12 @@ type ReservationStatus struct {
// +kubebuilder:printcolumn:name="Type",type="string",JSONPath=".metadata.labels['reservations\\.cortex\\.cloud/type']"
// +kubebuilder:printcolumn:name="Host",type="string",JSONPath=".status.host"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
// +kubebuilder:printcolumn:name="ResourceGroup",type="string",JSONPath=".spec.committedResourceReservation.resourceGroup"
// +kubebuilder:printcolumn:name="ResourceGroup",type="string",JSONPath=".spec.committedResourceReservation.resourceGroup",priority=1
// +kubebuilder:printcolumn:name="HA ResourceGroup",type="string",JSONPath=".spec.failoverReservation.resourceGroup",priority=1
// +kubebuilder:printcolumn:name="Project",type="string",JSONPath=".spec.committedResourceReservation.projectID"
// +kubebuilder:printcolumn:name="AZ",type="string",JSONPath=".spec.availabilityZone"
// +kubebuilder:printcolumn:name="Project",type="string",JSONPath=".spec.committedResourceReservation.projectID",priority=1
// +kubebuilder:printcolumn:name="AZ",type="string",JSONPath=".spec.availabilityZone",priority=1
// +kubebuilder:printcolumn:name="StartTime",type="string",JSONPath=".spec.startTime",priority=1
// +kubebuilder:printcolumn:name="EndTime",type="string",JSONPath=".spec.endTime"
// +kubebuilder:printcolumn:name="EndTime",type="string",JSONPath=".spec.endTime",priority=1
// +kubebuilder:printcolumn:name="Resources",type="string",JSONPath=".spec.resources",priority=1
// +kubebuilder:printcolumn:name="LastChanged",type="date",JSONPath=".status.failoverReservation.lastChanged",priority=1
// +kubebuilder:printcolumn:name="AcknowledgedAt",type="date",JSONPath=".status.failoverReservation.acknowledgedAt",priority=1
Expand Down Expand Up @@ -302,11 +417,6 @@ type ReservationList struct {
Items []Reservation `json:"items"`
}

// MatchesGroup reports whether the reservation targets the given project and resource group.
func (s *CommittedResourceReservationSpec) MatchesGroup(projectID, resourceGroup string) bool {
return s.ProjectID == projectID && s.ResourceGroup == resourceGroup
}

// IsReady returns true if the reservation has the Ready condition set to True.
func (r *Reservation) IsReady() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, ReservationConditionReady)
Expand Down
45 changes: 45 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions helm/library/cortex/files/crds/cortex.cloud_reservations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,27 @@ spec:
type: string
- jsonPath: .spec.committedResourceReservation.resourceGroup
name: ResourceGroup
priority: 1
type: string
- jsonPath: .spec.failoverReservation.resourceGroup
name: HA ResourceGroup
priority: 1
type: string
- jsonPath: .spec.committedResourceReservation.projectID
name: Project
priority: 1
type: string
- jsonPath: .spec.availabilityZone
name: AZ
priority: 1
type: string
- jsonPath: .spec.startTime
name: StartTime
priority: 1
type: string
- jsonPath: .spec.endTime
name: EndTime
priority: 1
type: string
- jsonPath: .spec.resources
name: Resources
Expand Down Expand Up @@ -163,10 +167,26 @@ spec:
description: EndTime is the time when the reservation expires.
format: date-time
type: string
failoverHostReservation:
description: |-
FailoverHostReservation contains fields specific to failover host reservations.
Only used when Type is FailoverHostReservation.
properties:
sourceHosts:
description: |-
SourceHosts is a list of hosts inside the same failover partition from
which a failover event towards the target host may originate.
See Spec.TargetHost for the target host of the failover reservation.
items:
type: string
type: array
type: object
failoverReservation:
description: |-
FailoverReservation contains fields specific to failover reservations.
Only used when Type is FailoverReservation.

Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
properties:
resourceGroup:
description: ResourceGroup is the group/category of the resource
Expand Down Expand Up @@ -229,6 +249,7 @@ spec:
- CommittedResourceReservation
- FailoverReservation
- InFlightReservation
- FailoverHostReservation
type: string
required:
- type
Expand Down Expand Up @@ -320,10 +341,23 @@ spec:
- type
type: object
type: array
failoverHostReservation:
description: |-
FailoverHostReservation contains status fields specific to failover
host reservations. Only used when Type is FailoverHostReservation.
properties:
sourceHost:
description: |-
SourceHost is the actual host from which the failover event originates.
Only set when the condition ConditionTypeFailoverHostInUse is True.
type: string
type: object
failoverReservation:
description: |-
FailoverReservation contains status fields specific to failover reservations.
Only used when Type is FailoverReservation.

Deprecated: FailoverReservations will be replaced with FailoverHostReservations.
properties:
acknowledgedAt:
description: |-
Expand Down
Loading