summaryrefslogtreecommitdiff
path: root/pkg/specgen/generate/kube/kube.go
diff options
context:
space:
mode:
authorYaron Dayagi <ydayagi@redhat.com>2022-02-02 21:02:22 +0200
committerYaron Dayagi <ydayagi@redhat.com>2022-02-02 22:34:54 +0200
commit5468757ad7b45c7fa07ff0a586e7a96d8a6ec428 (patch)
tree6b0f074facf9b311f0efc15897ce5fa59cac2317 /pkg/specgen/generate/kube/kube.go
parent21a8ee904465b1aa54ce5fa6e3bbf93519ca0442 (diff)
downloadpodman-5468757ad7b45c7fa07ff0a586e7a96d8a6ec428.tar.gz
podman-5468757ad7b45c7fa07ff0a586e7a96d8a6ec428.tar.bz2
podman-5468757ad7b45c7fa07ff0a586e7a96d8a6ec428.zip
play kube envVar.valueFrom.resourceFieldRef
add support for env vars values from container resources see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core relates to issue https://github.com/containers/podman/issues/12756 Signed-off-by: Yaron Dayagi <ydayagi@redhat.com>
Diffstat (limited to 'pkg/specgen/generate/kube/kube.go')
-rw-r--r--pkg/specgen/generate/kube/kube.go69
1 files changed, 69 insertions, 0 deletions
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index beaec1135..475401016 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -4,8 +4,10 @@ import (
"context"
"encoding/json"
"fmt"
+ "math"
"net"
"regexp"
+ "strconv"
"strings"
"time"
@@ -650,6 +652,10 @@ func envVarValue(env v1.EnvVar, opts *CtrSpecGenOptions) (*string, error) {
if env.ValueFrom.FieldRef != nil {
return envVarValueFieldRef(env, opts)
}
+
+ if env.ValueFrom.ResourceFieldRef != nil {
+ return envVarValueResourceFieldRef(env, opts)
+ }
}
return &env.Value, nil
@@ -688,6 +694,69 @@ func envVarValueFieldRef(env v1.EnvVar, opts *CtrSpecGenOptions) (*string, error
)
}
+func envVarValueResourceFieldRef(env v1.EnvVar, opts *CtrSpecGenOptions) (*string, error) {
+ divisor := env.ValueFrom.ResourceFieldRef.Divisor
+ if divisor.IsZero() { // divisor not set, use default
+ divisor.Set(1)
+ }
+
+ var value *resource.Quantity
+ resources := opts.Container.Resources
+ resourceName := env.ValueFrom.ResourceFieldRef.Resource
+ var isValidDivisor bool
+
+ switch resourceName {
+ case "limits.memory":
+ value = resources.Limits.Memory()
+ isValidDivisor = isMemoryDivisor(divisor)
+ case "limits.cpu":
+ value = resources.Limits.Cpu()
+ isValidDivisor = isCPUDivisor(divisor)
+ case "requests.memory":
+ value = resources.Requests.Memory()
+ isValidDivisor = isMemoryDivisor(divisor)
+ case "requests.cpu":
+ value = resources.Requests.Cpu()
+ isValidDivisor = isCPUDivisor(divisor)
+ default:
+ return nil, errors.Errorf(
+ "Can not set env %v. Reason: resource %v is either not valid or not supported",
+ env.Name, resourceName,
+ )
+ }
+
+ if !isValidDivisor {
+ return nil, errors.Errorf(
+ "Can not set env %s. Reason: divisor value %s is not valid",
+ env.Name, divisor.String(),
+ )
+ }
+
+ // k8s rounds up the result to the nearest integer
+ intValue := int(math.Ceil(value.AsApproximateFloat64() / divisor.AsApproximateFloat64()))
+ stringValue := strconv.Itoa(intValue)
+
+ return &stringValue, nil
+}
+
+func isMemoryDivisor(divisor resource.Quantity) bool {
+ switch divisor.String() {
+ case "1", "1k", "1M", "1G", "1T", "1P", "1E", "1Ki", "1Mi", "1Gi", "1Ti", "1Pi", "1Ei":
+ return true
+ default:
+ return false
+ }
+}
+
+func isCPUDivisor(divisor resource.Quantity) bool {
+ switch divisor.String() {
+ case "1", "1m":
+ return true
+ default:
+ return false
+ }
+}
+
// getPodPorts converts a slice of kube container descriptions to an
// array of portmapping
func getPodPorts(containers []v1.Container) []types.PortMapping {