Files
capsule/pkg/runtime/workloads/resource_quantity.go
T
Oliver BählerandGitHub 65a4e19e02 feat: requests and limit policies (#2095)
* chore: save progress

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: requests and limit policies

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
2026-08-21 14:31:06 +02:00

63 lines
1.9 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
package workloads
import (
"fmt"
"strings"
inf "gopkg.in/inf.v0"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
)
// PodLevelResourceSupported reports whether Kubernetes permits the resource
// name in Pod-level resource requirements.
func PodLevelResourceSupported(name corev1.ResourceName) bool {
return name == corev1.ResourceCPU ||
name == corev1.ResourceMemory ||
strings.HasPrefix(string(name), corev1.ResourceHugePagesPrefix)
}
// RatioSupportedResource reports whether Capsule can safely calculate a
// limit-to-request ratio for the resource. CPU is rounded down to milliCPU;
// byte-based resources are rounded down to whole bytes.
func RatioSupportedResource(name corev1.ResourceName) bool {
return name == corev1.ResourceCPU ||
name == corev1.ResourceMemory ||
name == corev1.ResourceEphemeralStorage
}
// LimitForRatio calculates request * ratio without floating-point arithmetic.
// The result is rounded down so it never exceeds the configured maximum ratio.
func LimitForRatio(
name corev1.ResourceName,
request resource.Quantity,
ratio resource.Quantity,
) (resource.Quantity, error) {
if !RatioSupportedResource(name) {
return resource.Quantity{}, fmt.Errorf("ratio is not supported for resource %q", name)
}
if request.Sign() <= 0 {
return resource.Quantity{}, fmt.Errorf("request for resource %q must be greater than zero", name)
}
if ratio.Cmp(resource.MustParse("1")) < 0 {
return resource.Quantity{}, fmt.Errorf("ratio for resource %q must be greater than or equal to 1", name)
}
product := new(inf.Dec).Mul(request.AsDec(), ratio.AsDec())
scale := inf.Scale(0)
if name == corev1.ResourceCPU {
scale = inf.Scale(3)
}
rounded := new(inf.Dec).Round(product, scale, inf.RoundDown)
return *resource.NewDecimalQuantity(*rounded, request.Format), nil
}