From ad4e7654eaf8dc7d684fefbe7e4d0884ce5695ad Mon Sep 17 00:00:00 2001 From: Nikhil <46481850+Nikateen@users.noreply.github.com> Date: Mon, 9 Mar 2026 19:53:31 +0530 Subject: [PATCH] Remove deprecated PodRequestsAndLimits from kubectl/pkg/util/resource (#137442) * Remove deprecated PodRequestsAndLimits from kubectl/pkg/util/resource The PodRequestsAndLimits function was deprecated in favor of k8s.io/component-helpers/resource.PodRequests and PodLimits, which also support pod-level resources. There are no remaining consumers in kubectl. This removal includes the unexported helpers: podRequests, podLimits, determineContainerReqs, max, addResourceList, and maxResourceList. * Remove test for deleted max helper function Kubernetes-commit: e026a9482a167bec567f16f87efe9df4c09dbb06 --- pkg/util/resource/resource.go | 168 ----------------------------- pkg/util/resource/resource_test.go | 79 -------------- 2 files changed, 247 deletions(-) diff --git a/pkg/util/resource/resource.go b/pkg/util/resource/resource.go index f769eb0f4..bf0dd08ec 100644 --- a/pkg/util/resource/resource.go +++ b/pkg/util/resource/resource.go @@ -25,176 +25,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/sets" - helpers "k8s.io/component-helpers/resource" ) -// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all -// containers of the pod. If pod overhead is non-nil, the pod overhead is added to the -// total container resource requests and to the total container limits which have a -// non-zero quantity. -// -// Deprecated: Use k8s.io/component-helpers/resource.PodRequests and -// k8s.io/component-helpers/resource.PodLimits instead, which also support -// pod-level resources. -func PodRequestsAndLimits(pod *corev1.Pod) (reqs, limits corev1.ResourceList) { - return podRequests(pod), podLimits(pod) -} - -// podRequests is a simplified form of PodRequests from k8s.io/kubernetes/pkg/api/v1/resource that doesn't check -// feature gate enablement and avoids adding a dependency on k8s.io/kubernetes/pkg/apis/core/v1 for kubectl. -func podRequests(pod *corev1.Pod) corev1.ResourceList { - // attempt to reuse the maps if passed, or allocate otherwise - reqs := corev1.ResourceList{} - - containerStatuses := map[string]*corev1.ContainerStatus{} - for i := range pod.Status.ContainerStatuses { - containerStatuses[pod.Status.ContainerStatuses[i].Name] = &pod.Status.ContainerStatuses[i] - } - for i := range pod.Status.InitContainerStatuses { - containerStatuses[pod.Status.InitContainerStatuses[i].Name] = &pod.Status.InitContainerStatuses[i] - } - - for _, container := range pod.Spec.Containers { - containerReqs := container.Resources.Requests - cs, found := containerStatuses[container.Name] - if found && cs.Resources != nil { - containerReqs = determineContainerReqs(pod, &container, cs) - } - addResourceList(reqs, containerReqs) - } - - restartableInitContainerReqs := corev1.ResourceList{} - initContainerReqs := corev1.ResourceList{} - - for _, container := range pod.Spec.InitContainers { - containerReqs := container.Resources.Requests - - if container.RestartPolicy != nil && *container.RestartPolicy == corev1.ContainerRestartPolicyAlways { - cs, found := containerStatuses[container.Name] - if found && cs.Resources != nil { - containerReqs = determineContainerReqs(pod, &container, cs) - } - // and add them to the resulting cumulative container requests - addResourceList(reqs, containerReqs) - - // track our cumulative restartable init container resources - addResourceList(restartableInitContainerReqs, containerReqs) - containerReqs = restartableInitContainerReqs - } else { - tmp := corev1.ResourceList{} - addResourceList(tmp, containerReqs) - addResourceList(tmp, restartableInitContainerReqs) - containerReqs = tmp - } - maxResourceList(initContainerReqs, containerReqs) - } - - maxResourceList(reqs, initContainerReqs) - - // Add overhead for running a pod to the sum of requests if requested: - if pod.Spec.Overhead != nil { - addResourceList(reqs, pod.Spec.Overhead) - } - - return reqs -} - -// podLimits is a simplified form of PodLimits from k8s.io/kubernetes/pkg/api/v1/resource that doesn't check -// feature gate enablement and avoids adding a dependency on k8s.io/kubernetes/pkg/apis/core/v1 for kubectl. -func podLimits(pod *corev1.Pod) corev1.ResourceList { - limits := corev1.ResourceList{} - - for _, container := range pod.Spec.Containers { - addResourceList(limits, container.Resources.Limits) - } - - restartableInitContainerLimits := corev1.ResourceList{} - initContainerLimits := corev1.ResourceList{} - - for _, container := range pod.Spec.InitContainers { - containerLimits := container.Resources.Limits - // Is the init container marked as a restartable init container? - if container.RestartPolicy != nil && *container.RestartPolicy == corev1.ContainerRestartPolicyAlways { - addResourceList(limits, containerLimits) - - // track our cumulative restartable init container resources - addResourceList(restartableInitContainerLimits, containerLimits) - containerLimits = restartableInitContainerLimits - } else { - tmp := corev1.ResourceList{} - addResourceList(tmp, containerLimits) - addResourceList(tmp, restartableInitContainerLimits) - containerLimits = tmp - } - - maxResourceList(initContainerLimits, containerLimits) - } - - maxResourceList(limits, initContainerLimits) - - // Add overhead to non-zero limits if requested: - if pod.Spec.Overhead != nil { - for name, quantity := range pod.Spec.Overhead { - if value, ok := limits[name]; ok && !value.IsZero() { - value.Add(quantity) - limits[name] = value - } - } - } - - return limits -} - -// determineContainerReqs will return a copy of the container requests based on if resizing is feasible or not. -func determineContainerReqs(pod *corev1.Pod, container *corev1.Container, cs *corev1.ContainerStatus) corev1.ResourceList { - if helpers.IsPodResizeInfeasible(pod) { - return max(cs.Resources.Requests, cs.AllocatedResources) - } - return max(container.Resources.Requests, cs.Resources.Requests, cs.AllocatedResources) -} - -// max returns the result of max(a, b...) for each named resource and is only used if we can't -// accumulate into an existing resource list -func max(a corev1.ResourceList, b ...corev1.ResourceList) corev1.ResourceList { - var result corev1.ResourceList - if a != nil { - result = a.DeepCopy() - } else { - result = corev1.ResourceList{} - } - for _, other := range b { - maxResourceList(result, other) - } - return result -} - -// addResourceList adds the resources in newList to list -func addResourceList(list, new corev1.ResourceList) { - for name, quantity := range new { - if value, ok := list[name]; !ok { - list[name] = quantity.DeepCopy() - } else { - value.Add(quantity) - list[name] = value - } - } -} - -// maxResourceList sets list to the greater of list/newList for every resource -// either list -func maxResourceList(list, new corev1.ResourceList) { - for name, quantity := range new { - if value, ok := list[name]; !ok { - list[name] = quantity.DeepCopy() - continue - } else { - if quantity.Cmp(value) > 0 { - list[name] = quantity.DeepCopy() - } - } - } -} - // ExtractContainerResourceValue extracts the value of a resource // in an already known container func ExtractContainerResourceValue(fs *corev1.ResourceFieldSelector, container *corev1.Container) (string, error) { diff --git a/pkg/util/resource/resource_test.go b/pkg/util/resource/resource_test.go index a020c32a5..be38380e0 100644 --- a/pkg/util/resource/resource_test.go +++ b/pkg/util/resource/resource_test.go @@ -15,82 +15,3 @@ limitations under the License. */ package resource - -import ( - "testing" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" -) - -func TestMaxWithNilResourceList(t *testing.T) { - tests := []struct { - name string - a corev1.ResourceList - b []corev1.ResourceList - want corev1.ResourceList - }{ - { - name: "nil first argument with non-nil second", - a: nil, - b: []corev1.ResourceList{{corev1.ResourceCPU: resource.MustParse("100m")}}, - want: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}, - }, - { - name: "nil first argument with nil second", - a: nil, - b: []corev1.ResourceList{nil}, - want: corev1.ResourceList{}, - }, - { - name: "nil first argument with empty second", - a: nil, - b: []corev1.ResourceList{{}}, - want: corev1.ResourceList{}, - }, - { - name: "nil first argument with no second arguments", - a: nil, - b: nil, - want: corev1.ResourceList{}, - }, - { - name: "empty first argument with non-nil second", - a: corev1.ResourceList{}, - b: []corev1.ResourceList{{corev1.ResourceCPU: resource.MustParse("100m")}}, - want: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}, - }, - { - name: "non-nil first argument takes max", - a: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}, - b: []corev1.ResourceList{{corev1.ResourceCPU: resource.MustParse("100m")}}, - want: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}, - }, - { - name: "second argument larger takes max", - a: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("100m")}, - b: []corev1.ResourceList{{corev1.ResourceCPU: resource.MustParse("200m")}}, - want: corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("200m")}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := max(tt.a, tt.b...) - if len(got) != len(tt.want) { - t.Errorf("case %q, expected %d resources but got %d", tt.name, len(tt.want), len(got)) - return - } - for name, wantQty := range tt.want { - gotQty, ok := got[name] - if !ok { - t.Errorf("case %q, expected resource %s but it was missing", tt.name, name) - continue - } - if gotQty.Cmp(wantQty) != 0 { - t.Errorf("case %q, expected resource %s to be %s but got %s", tt.name, name, wantQty.String(), gotQty.String()) - } - } - }) - } -}