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
5 changes: 3 additions & 2 deletions api/v1alpha1/reservation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package v1alpha1

import (
hv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -44,7 +45,7 @@ type CommittedResourceAllocation struct {

// Resources consumed by this instance.
// +kubebuilder:validation:Required
Resources map[string]resource.Quantity `json:"resources"`
Resources map[hv1.ResourceName]resource.Quantity `json:"resources"`
}

// CommittedResourceReservationSpec defines the spec fields specific to committed resource reservations.
Expand Down Expand Up @@ -99,7 +100,7 @@ type ReservationSpec struct {

// Resources to reserve for this instance.
// +kubebuilder:validation:Optional
Resources map[string]resource.Quantity `json:"resources,omitempty"`
Resources map[hv1.ResourceName]resource.Quantity `json:"resources,omitempty"`

// StartTime is the time when the reservation becomes active.
// +kubebuilder:validation:Optional
Expand Down
5 changes: 3 additions & 2 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 go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/cobaltcore-dev/cortex
go 1.26

require (
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260313132145-05f22f69d9fd
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260316070528-80f53bbce409
github.com/go-gorp/gorp v2.2.0+incompatible
github.com/gophercloud/gophercloud/v2 v2.11.1
github.com/ironcore-dev/ironcore v0.2.4
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260313132145-05f22f69d9fd h1:IzxramZZRC/9FtQQqpbgf8KIpH4soD9cliCFs2+zPd4=
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260313132145-05f22f69d9fd/go.mod h1:b0KmJdxvRI8UXlGe8cRm5BD8Tm2WhF7zSKMSIRGyVL4=
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260316070528-80f53bbce409 h1:hiTMLk6JZsmFF+ECBJnOVcDAw2d+iCXhk4eDvVpYHYM=
github.com/cobaltcore-dev/openstack-hypervisor-operator v0.0.0-20260316070528-80f53bbce409/go.mod h1:b0KmJdxvRI8UXlGe8cRm5BD8Tm2WhF7zSKMSIRGyVL4=
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("128"),
"memory": resource.MustParse("512Gi"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("128"),
hv1.ResourceMemory: resource.MustParse("512Gi"),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse("64"),
"memory": resource.MustParse("256Gi"),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("64"),
hv1.ResourceMemory: resource.MustParse("256Gi"),
},
Traits: []string{},
},
Expand Down Expand Up @@ -148,13 +148,13 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("256"),
"memory": resource.MustParse("1Ti"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("256"),
hv1.ResourceMemory: resource.MustParse("1Ti"),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse("128"),
"memory": resource.MustParse("512Gi"),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("128"),
hv1.ResourceMemory: resource.MustParse("512Gi"),
},
Traits: []string{
"CUSTOM_HW_SAPPHIRE_RAPIDS",
Expand Down Expand Up @@ -209,13 +209,13 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("64"),
"memory": resource.MustParse("256Gi"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("64"),
hv1.ResourceMemory: resource.MustParse("256Gi"),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse("32"),
"memory": resource.MustParse("128Gi"),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("32"),
hv1.ResourceMemory: resource.MustParse("128Gi"),
},
Traits: []string{
"CUSTOM_DECOMMISSIONING",
Expand Down Expand Up @@ -255,13 +255,13 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("100"),
"memory": resource.MustParse("200Gi"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("100"),
hv1.ResourceMemory: resource.MustParse("200Gi"),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse("50"),
"memory": resource.MustParse("100Gi"),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("50"),
hv1.ResourceMemory: resource.MustParse("100Gi"),
},
Traits: []string{},
},
Expand All @@ -274,13 +274,13 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("200"),
"memory": resource.MustParse("400Gi"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("200"),
hv1.ResourceMemory: resource.MustParse("400Gi"),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse("150"),
"memory": resource.MustParse("300Gi"),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("150"),
hv1.ResourceMemory: resource.MustParse("300Gi"),
},
Traits: []string{"CUSTOM_HW_SAPPHIRE_RAPIDS"},
},
Expand Down Expand Up @@ -332,9 +332,9 @@ func TestKVMResourceCapacityKPI_Collect(t *testing.T) {
},
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse("96"),
"memory": resource.MustParse("384Gi"),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse("96"),
hv1.ResourceMemory: resource.MustParse("384Gi"),
},
// No Allocation field - simulating missing data
Allocation: nil,
Expand Down
24 changes: 12 additions & 12 deletions internal/scheduling/nova/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ func newHypervisor(name, cpuCap, cpuAlloc, memCap, memAlloc string) *hv1.Hypervi
Name: name,
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse(cpuCap),
"memory": resource.MustParse(memCap),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpuCap),
hv1.ResourceMemory: resource.MustParse(memCap),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse(cpuAlloc),
"memory": resource.MustParse(memAlloc),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpuAlloc),
hv1.ResourceMemory: resource.MustParse(memAlloc),
},
},
}
Expand All @@ -68,9 +68,9 @@ func newCommittedReservation(name, targetHost, observedHost, projectID, flavorNa
Spec: v1alpha1.ReservationSpec{
Type: v1alpha1.ReservationTypeCommittedResource,
TargetHost: targetHost,
Resources: map[string]resource.Quantity{
"cpu": resource.MustParse(cpu),
"memory": resource.MustParse(memory),
Resources: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpu),
hv1.ResourceMemory: resource.MustParse(memory),
},
CommittedResourceReservation: &v1alpha1.CommittedResourceReservationSpec{
ProjectID: projectID,
Expand Down Expand Up @@ -100,9 +100,9 @@ func newFailoverReservation(name, targetHost, resourceGroup, cpu, memory string,
Spec: v1alpha1.ReservationSpec{
Type: v1alpha1.ReservationTypeFailover,
TargetHost: targetHost,
Resources: map[string]resource.Quantity{
"cpu": resource.MustParse(cpu),
"memory": resource.MustParse(memory),
Resources: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpu),
hv1.ResourceMemory: resource.MustParse(memory),
},
FailoverReservation: &v1alpha1.FailoverReservationSpec{
ResourceGroup: resourceGroup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (s *FilterHasEnoughCapacity) Run(traceLog *slog.Logger, request api.Externa
result := s.IncludeAllHostsFromRequest(request)

// This map holds the free resources per host.
freeResourcesByHost := make(map[string]map[string]resource.Quantity)
freeResourcesByHost := make(map[string]map[hv1.ResourceName]resource.Quantity)

// The hypervisor resource auto-discovers its current utilization.
// We can use the hypervisor status to calculate the total capacity
Expand Down Expand Up @@ -145,7 +145,7 @@ func (s *FilterHasEnoughCapacity) Run(traceLog *slog.Logger, request api.Externa

// For CR reservations with allocations, calculate remaining (unallocated) resources to block.
// This prevents double-blocking of resources already consumed by running instances.
var resourcesToBlock map[string]resource.Quantity
var resourcesToBlock map[hv1.ResourceName]resource.Quantity
if reservation.Spec.Type == v1alpha1.ReservationTypeCommittedResource &&
// if the reservation is not being migrated, block only unused resources
reservation.Spec.TargetHost == reservation.Status.Host &&
Expand All @@ -154,7 +154,7 @@ func (s *FilterHasEnoughCapacity) Run(traceLog *slog.Logger, request api.Externa
len(reservation.Spec.CommittedResourceReservation.Allocations) > 0 &&
len(reservation.Status.CommittedResourceReservation.Allocations) > 0 {
// Start with full reservation resources
resourcesToBlock = make(map[string]resource.Quantity)
resourcesToBlock = make(map[hv1.ResourceName]resource.Quantity)
for k, v := range reservation.Spec.Resources {
resourcesToBlock[k] = v.DeepCopy()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ func newHypervisor(name, cpuCap, cpuAlloc, memCap, memAlloc string) *hv1.Hypervi
Name: name,
},
Status: hv1.HypervisorStatus{
Capacity: map[string]resource.Quantity{
"cpu": resource.MustParse(cpuCap),
"memory": resource.MustParse(memCap),
Capacity: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpuCap),
hv1.ResourceMemory: resource.MustParse(memCap),
},
Allocation: map[string]resource.Quantity{
"cpu": resource.MustParse(cpuAlloc),
"memory": resource.MustParse(memAlloc),
Allocation: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpuAlloc),
hv1.ResourceMemory: resource.MustParse(memAlloc),
},
},
}
Expand All @@ -64,9 +64,9 @@ func newCommittedReservation(
Spec: v1alpha1.ReservationSpec{
Type: v1alpha1.ReservationTypeCommittedResource,
TargetHost: targetHost,
Resources: map[string]resource.Quantity{
"cpu": resource.MustParse(cpu),
"memory": resource.MustParse(memory),
Resources: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpu),
hv1.ResourceMemory: resource.MustParse(memory),
},
CommittedResourceReservation: &v1alpha1.CommittedResourceReservationSpec{
ProjectID: projectID,
Expand Down Expand Up @@ -104,9 +104,9 @@ func newFailoverReservation(name, targetHost, cpu, memory string, allocations ma
Spec: v1alpha1.ReservationSpec{
Type: v1alpha1.ReservationTypeFailover,
TargetHost: targetHost,
Resources: map[string]resource.Quantity{
"cpu": resource.MustParse(cpu),
"memory": resource.MustParse(memory),
Resources: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(cpu),
hv1.ResourceMemory: resource.MustParse(memory),
},
FailoverReservation: &v1alpha1.FailoverReservationSpec{
ResourceGroup: "m1.large",
Expand Down Expand Up @@ -150,9 +150,9 @@ func crSpecAllocs(vms ...crVmAlloc) map[string]v1alpha1.CommittedResourceAllocat
for _, v := range vms {
allocs[v.uuid] = v1alpha1.CommittedResourceAllocation{
CreationTimestamp: metav1.Now(),
Resources: map[string]resource.Quantity{
"cpu": resource.MustParse(v.cpu),
"memory": resource.MustParse(v.mem),
Resources: map[hv1.ResourceName]resource.Quantity{
hv1.ResourceCPU: resource.MustParse(v.cpu),
hv1.ResourceMemory: resource.MustParse(v.mem),
},
}
}
Expand Down
21 changes: 10 additions & 11 deletions internal/scheduling/nova/plugins/weighers/kvm_binpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
api "github.com/cobaltcore-dev/cortex/api/external/nova"
"github.com/cobaltcore-dev/cortex/internal/scheduling/lib"
hv1 "github.com/cobaltcore-dev/openstack-hypervisor-operator/api/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
)

Expand All @@ -23,17 +22,17 @@ type KVMBinpackStepOpts struct {
// node's resource utilizations after placing the VM.
// If a resource is not specified, is ignored in the score calculation
// (equivalent to a weight of 0).
ResourceWeights map[corev1.ResourceName]float64 `json:"resourceWeights"`
ResourceWeights map[hv1.ResourceName]float64 `json:"resourceWeights"`
}

// Validate the options to ensure they are correct before running the weigher.
func (o KVMBinpackStepOpts) Validate() error {
if len(o.ResourceWeights) == 0 {
return errors.New("at least one resource weight must be specified")
}
supportedResources := []corev1.ResourceName{
corev1.ResourceMemory,
corev1.ResourceCPU,
supportedResources := []hv1.ResourceName{
hv1.ResourceMemory,
hv1.ResourceCPU,
}
for resourceName, value := range o.ResourceWeights {
if !slices.Contains(supportedResources, resourceName) {
Expand Down Expand Up @@ -94,7 +93,7 @@ func (s *KVMBinpackStep) Run(traceLog *slog.Logger, request api.ExternalSchedule
var totalWeightedUtilization, totalWeight float64

for resourceName, weight := range s.Options.ResourceWeights {
capacity, ok := hv.Status.Capacity[resourceName.String()]
capacity, ok := hv.Status.Capacity[resourceName]
if !ok {
traceLog.Warn("no capacity in status, skipping",
"host", host, "resource", resourceName)
Expand All @@ -105,7 +104,7 @@ func (s *KVMBinpackStep) Run(traceLog *slog.Logger, request api.ExternalSchedule
"host", host, "resource", resourceName)
continue
}
allocation, ok := hv.Status.Allocation[resourceName.String()]
allocation, ok := hv.Status.Allocation[resourceName]
if !ok {
traceLog.Warn("no allocation in status, skipping",
"host", host, "resource", resourceName)
Expand Down Expand Up @@ -138,15 +137,15 @@ func (s *KVMBinpackStep) Run(traceLog *slog.Logger, request api.ExternalSchedule
}

// calcVMResources calculates the total resource requests for the VM to be scheduled.
func (s *KVMBinpackStep) calcVMResources(req api.ExternalSchedulerRequest) map[corev1.ResourceName]resource.Quantity {
resources := make(map[corev1.ResourceName]resource.Quantity)
func (s *KVMBinpackStep) calcVMResources(req api.ExternalSchedulerRequest) map[hv1.ResourceName]resource.Quantity {
resources := make(map[hv1.ResourceName]resource.Quantity)
resourcesMemBytes := int64(req.Spec.Data.Flavor.Data.MemoryMB * 1_000_000) //nolint:gosec // memory values are bounded by Nova
resourcesMemBytes *= int64(req.Spec.Data.NumInstances) //nolint:gosec // instance count is bounded by Nova
resources[corev1.ResourceMemory] = *resource.
resources[hv1.ResourceMemory] = *resource.
NewQuantity(resourcesMemBytes, resource.DecimalSI)
resourcesCPU := int64(req.Spec.Data.Flavor.Data.VCPUs) //nolint:gosec // vCPU values are bounded by Nova
resourcesCPU *= int64(req.Spec.Data.NumInstances) //nolint:gosec // instance count is bounded by Nova
resources[corev1.ResourceCPU] = *resource.
resources[hv1.ResourceCPU] = *resource.
NewQuantity(resourcesCPU, resource.DecimalSI)
return resources
}
Expand Down
Loading