diff options
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 48 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/play_test.go | 79 |
2 files changed, 126 insertions, 1 deletions
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 767589ead..5e6671231 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -7,6 +7,7 @@ import ( "math" "net" "regexp" + "runtime" "strconv" "strings" "time" @@ -22,6 +23,7 @@ import ( "github.com/containers/podman/v4/pkg/specgen" "github.com/containers/podman/v4/pkg/specgen/generate" "github.com/containers/podman/v4/pkg/util" + "github.com/docker/docker/pkg/system" "github.com/docker/go-units" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -712,8 +714,12 @@ func envVarValueResourceFieldRef(env v1.EnvVar, opts *CtrSpecGenOptions) (*strin divisor.Set(1) } + resources, err := getContainerResources(opts.Container) + if err != nil { + return nil, err + } + var value *resource.Quantity - resources := opts.Container.Resources resourceName := env.ValueFrom.ResourceFieldRef.Resource var isValidDivisor bool @@ -769,6 +775,46 @@ func isCPUDivisor(divisor resource.Quantity) bool { } } +func getContainerResources(container v1.Container) (v1.ResourceRequirements, error) { + result := v1.ResourceRequirements{ + Limits: v1.ResourceList{}, + Requests: v1.ResourceList{}, + } + + limits := container.Resources.Limits + requests := container.Resources.Requests + + if limits == nil || limits.Memory().IsZero() { + mi, err := system.ReadMemInfo() + if err != nil { + return result, err + } + result.Limits[v1.ResourceMemory] = *resource.NewQuantity(mi.MemTotal, resource.DecimalSI) + } else { + result.Limits[v1.ResourceMemory] = limits[v1.ResourceMemory] + } + + if limits == nil || limits.Cpu().IsZero() { + result.Limits[v1.ResourceCPU] = *resource.NewQuantity(int64(runtime.NumCPU()), resource.DecimalSI) + } else { + result.Limits[v1.ResourceCPU] = limits[v1.ResourceCPU] + } + + if requests == nil || requests.Memory().IsZero() { + result.Requests[v1.ResourceMemory] = result.Limits[v1.ResourceMemory] + } else { + result.Requests[v1.ResourceMemory] = requests[v1.ResourceMemory] + } + + if requests == nil || requests.Cpu().IsZero() { + result.Requests[v1.ResourceCPU] = result.Limits[v1.ResourceCPU] + } else { + result.Requests[v1.ResourceCPU] = requests[v1.ResourceCPU] + } + + return result, nil +} + // getPodPorts converts a slice of kube container descriptions to an // array of portmapping func getPodPorts(containers []v1.Container) []types.PortMapping { diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go index 282324310..6798fdb1b 100644 --- a/pkg/specgen/generate/kube/play_test.go +++ b/pkg/specgen/generate/kube/play_test.go @@ -6,10 +6,12 @@ import ( "io/ioutil" "math" "os" + "runtime" "strconv" "testing" "github.com/containers/common/pkg/secrets" + "github.com/docker/docker/pkg/system" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -193,6 +195,11 @@ func TestEnvVarValue(t *testing.T) { assert.NoError(t, err) defer os.RemoveAll(d) secretsManager := createSecrets(t, d) + stringNumCPUs := strconv.Itoa(runtime.NumCPU()) + + mi, err := system.ReadMemInfo() + assert.Nil(t, err) + stringMemTotal := strconv.FormatInt(mi.MemTotal, 10) tests := []struct { name string @@ -694,6 +701,78 @@ func TestEnvVarValue(t *testing.T) { true, strconv.Itoa(int(float64(cpuInt) / 0.001)), }, + { + "ResourceFieldRefNoLimitMemory", + v1.EnvVar{ + Name: "FOO", + ValueFrom: &v1.EnvVarSource{ + ResourceFieldRef: &v1.ResourceFieldSelector{ + Resource: "limits.memory", + }, + }, + }, + CtrSpecGenOptions{ + Container: v1.Container{ + Name: "test", + }, + }, + true, + stringMemTotal, + }, + { + "ResourceFieldRefNoRequestMemory", + v1.EnvVar{ + Name: "FOO", + ValueFrom: &v1.EnvVarSource{ + ResourceFieldRef: &v1.ResourceFieldSelector{ + Resource: "requests.memory", + }, + }, + }, + CtrSpecGenOptions{ + Container: v1.Container{ + Name: "test", + }, + }, + true, + stringMemTotal, + }, + { + "ResourceFieldRefNoLimitCPU", + v1.EnvVar{ + Name: "FOO", + ValueFrom: &v1.EnvVarSource{ + ResourceFieldRef: &v1.ResourceFieldSelector{ + Resource: "limits.cpu", + }, + }, + }, + CtrSpecGenOptions{ + Container: v1.Container{ + Name: "test", + }, + }, + true, + stringNumCPUs, + }, + { + "ResourceFieldRefNoRequestCPU", + v1.EnvVar{ + Name: "FOO", + ValueFrom: &v1.EnvVarSource{ + ResourceFieldRef: &v1.ResourceFieldSelector{ + Resource: "requests.cpu", + }, + }, + }, + CtrSpecGenOptions{ + Container: v1.Container{ + Name: "test", + }, + }, + true, + stringNumCPUs, + }, } for _, test := range tests { |