Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2025 SAP SE
// SPDX-License-Identifier: Apache-2.0

package filters

import (
"context"
"log/slog"

api "github.com/cobaltcore-dev/cortex/api/delegation/nova"
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
"github.com/cobaltcore-dev/cortex/internal/scheduling/lib"
)

type FilterProjectReservations struct {
lib.BaseStep[api.ExternalSchedulerRequest, lib.EmptyStepOpts]
}

func (s *FilterProjectReservations) Run(traceLog *slog.Logger, request api.ExternalSchedulerRequest) (*lib.StepResult, error) {
result := s.PrepareResult(request)
var reservations v1alpha1.ReservationList
ctx := context.Background()
if err := s.Client.List(ctx, &reservations); err != nil {
return nil, err
}

hostHasReservation := make(map[string]bool)

for _, reservation := range reservations.Items {
if reservation.Status.Phase != v1alpha1.ReservationStatusPhaseActive {
continue // Only consider active reservations.
}
if reservation.Spec.Scheduler.CortexNova == nil {
continue // Not handled by us.
}
// If the requested vm matches this reservation, free the resources.
if reservation.Spec.Scheduler.CortexNova.ProjectID == request.Spec.Data.ProjectID &&
reservation.Spec.Scheduler.CortexNova.FlavorName == request.Spec.Data.Flavor.Data.Name {
hostHasReservation[reservation.Status.Host] = true
break
}
}
for host := range result.Activations {
// Filter out hosts that do not have a matching reservation.
if _, ok := hostHasReservation[host]; !ok {
delete(result.Activations, host)
traceLog.Debug(
"removing host with unknown capacity",
"host", host,
)
}
}
return result, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2025 SAP SE
// SPDX-License-Identifier: Apache-2.0

package weighers

import (
"context"
"log/slog"

api "github.com/cobaltcore-dev/cortex/api/delegation/nova"
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
"github.com/cobaltcore-dev/cortex/internal/scheduling/lib"
)

type ProjectReservations struct {
lib.BaseStep[api.ExternalSchedulerRequest, lib.EmptyStepOpts]
}

func (s *ProjectReservations) Run(traceLog *slog.Logger, request api.ExternalSchedulerRequest) (*lib.StepResult, error) {
result := s.PrepareResult(request)
var reservations v1alpha1.ReservationList
ctx := context.Background()
if err := s.Client.List(ctx, &reservations); err != nil {
return nil, err
}

hostHasReservation := make(map[string]bool)

for _, reservation := range reservations.Items {
if reservation.Status.Phase != v1alpha1.ReservationStatusPhaseActive {
continue // Only consider active reservations.
}
if reservation.Spec.Scheduler.CortexNova == nil {
continue // Not handled by us.
}
// If the requested vm matches this reservation, free the resources.
if reservation.Spec.Scheduler.CortexNova.ProjectID == request.Spec.Data.ProjectID &&
reservation.Spec.Scheduler.CortexNova.FlavorName == request.Spec.Data.Flavor.Data.Name {
hostHasReservation[reservation.Status.Host] = true
break
}
}
for host := range result.Activations {
// Prefer hosts that have a matching reservation.
if _, ok := hostHasReservation[host]; ok {
result.Activations[host] = 1
continue
}
result.Activations[host] = -1
}
return result, nil
}