Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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