Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
39 changes: 31 additions & 8 deletions api/v1alpha1/flavor_group_capacity_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ type FlavorGroupCapacitySpec struct {
AvailabilityZone string `json:"availabilityZone"`
}

// FlavorCapacityStatus holds per-flavor capacity numbers for one (flavor group × AZ) pair.
// FlavorCapacityStatus holds per-flavor scheduler probe results for one (flavor group × AZ) pair.
// These values come directly from scheduler probes and are independent of the cross-group
// capacity split (see FreeCapacity and ExclusivelyFreeCapacity on the parent status).
// "Placeable" means: if all remaining capacity in this AZ were used solely by this flavor,
// this is how many would fit. It does not account for competing flavor groups.
type FlavorCapacityStatus struct {
// FlavorName is the OpenStack flavor name (e.g. "hana-v2-small").
FlavorName string `json:"flavorName"`
Expand All @@ -37,11 +41,11 @@ type FlavorCapacityStatus struct {
// +kubebuilder:validation:Optional
PlaceableVMs int64 `json:"placeableVms,omitempty"`

// TotalCapacityHosts is the number of eligible hosts in an empty-datacenter scenario.
// TotalCapacityHosts is the number of eligible hosts assuming an empty datacenter.
// +kubebuilder:validation:Optional
TotalCapacityHosts int64 `json:"totalCapacityHosts,omitempty"`

// TotalCapacityVMSlots is the maximum number of VM slots in an empty-datacenter scenario.
// TotalCapacityVMSlots is the maximum number of VM slots assuming an empty datacenter.
// +kubebuilder:validation:Optional
TotalCapacityVMSlots int64 `json:"totalCapacityVmSlots,omitempty"`
}
Expand All @@ -57,14 +61,33 @@ type FlavorGroupCapacityStatus struct {
// +kubebuilder:validation:Optional
CommittedCapacity int64 `json:"committedCapacity,omitempty"`

// TotalCapacity is the total capacity of all eligible hosts in an empty-datacenter scenario.
// TotalCapacity is the installed capacity across all eligible hosts in an empty-datacenter
// scenario, expressed as raw resource amounts (bytes for memory, count for cores).
// +kubebuilder:validation:Optional
TotalCapacity map[string]resource.Quantity `json:"totalCapacity,omitempty"`

// TotalInstances is the total number of VM instances running on hypervisors in this AZ,
// derived from Hypervisor CRD Status.Instances (not filtered by flavor group).
// FreeCapacity is the sum of remaining resources across all candidate hosts for this
// group given current allocations. Because groups can share hosts, the sum across groups
// may exceed actual installed capacity — this field reflects per-group availability
// before any cross-group fairness split.
// +kubebuilder:validation:Optional
TotalInstances int64 `json:"totalInstances,omitempty"`
FreeCapacity map[string]resource.Quantity `json:"freeCapacity,omitempty"`

// ExclusivelyFreeCapacity is the share of remaining resources fairly attributed to this
// group by the round-robin capacity split. The sum across all groups for an AZ never
// exceeds actual installed capacity.
// +kubebuilder:validation:Optional
ExclusivelyFreeCapacity map[string]resource.Quantity `json:"exclusivelyFreeCapacity,omitempty"`

// RunningInstances is the number of VMs running in this (flavor group × AZ) whose
// flavor belongs to this group.
// +kubebuilder:validation:Optional
RunningInstances int64 `json:"runningInstances,omitempty"`

// RunningResources is the total resource consumption of running VMs in this
// (flavor group × AZ), keyed by resource type (e.g. "memory", "cores").
// +kubebuilder:validation:Optional
RunningResources map[string]resource.Quantity `json:"runningResources,omitempty"`

// LastReconcileAt is the timestamp of the last successful reconcile.
// +kubebuilder:validation:Optional
Expand All @@ -80,7 +103,7 @@ type FlavorGroupCapacityStatus struct {
// +kubebuilder:resource:scope=Cluster
// +kubebuilder:printcolumn:name="FlavorGroup",type="string",JSONPath=".spec.flavorGroup"
// +kubebuilder:printcolumn:name="AZ",type="string",JSONPath=".spec.availabilityZone"
// +kubebuilder:printcolumn:name="TotalInstances",type="integer",JSONPath=".status.totalInstances"
// +kubebuilder:printcolumn:name="Running",type="integer",JSONPath=".status.runningInstances"
// +kubebuilder:printcolumn:name="LastReconcile",type="date",JSONPath=".status.lastReconcileAt"
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"

Expand Down
21 changes: 21 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.

2 changes: 1 addition & 1 deletion cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ func main() {
setupLog.Error(err, "failed to register capacity monitor metrics, continuing without metrics")
}

capacityController := capacity.NewController(multiclusterClient, capacityConfig)
capacityController := capacity.NewController(multiclusterClient, capacityConfig, commitmentsVMSource)
if err := mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {
return capacityController.Start(ctx)
})); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ spec:
- jsonPath: .spec.availabilityZone
name: AZ
type: string
- jsonPath: .status.totalInstances
name: TotalInstances
- jsonPath: .status.runningInstances
name: Running
type: integer
- jsonPath: .status.lastReconcileAt
name: LastReconcile
Expand Down Expand Up @@ -135,12 +135,28 @@ spec:
- type
type: object
type: array
exclusivelyFreeCapacity:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: |-
ExclusivelyFreeCapacity is the share of remaining resources fairly attributed to this
group by the round-robin capacity split. The sum across all groups for an AZ never
exceeds actual installed capacity.
type: object
flavors:
description: Flavors holds per-flavor capacity data for all flavors
in the group.
items:
description: FlavorCapacityStatus holds per-flavor capacity numbers
for one (flavor group × AZ) pair.
description: |-
FlavorCapacityStatus holds per-flavor scheduler probe results for one (flavor group × AZ) pair.
These values come directly from scheduler probes and are independent of the cross-group
capacity split (see FreeCapacity and ExclusivelyFreeCapacity on the parent status).
"Placeable" means: if all remaining capacity in this AZ were used solely by this flavor,
this is how many would fit. It does not account for competing flavor groups.
properties:
flavorName:
description: FlavorName is the OpenStack flavor name (e.g. "hana-v2-small").
Expand All @@ -157,39 +173,64 @@ spec:
type: integer
totalCapacityHosts:
description: TotalCapacityHosts is the number of eligible hosts
in an empty-datacenter scenario.
assuming an empty datacenter.
format: int64
type: integer
totalCapacityVmSlots:
description: TotalCapacityVMSlots is the maximum number of VM
slots in an empty-datacenter scenario.
slots assuming an empty datacenter.
format: int64
type: integer
required:
- flavorName
type: object
type: array
freeCapacity:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: |-
FreeCapacity is the sum of remaining resources across all candidate hosts for this
group given current allocations. Because groups can share hosts, the sum across groups
may exceed actual installed capacity — this field reflects per-group availability
before any cross-group fairness split.
type: object
lastReconcileAt:
description: LastReconcileAt is the timestamp of the last successful
reconcile.
format: date-time
type: string
totalCapacity:
runningInstances:
description: |-
RunningInstances is the number of VMs running in this (flavor group × AZ) whose
flavor belongs to this group.
format: int64
type: integer
runningResources:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: TotalCapacity is the total capacity of all eligible hosts
in an empty-datacenter scenario.
description: |-
RunningResources is the total resource consumption of running VMs in this
(flavor group × AZ), keyed by resource type (e.g. "memory", "cores").
type: object
totalInstances:
totalCapacity:
additionalProperties:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
description: |-
TotalInstances is the total number of VM instances running on hypervisors in this AZ,
derived from Hypervisor CRD Status.Instances (not filtered by flavor group).
format: int64
type: integer
TotalCapacity is the installed capacity across all eligible hosts in an empty-datacenter
scenario, expressed as raw resource amounts (bytes for memory, count for cores).
type: object
type: object
required:
- spec
Expand Down
Loading