mirror of
https://github.com/kubernetes/kubectl.git
synced 2026-06-09 08:51:18 -04:00
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
This commit is contained in:
parent
8ff045b4dc
commit
ad4e7654ea
2 changed files with 0 additions and 247 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue