From 73cf7357414eadcb56c6cebc5e9e9d8ff5b22df9 Mon Sep 17 00:00:00 2001 From: Gerrit Date: Mon, 16 Sep 2024 10:25:43 +0200 Subject: [PATCH] Add `Allocatable` and `RemainingReservations` to partition capacity. --- .../internal/service/partition-service.go | 9 ++- .../service/partition-service_test.go | 62 +++++++++++-------- .../internal/service/v1/partition.go | 5 ++ spec/metal-api.json | 10 +++ 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/cmd/metal-api/internal/service/partition-service.go b/cmd/metal-api/internal/service/partition-service.go index f783ac4ae..b0573768f 100644 --- a/cmd/metal-api/internal/service/partition-service.go +++ b/cmd/metal-api/internal/service/partition-service.go @@ -446,7 +446,8 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque case m.Allocation != nil: cap.Allocated++ case m.Waiting && !m.PreAllocated && m.State.Value == metal.AvailableState && ec.Liveliness == metal.MachineLivelinessAlive: - // the free machine count considers the same aspects as the query for electing the machine candidate! + // the free and allocatable machine counts consider the same aspects as the query for electing the machine candidate! + cap.Allocatable++ cap.Free++ default: cap.Unavailable++ @@ -469,8 +470,6 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque pc := pc for _, cap := range pc.ServerCapacities { - cap := cap - size := sizesByID[cap.Size] for _, reservation := range size.Reservations.ForPartition(pc.ID) { @@ -483,6 +482,10 @@ func (r *partitionResource) calcPartitionCapacity(pcr *v1.PartitionCapacityReque } } + for _, cap := range pc.ServerCapacities { + cap.RemainingReservations = cap.Reservations - cap.UsedReservations + } + res = append(res, *pc) } diff --git a/cmd/metal-api/internal/service/partition-service_test.go b/cmd/metal-api/internal/service/partition-service_test.go index fd6b15a82..943492d95 100644 --- a/cmd/metal-api/internal/service/partition-service_test.go +++ b/cmd/metal-api/internal/service/partition-service_test.go @@ -407,10 +407,11 @@ func TestPartitionCapacity(t *testing.T) { }, ServerCapacities: v1.ServerCapacities{ { - Size: "size-a", - Total: 1, - Waiting: 1, - Free: 1, + Size: "size-a", + Total: 1, + Waiting: 1, + Free: 1, + Allocatable: 1, }, }, }, @@ -457,12 +458,13 @@ func TestPartitionCapacity(t *testing.T) { }, ServerCapacities: v1.ServerCapacities{ { - Size: "size-a", - Total: 2, - Allocated: 1, - Waiting: 1, - PhonedHome: 1, - Free: 1, + Size: "size-a", + Total: 2, + Allocated: 1, + Waiting: 1, + PhonedHome: 1, + Free: 1, + Allocatable: 1, }, }, }, @@ -483,10 +485,11 @@ func TestPartitionCapacity(t *testing.T) { }, ServerCapacities: v1.ServerCapacities{ { - Size: "size-a", - Total: 1, - Waiting: 1, - Free: 1, + Size: "size-a", + Total: 1, + Waiting: 1, + Free: 1, + Allocatable: 1, }, }, }, @@ -539,12 +542,14 @@ func TestPartitionCapacity(t *testing.T) { }, ServerCapacities: v1.ServerCapacities{ { - Size: "size-a", - Total: 1, - Waiting: 1, - Free: 0, - Reservations: 1, - UsedReservations: 0, + Size: "size-a", + Total: 1, + Waiting: 1, + Free: 0, + Allocatable: 1, + Reservations: 1, + UsedReservations: 0, + RemainingReservations: 1, }, }, }, @@ -578,12 +583,14 @@ func TestPartitionCapacity(t *testing.T) { }, ServerCapacities: v1.ServerCapacities{ { - Size: "size-a", - Total: 1, - Waiting: 1, - Free: 0, - Reservations: 3, - UsedReservations: 0, + Size: "size-a", + Total: 1, + Waiting: 1, + Free: 0, + Allocatable: 1, + Reservations: 3, + UsedReservations: 0, + RemainingReservations: 3, }, }, }, @@ -619,6 +626,7 @@ func TestPartitionCapacity(t *testing.T) { Allocated: 2, Waiting: 1, Free: 1, + Allocatable: 1, Reservations: 2, UsedReservations: 2, PhonedHome: 2, @@ -657,6 +665,7 @@ func TestPartitionCapacity(t *testing.T) { Allocated: 2, Waiting: 1, Free: 1, + Allocatable: 1, Reservations: 1, UsedReservations: 1, PhonedHome: 2, @@ -700,6 +709,7 @@ func TestPartitionCapacity(t *testing.T) { Allocated: 2, Waiting: 1, Free: 1, + Allocatable: 1, Reservations: 2, UsedReservations: 2, PhonedHome: 2, diff --git a/cmd/metal-api/internal/service/v1/partition.go b/cmd/metal-api/internal/service/v1/partition.go index fc9b8c3a8..f3304241f 100644 --- a/cmd/metal-api/internal/service/v1/partition.go +++ b/cmd/metal-api/internal/service/v1/partition.go @@ -69,6 +69,9 @@ type ServerCapacity struct { // Allocated is the amount of machines that are currently allocated. Allocated int `json:"allocated,omitempty" description:"allocated machines"` + // Allocatable is the amount of machines in a partition is the amount of machines that can be allocated. + // Effectively this is the amount of waiting machines minus the machines that are unavailable due to machine state or un-allocatable. Size reservations are not considered in this count. + Allocatable int `json:"allocatable,omitempty" description:"free machines with this size, size reservations are not considered"` // Free is the amount of machines in a partition that can be freely allocated at any given moment by a project. // Effectively this is the amount of waiting machines minus the machines that are unavailable due to machine state or un-allocatable due to size reservations. Free int `json:"free,omitempty" description:"free machines with this size (freely allocatable)"` @@ -85,6 +88,8 @@ type ServerCapacity struct { Reservations int `json:"reservations,omitempty" description:"the amount of reservations for this size"` // UsedReservations is the amount of reservations already used up for this size. UsedReservations int `json:"usedreservations,omitempty" description:"the amount of used reservations for this size"` + // RemainingReservations is the amount of reservations remaining for this size. + RemainingReservations int `json:"remainingreservations,omitempty" description:"the amount of unused / remaining / open reservations for this size"` } func NewPartitionResponse(p *metal.Partition) *PartitionResponse { diff --git a/spec/metal-api.json b/spec/metal-api.json index b67cf2766..a86251726 100644 --- a/spec/metal-api.json +++ b/spec/metal-api.json @@ -4399,6 +4399,11 @@ }, "v1.ServerCapacity": { "properties": { + "allocatable": { + "description": "free machines with this size, size reservations are not considered", + "format": "int32", + "type": "integer" + }, "allocated": { "description": "allocated machines", "format": "int32", @@ -4438,6 +4443,11 @@ "format": "int32", "type": "integer" }, + "remainingreservations": { + "description": "the amount of unused / remaining / open reservations for this size", + "format": "int32", + "type": "integer" + }, "reservations": { "description": "the amount of reservations for this size", "format": "int32",