Add ability to find init Container IDs in cpumanager reconcileState()

The cpumanager loops through all init Containers and app Containers when
reconciling its state. However, the current implementation of
findContainerIDByName(), which is call by the reconciler, does not
resolve for init Containers.

This patch updates findContainerIDByName() to account for init
Containers and adds a regression test that fails before the change and
succeeds after.
This commit is contained in:
Kevin Klues 2019-04-27 05:57:03 -07:00
parent 41f9f31592
commit ef27f5f1a5
2 changed files with 88 additions and 30 deletions

View File

@ -294,7 +294,9 @@ func (m *manager) reconcileState() (success []reconciledContainer, failure []rec
} }
func findContainerIDByName(status *v1.PodStatus, name string) (string, error) { func findContainerIDByName(status *v1.PodStatus, name string) (string, error) {
for _, container := range status.ContainerStatuses { allStatuses := status.InitContainerStatuses
allStatuses = append(allStatuses, status.ContainerStatuses...)
for _, container := range allStatuses {
if container.Name == name && container.ContainerID != "" { if container.Name == name && container.ContainerID != "" {
cid := &kubecontainer.ContainerID{} cid := &kubecontainer.ContainerID{}
err := cid.ParseString(container.ContainerID) err := cid.ParseString(container.ContainerID)

View File

@ -352,14 +352,15 @@ func TestCPUManagerRemove(t *testing.T) {
func TestReconcileState(t *testing.T) { func TestReconcileState(t *testing.T) {
testCases := []struct { testCases := []struct {
description string description string
activePods []*v1.Pod activePods []*v1.Pod
pspPS v1.PodStatus pspPS v1.PodStatus
pspFound bool pspFound bool
stAssignments state.ContainerCPUAssignments stAssignments state.ContainerCPUAssignments
stDefaultCPUSet cpuset.CPUSet stDefaultCPUSet cpuset.CPUSet
updateErr error updateErr error
expectFailedContainerName string expectSucceededContainerName string
expectFailedContainerName string
}{ }{
{ {
description: "cpu manager reconclie - no error", description: "cpu manager reconclie - no error",
@ -390,9 +391,44 @@ func TestReconcileState(t *testing.T) {
stAssignments: state.ContainerCPUAssignments{ stAssignments: state.ContainerCPUAssignments{
"fakeID": cpuset.NewCPUSet(1, 2), "fakeID": cpuset.NewCPUSet(1, 2),
}, },
stDefaultCPUSet: cpuset.NewCPUSet(3, 4, 5, 6, 7), stDefaultCPUSet: cpuset.NewCPUSet(3, 4, 5, 6, 7),
updateErr: nil, updateErr: nil,
expectFailedContainerName: "", expectSucceededContainerName: "fakeName",
expectFailedContainerName: "",
},
{
description: "cpu manager reconcile init container - no error",
activePods: []*v1.Pod{
{
ObjectMeta: metav1.ObjectMeta{
Name: "fakePodName",
UID: "fakeUID",
},
Spec: v1.PodSpec{
InitContainers: []v1.Container{
{
Name: "fakeName",
},
},
},
},
},
pspPS: v1.PodStatus{
InitContainerStatuses: []v1.ContainerStatus{
{
Name: "fakeName",
ContainerID: "docker://fakeID",
},
},
},
pspFound: true,
stAssignments: state.ContainerCPUAssignments{
"fakeID": cpuset.NewCPUSet(1, 2),
},
stDefaultCPUSet: cpuset.NewCPUSet(3, 4, 5, 6, 7),
updateErr: nil,
expectSucceededContainerName: "fakeName",
expectFailedContainerName: "",
}, },
{ {
description: "cpu manager reconclie - pod status not found", description: "cpu manager reconclie - pod status not found",
@ -411,12 +447,13 @@ func TestReconcileState(t *testing.T) {
}, },
}, },
}, },
pspPS: v1.PodStatus{}, pspPS: v1.PodStatus{},
pspFound: false, pspFound: false,
stAssignments: state.ContainerCPUAssignments{}, stAssignments: state.ContainerCPUAssignments{},
stDefaultCPUSet: cpuset.NewCPUSet(), stDefaultCPUSet: cpuset.NewCPUSet(),
updateErr: nil, updateErr: nil,
expectFailedContainerName: "fakeName", expectSucceededContainerName: "",
expectFailedContainerName: "fakeName",
}, },
{ {
description: "cpu manager reconclie - container id not found", description: "cpu manager reconclie - container id not found",
@ -443,11 +480,12 @@ func TestReconcileState(t *testing.T) {
}, },
}, },
}, },
pspFound: true, pspFound: true,
stAssignments: state.ContainerCPUAssignments{}, stAssignments: state.ContainerCPUAssignments{},
stDefaultCPUSet: cpuset.NewCPUSet(), stDefaultCPUSet: cpuset.NewCPUSet(),
updateErr: nil, updateErr: nil,
expectFailedContainerName: "fakeName", expectSucceededContainerName: "",
expectFailedContainerName: "fakeName",
}, },
{ {
description: "cpu manager reconclie - cpuset is empty", description: "cpu manager reconclie - cpuset is empty",
@ -478,9 +516,10 @@ func TestReconcileState(t *testing.T) {
stAssignments: state.ContainerCPUAssignments{ stAssignments: state.ContainerCPUAssignments{
"fakeID": cpuset.NewCPUSet(), "fakeID": cpuset.NewCPUSet(),
}, },
stDefaultCPUSet: cpuset.NewCPUSet(1, 2, 3, 4, 5, 6, 7), stDefaultCPUSet: cpuset.NewCPUSet(1, 2, 3, 4, 5, 6, 7),
updateErr: nil, updateErr: nil,
expectFailedContainerName: "fakeName", expectSucceededContainerName: "",
expectFailedContainerName: "fakeName",
}, },
{ {
description: "cpu manager reconclie - container update error", description: "cpu manager reconclie - container update error",
@ -511,9 +550,10 @@ func TestReconcileState(t *testing.T) {
stAssignments: state.ContainerCPUAssignments{ stAssignments: state.ContainerCPUAssignments{
"fakeID": cpuset.NewCPUSet(1, 2), "fakeID": cpuset.NewCPUSet(1, 2),
}, },
stDefaultCPUSet: cpuset.NewCPUSet(3, 4, 5, 6, 7), stDefaultCPUSet: cpuset.NewCPUSet(3, 4, 5, 6, 7),
updateErr: fmt.Errorf("fake container update error"), updateErr: fmt.Errorf("fake container update error"),
expectFailedContainerName: "fakeName", expectSucceededContainerName: "",
expectFailedContainerName: "fakeName",
}, },
} }
@ -538,7 +578,22 @@ func TestReconcileState(t *testing.T) {
}, },
} }
_, failure := mgr.reconcileState() success, failure := mgr.reconcileState()
if testCase.expectSucceededContainerName != "" {
// Search succeeded reconciled containers for the supplied name.
foundSucceededContainer := false
for _, reconciled := range success {
if reconciled.containerName == testCase.expectSucceededContainerName {
foundSucceededContainer = true
break
}
}
if !foundSucceededContainer {
t.Errorf("%v", testCase.description)
t.Errorf("Expected reconciliation success for container: %s", testCase.expectSucceededContainerName)
}
}
if testCase.expectFailedContainerName != "" { if testCase.expectFailedContainerName != "" {
// Search failed reconciled containers for the supplied name. // Search failed reconciled containers for the supplied name.
@ -550,6 +605,7 @@ func TestReconcileState(t *testing.T) {
} }
} }
if !foundFailedContainer { if !foundFailedContainer {
t.Errorf("%v", testCase.description)
t.Errorf("Expected reconciliation failure for container: %s", testCase.expectFailedContainerName) t.Errorf("Expected reconciliation failure for container: %s", testCase.expectFailedContainerName)
} }
} }