Skip to content

Commit d7ef3fa

Browse files
committed
Add filter and weigher for project reservations
1 parent f80107f commit d7ef3fa

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2025 SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package filters
5+
6+
import (
7+
"context"
8+
"log/slog"
9+
10+
api "github.com/cobaltcore-dev/cortex/api/delegation/nova"
11+
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
12+
"github.com/cobaltcore-dev/cortex/internal/scheduling/lib"
13+
)
14+
15+
type FilterProjectReservations struct {
16+
lib.BaseStep[api.ExternalSchedulerRequest, lib.EmptyStepOpts]
17+
}
18+
19+
func (s *FilterProjectReservations) Run(traceLog *slog.Logger, request api.ExternalSchedulerRequest) (*lib.StepResult, error) {
20+
result := s.PrepareResult(request)
21+
var reservations v1alpha1.ReservationList
22+
ctx := context.Background()
23+
if err := s.Client.List(ctx, &reservations); err != nil {
24+
return nil, err
25+
}
26+
27+
hostHasReservation := make(map[string]bool)
28+
29+
for _, reservation := range reservations.Items {
30+
if reservation.Status.Phase != v1alpha1.ReservationStatusPhaseActive {
31+
continue // Only consider active reservations.
32+
}
33+
if reservation.Spec.Scheduler.CortexNova == nil {
34+
continue // Not handled by us.
35+
}
36+
// If the requested vm matches this reservation, free the resources.
37+
if reservation.Spec.Scheduler.CortexNova.ProjectID == request.Spec.Data.ProjectID &&
38+
reservation.Spec.Scheduler.CortexNova.FlavorName == request.Spec.Data.Flavor.Data.Name {
39+
hostHasReservation[reservation.Status.Host] = true
40+
break
41+
}
42+
}
43+
for host := range result.Activations {
44+
// Filter out hosts that do not have a matching reservation.
45+
if _, ok := hostHasReservation[host]; !ok {
46+
delete(result.Activations, host)
47+
traceLog.Debug(
48+
"removing host with unknown capacity",
49+
"host", host,
50+
)
51+
}
52+
}
53+
return result, nil
54+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2025 SAP SE
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package weighers
5+
6+
import (
7+
"context"
8+
"log/slog"
9+
10+
api "github.com/cobaltcore-dev/cortex/api/delegation/nova"
11+
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
12+
"github.com/cobaltcore-dev/cortex/internal/scheduling/lib"
13+
)
14+
15+
type ProjectReservations struct {
16+
lib.BaseStep[api.ExternalSchedulerRequest, lib.EmptyStepOpts]
17+
}
18+
19+
func (s *ProjectReservations) Run(traceLog *slog.Logger, request api.ExternalSchedulerRequest) (*lib.StepResult, error) {
20+
result := s.PrepareResult(request)
21+
var reservations v1alpha1.ReservationList
22+
ctx := context.Background()
23+
if err := s.Client.List(ctx, &reservations); err != nil {
24+
return nil, err
25+
}
26+
27+
hostHasReservation := make(map[string]bool)
28+
29+
for _, reservation := range reservations.Items {
30+
if reservation.Status.Phase != v1alpha1.ReservationStatusPhaseActive {
31+
continue // Only consider active reservations.
32+
}
33+
if reservation.Spec.Scheduler.CortexNova == nil {
34+
continue // Not handled by us.
35+
}
36+
// If the requested vm matches this reservation, free the resources.
37+
if reservation.Spec.Scheduler.CortexNova.ProjectID == request.Spec.Data.ProjectID &&
38+
reservation.Spec.Scheduler.CortexNova.FlavorName == request.Spec.Data.Flavor.Data.Name {
39+
hostHasReservation[reservation.Status.Host] = true
40+
break
41+
}
42+
}
43+
for host := range result.Activations {
44+
// Prefer hosts that have a matching reservation.
45+
if _, ok := hostHasReservation[host]; ok {
46+
result.Activations[host] = 1
47+
continue
48+
}
49+
result.Activations[host] = -1
50+
}
51+
return result, nil
52+
}

0 commit comments

Comments
 (0)