diff --git a/pkg/kubelet/apis/podresources/server_v1.go b/pkg/kubelet/apis/podresources/server_v1.go index 8482f51a19d..325a7f727ec 100644 --- a/pkg/kubelet/apis/podresources/server_v1.go +++ b/pkg/kubelet/apis/podresources/server_v1.go @@ -60,7 +60,7 @@ func (p *v1PodResourcesServer) List(ctx context.Context, req *v1.ListPodResource pRes.Containers[j] = &v1.ContainerResources{ Name: container.Name, Devices: p.devicesProvider.GetDevices(string(pod.UID), container.Name), - CpuIds: p.cpusProvider.GetCPUs(string(pod.UID), container.Name), + CpuIds: p.cpusProvider.GetCPUs(string(pod.UID), container.Name).ToSliceNoSortInt64(), } } podResources[i] = &pRes diff --git a/pkg/kubelet/apis/podresources/server_v1_test.go b/pkg/kubelet/apis/podresources/server_v1_test.go index c25912ee3ba..ed6033c3d50 100644 --- a/pkg/kubelet/apis/podresources/server_v1_test.go +++ b/pkg/kubelet/apis/podresources/server_v1_test.go @@ -18,12 +18,15 @@ package podresources import ( "context" + "reflect" + "sort" "testing" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ) func TestListPodResourcesV1(t *testing.T) { @@ -41,20 +44,20 @@ func TestListPodResourcesV1(t *testing.T) { }, } - cpus := []int64{12, 23, 30} + cpus := cpuset.NewCPUSet(12, 23, 30) for _, tc := range []struct { desc string pods []*v1.Pod devices []*podresourcesapi.ContainerDevices - cpus []int64 + cpus cpuset.CPUSet expectedResponse *podresourcesapi.ListPodResourcesResponse }{ { desc: "no pods", pods: []*v1.Pod{}, devices: []*podresourcesapi.ContainerDevices{}, - cpus: []int64{}, + cpus: cpuset.CPUSet{}, expectedResponse: &podresourcesapi.ListPodResourcesResponse{}, }, { @@ -76,7 +79,7 @@ func TestListPodResourcesV1(t *testing.T) { }, }, devices: []*podresourcesapi.ContainerDevices{}, - cpus: []int64{}, + cpus: cpuset.CPUSet{}, expectedResponse: &podresourcesapi.ListPodResourcesResponse{ PodResources: []*podresourcesapi.PodResources{ { @@ -121,7 +124,7 @@ func TestListPodResourcesV1(t *testing.T) { { Name: containerName, Devices: devs, - CpuIds: cpus, + CpuIds: cpus.ToSliceNoSortInt64(), }, }, }, @@ -140,9 +143,91 @@ func TestListPodResourcesV1(t *testing.T) { if err != nil { t.Errorf("want err = %v, got %q", nil, err) } - if tc.expectedResponse.String() != resp.String() { + if !equalListResponse(tc.expectedResponse, resp) { t.Errorf("want resp = %s, got %s", tc.expectedResponse.String(), resp.String()) } }) } } + +func equalListResponse(respA, respB *podresourcesapi.ListPodResourcesResponse) bool { + if len(respA.PodResources) != len(respB.PodResources) { + return false + } + for idx := 0; idx < len(respA.PodResources); idx++ { + podResA := respA.PodResources[idx] + podResB := respB.PodResources[idx] + if podResA.Name != podResB.Name { + return false + } + if podResA.Namespace != podResB.Namespace { + return false + } + if len(podResA.Containers) != len(podResB.Containers) { + return false + } + for jdx := 0; jdx < len(podResA.Containers); jdx++ { + cntA := podResA.Containers[jdx] + cntB := podResB.Containers[jdx] + + if cntA.Name != cntB.Name { + return false + } + if !equalInt64s(cntA.CpuIds, cntB.CpuIds) { + return false + } + + if len(cntA.Devices) != len(cntB.Devices) { + return false + } + + for kdx := 0; kdx < len(cntA.Devices); kdx++ { + cntDevA := cntA.Devices[kdx] + cntDevB := cntB.Devices[kdx] + + if cntDevA.ResourceName != cntDevB.ResourceName { + return false + } + if !equalTopology(cntDevA.Topology, cntDevB.Topology) { + return false + } + if !equalStrings(cntDevA.DeviceIds, cntDevB.DeviceIds) { + return false + } + } + } + } + return true +} + +func equalInt64s(a, b []int64) bool { + if len(a) != len(b) { + return false + } + aCopy := append([]int64{}, a...) + sort.Slice(aCopy, func(i, j int) bool { return aCopy[i] < aCopy[j] }) + bCopy := append([]int64{}, b...) + sort.Slice(bCopy, func(i, j int) bool { return bCopy[i] < bCopy[j] }) + return reflect.DeepEqual(aCopy, bCopy) +} + +func equalStrings(a, b []string) bool { + if len(a) != len(b) { + return false + } + aCopy := append([]string{}, a...) + sort.Strings(aCopy) + bCopy := append([]string{}, b...) + sort.Strings(bCopy) + return reflect.DeepEqual(aCopy, bCopy) +} + +func equalTopology(a, b *podresourcesapi.TopologyInfo) bool { + if a == nil && b != nil { + return false + } + if a != nil && b == nil { + return false + } + return reflect.DeepEqual(a, b) +} diff --git a/pkg/kubelet/apis/podresources/server_v1alpha1_test.go b/pkg/kubelet/apis/podresources/server_v1alpha1_test.go index 5fe6f966e9d..9ce97900d7f 100644 --- a/pkg/kubelet/apis/podresources/server_v1alpha1_test.go +++ b/pkg/kubelet/apis/podresources/server_v1alpha1_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" podresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1" "k8s.io/kubelet/pkg/apis/podresources/v1alpha1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ) type mockProvider struct { @@ -43,9 +44,9 @@ func (m *mockProvider) GetDevices(podUID, containerName string) []*podresourcesv return args.Get(0).([]*podresourcesv1.ContainerDevices) } -func (m *mockProvider) GetCPUs(podUID, containerName string) []int64 { +func (m *mockProvider) GetCPUs(podUID, containerName string) cpuset.CPUSet { args := m.Called(podUID, containerName) - return args.Get(0).([]int64) + return args.Get(0).(cpuset.CPUSet) } func (m *mockProvider) UpdateAllocatedDevices() { diff --git a/pkg/kubelet/apis/podresources/types.go b/pkg/kubelet/apis/podresources/types.go index 433d92c5996..40d00db7954 100644 --- a/pkg/kubelet/apis/podresources/types.go +++ b/pkg/kubelet/apis/podresources/types.go @@ -19,6 +19,7 @@ package podresources import ( "k8s.io/api/core/v1" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" ) // DevicesProvider knows how to provide the devices used by the given container @@ -34,5 +35,5 @@ type PodsProvider interface { // CPUsProvider knows how to provide the cpus used by the given container type CPUsProvider interface { - GetCPUs(podUID, containerName string) []int64 + GetCPUs(podUID, containerName string) cpuset.CPUSet } diff --git a/pkg/kubelet/cm/container_manager.go b/pkg/kubelet/cm/container_manager.go index e4a71094718..cefb40f9512 100644 --- a/pkg/kubelet/cm/container_manager.go +++ b/pkg/kubelet/cm/container_manager.go @@ -107,7 +107,7 @@ type ContainerManager interface { GetDevices(podUID, containerName string) []*podresourcesapi.ContainerDevices // GetCPUs returns information about the cpus assigned to pods and containers - GetCPUs(podUID, containerName string) []int64 + GetCPUs(podUID, containerName string) cpuset.CPUSet // ShouldResetExtendedResourceCapacity returns whether or not the extended resources should be zeroed, // due to node recreation. diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go index e6e16ace516..a19e2180268 100644 --- a/pkg/kubelet/cm/container_manager_linux.go +++ b/pkg/kubelet/cm/container_manager_linux.go @@ -52,6 +52,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cm/containermap" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager" "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" @@ -1072,8 +1073,8 @@ func (cm *containerManagerImpl) GetDevices(podUID, containerName string) []*podr return cm.deviceManager.GetDevices(podUID, containerName) } -func (cm *containerManagerImpl) GetCPUs(podUID, containerName string) []int64 { - return cm.cpuManager.GetCPUs(podUID, containerName).ToSliceNoSortInt64() +func (cm *containerManagerImpl) GetCPUs(podUID, containerName string) cpuset.CPUSet { + return cm.cpuManager.GetCPUs(podUID, containerName).Clone() } func (cm *containerManagerImpl) ShouldResetExtendedResourceCapacity() bool { diff --git a/pkg/kubelet/cm/container_manager_stub.go b/pkg/kubelet/cm/container_manager_stub.go index ac4ceee2c56..5c8e835a39b 100644 --- a/pkg/kubelet/cm/container_manager_stub.go +++ b/pkg/kubelet/cm/container_manager_stub.go @@ -24,6 +24,7 @@ import ( internalapi "k8s.io/cri-api/pkg/apis" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/config" @@ -126,8 +127,8 @@ func (cm *containerManagerStub) UpdateAllocatedDevices() { return } -func (cm *containerManagerStub) GetCPUs(_, _ string) []int64 { - return nil +func (cm *containerManagerStub) GetCPUs(_, _ string) cpuset.CPUSet { + return cpuset.CPUSet{} } func NewStubContainerManager() ContainerManager { diff --git a/pkg/kubelet/cm/container_manager_windows.go b/pkg/kubelet/cm/container_manager_windows.go index c3d07f270c3..54ca4f53d01 100644 --- a/pkg/kubelet/cm/container_manager_windows.go +++ b/pkg/kubelet/cm/container_manager_windows.go @@ -232,6 +232,6 @@ func (cm *containerManagerImpl) UpdateAllocatedDevices() { return } -func (cm *containerManagerImpl) GetCPUs(_, _ string) []int64 { - return nil +func (cm *containerManagerImpl) GetCPUs(_, _ string) cpuset.CPUSet { + return cpuset.CPUSet{} } diff --git a/pkg/kubelet/cm/fake_container_manager.go b/pkg/kubelet/cm/fake_container_manager.go index 027fffc7e72..67aaaec5060 100644 --- a/pkg/kubelet/cm/fake_container_manager.go +++ b/pkg/kubelet/cm/fake_container_manager.go @@ -25,6 +25,7 @@ import ( internalapi "k8s.io/cri-api/pkg/apis" podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" + "k8s.io/kubernetes/pkg/kubelet/cm/cpuset" "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" "k8s.io/kubernetes/pkg/kubelet/config" @@ -195,9 +196,9 @@ func (cm *FakeContainerManager) UpdateAllocatedDevices() { return } -func (cm *FakeContainerManager) GetCPUs(_, _ string) []int64 { +func (cm *FakeContainerManager) GetCPUs(_, _ string) cpuset.CPUSet { cm.Lock() defer cm.Unlock() cm.CalledFunctions = append(cm.CalledFunctions, "GetCPUs") - return nil + return cpuset.CPUSet{} }