Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2b46aea4
Commit
2b46aea4
authored
Jun 06, 2016
by
Łukasz Oleś
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Custom sort function for InitContainersStatuses
Order in init container statuses should be the same as defined in pod. Statues shoudln't be sorted by name.
parent
0d3be6a3
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
95 additions
and
8 deletions
+95
-8
kubelet.go
pkg/kubelet/kubelet.go
+5
-1
manager.go
pkg/kubelet/status/manager.go
+4
-4
manager_test.go
pkg/kubelet/status/manager_test.go
+6
-3
types.go
pkg/kubelet/types/types.go
+16
-0
types_test.go
pkg/kubelet/types/types_test.go
+64
-0
No files found.
pkg/kubelet/kubelet.go
View file @
2b46aea4
...
@@ -3830,7 +3830,11 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *api.Pod, podStatus *kubeco
...
@@ -3830,7 +3830,11 @@ func (kl *Kubelet) convertToAPIContainerStatuses(pod *api.Pod, podStatus *kubeco
// Sort the container statuses since clients of this interface expect the list
// Sort the container statuses since clients of this interface expect the list
// of containers in a pod has a deterministic order.
// of containers in a pod has a deterministic order.
sort
.
Sort
(
kubetypes
.
SortedContainerStatuses
(
containerStatuses
))
if
isInitContainer
{
kubetypes
.
SortInitContainerStatuses
(
pod
,
containerStatuses
)
}
else
{
sort
.
Sort
(
kubetypes
.
SortedContainerStatuses
(
containerStatuses
))
}
return
containerStatuses
return
containerStatuses
}
}
...
...
pkg/kubelet/status/manager.go
View file @
2b46aea4
...
@@ -306,7 +306,7 @@ func (m *manager) updateStatusInternal(pod *api.Pod, status api.PodStatus, force
...
@@ -306,7 +306,7 @@ func (m *manager) updateStatusInternal(pod *api.Pod, status api.PodStatus, force
status
.
StartTime
=
&
now
status
.
StartTime
=
&
now
}
}
normalizeStatus
(
&
status
)
normalizeStatus
(
pod
,
&
status
)
// The intent here is to prevent concurrent updates to a pod's status from
// The intent here is to prevent concurrent updates to a pod's status from
// clobbering each other so the phase of a pod progresses monotonically.
// clobbering each other so the phase of a pod progresses monotonically.
if
isCached
&&
isStatusEqual
(
&
cachedStatus
.
status
,
&
status
)
&&
!
forceUpdate
{
if
isCached
&&
isStatusEqual
(
&
cachedStatus
.
status
,
&
status
)
&&
!
forceUpdate
{
...
@@ -484,7 +484,7 @@ func (m *manager) needsReconcile(uid types.UID, status api.PodStatus) bool {
...
@@ -484,7 +484,7 @@ func (m *manager) needsReconcile(uid types.UID, status api.PodStatus) bool {
if
err
!=
nil
{
if
err
!=
nil
{
return
false
return
false
}
}
normalizeStatus
(
&
podStatus
)
normalizeStatus
(
pod
,
&
podStatus
)
if
isStatusEqual
(
&
podStatus
,
&
status
)
{
if
isStatusEqual
(
&
podStatus
,
&
status
)
{
// If the status from the source is the same with the cached status,
// If the status from the source is the same with the cached status,
...
@@ -504,7 +504,7 @@ func (m *manager) needsReconcile(uid types.UID, status api.PodStatus) bool {
...
@@ -504,7 +504,7 @@ func (m *manager) needsReconcile(uid types.UID, status api.PodStatus) bool {
// In fact, the best way to solve this is to do it on api side. However for now, we normalize the status locally in
// In fact, the best way to solve this is to do it on api side. However for now, we normalize the status locally in
// kubelet temporarily.
// kubelet temporarily.
// TODO(random-liu): Remove timestamp related logic after apiserver supports nanosecond or makes it consistent.
// TODO(random-liu): Remove timestamp related logic after apiserver supports nanosecond or makes it consistent.
func
normalizeStatus
(
status
*
api
.
PodStatus
)
*
api
.
PodStatus
{
func
normalizeStatus
(
pod
*
api
.
Pod
,
status
*
api
.
PodStatus
)
*
api
.
PodStatus
{
normalizeTimeStamp
:=
func
(
t
*
unversioned
.
Time
)
{
normalizeTimeStamp
:=
func
(
t
*
unversioned
.
Time
)
{
*
t
=
t
.
Rfc3339Copy
()
*
t
=
t
.
Rfc3339Copy
()
}
}
...
@@ -543,7 +543,7 @@ func normalizeStatus(status *api.PodStatus) *api.PodStatus {
...
@@ -543,7 +543,7 @@ func normalizeStatus(status *api.PodStatus) *api.PodStatus {
normalizeContainerState
(
&
cstatus
.
LastTerminationState
)
normalizeContainerState
(
&
cstatus
.
LastTerminationState
)
}
}
// Sort the container statuses, so that the order won't affect the result of comparison
// Sort the container statuses, so that the order won't affect the result of comparison
sort
.
Sort
(
kubetypes
.
SortedContainerStatuses
(
status
.
InitContainerStatuses
)
)
kubetypes
.
SortInitContainerStatuses
(
pod
,
status
.
InitContainerStatuses
)
return
status
return
status
}
}
...
...
pkg/kubelet/status/manager_test.go
View file @
2b46aea4
...
@@ -452,6 +452,9 @@ func shuffle(statuses []api.ContainerStatus) []api.ContainerStatus {
...
@@ -452,6 +452,9 @@ func shuffle(statuses []api.ContainerStatus) []api.ContainerStatus {
}
}
func
TestStatusEquality
(
t
*
testing
.
T
)
{
func
TestStatusEquality
(
t
*
testing
.
T
)
{
pod
:=
api
.
Pod
{
Spec
:
api
.
PodSpec
{},
}
containerStatus
:=
[]
api
.
ContainerStatus
{}
containerStatus
:=
[]
api
.
ContainerStatus
{}
for
i
:=
0
;
i
<
10
;
i
++
{
for
i
:=
0
;
i
<
10
;
i
++
{
s
:=
api
.
ContainerStatus
{
s
:=
api
.
ContainerStatus
{
...
@@ -466,8 +469,8 @@ func TestStatusEquality(t *testing.T) {
...
@@ -466,8 +469,8 @@ func TestStatusEquality(t *testing.T) {
oldPodStatus
:=
api
.
PodStatus
{
oldPodStatus
:=
api
.
PodStatus
{
ContainerStatuses
:
shuffle
(
podStatus
.
ContainerStatuses
),
ContainerStatuses
:
shuffle
(
podStatus
.
ContainerStatuses
),
}
}
normalizeStatus
(
&
oldPodStatus
)
normalizeStatus
(
&
pod
,
&
oldPodStatus
)
normalizeStatus
(
&
podStatus
)
normalizeStatus
(
&
pod
,
&
pod
Status
)
if
!
isStatusEqual
(
&
oldPodStatus
,
&
podStatus
)
{
if
!
isStatusEqual
(
&
oldPodStatus
,
&
podStatus
)
{
t
.
Fatalf
(
"Order of container statuses should not affect normalized equality."
)
t
.
Fatalf
(
"Order of container statuses should not affect normalized equality."
)
}
}
...
@@ -498,7 +501,7 @@ func TestStaticPodStatus(t *testing.T) {
...
@@ -498,7 +501,7 @@ func TestStaticPodStatus(t *testing.T) {
m
.
SetPodStatus
(
staticPod
,
status
)
m
.
SetPodStatus
(
staticPod
,
status
)
retrievedStatus
:=
expectPodStatus
(
t
,
m
,
staticPod
)
retrievedStatus
:=
expectPodStatus
(
t
,
m
,
staticPod
)
normalizeStatus
(
&
status
)
normalizeStatus
(
staticPod
,
&
status
)
assert
.
True
(
t
,
isStatusEqual
(
&
status
,
&
retrievedStatus
),
"Expected: %+v, Got: %+v"
,
status
,
retrievedStatus
)
assert
.
True
(
t
,
isStatusEqual
(
&
status
,
&
retrievedStatus
),
"Expected: %+v, Got: %+v"
,
status
,
retrievedStatus
)
retrievedStatus
,
_
=
m
.
GetPodStatus
(
mirrorPod
.
UID
)
retrievedStatus
,
_
=
m
.
GetPodStatus
(
mirrorPod
.
UID
)
assert
.
True
(
t
,
isStatusEqual
(
&
status
,
&
retrievedStatus
),
"Expected: %+v, Got: %+v"
,
status
,
retrievedStatus
)
assert
.
True
(
t
,
isStatusEqual
(
&
status
,
&
retrievedStatus
),
"Expected: %+v, Got: %+v"
,
status
,
retrievedStatus
)
...
...
pkg/kubelet/types/types.go
View file @
2b46aea4
...
@@ -68,6 +68,22 @@ func (s SortedContainerStatuses) Less(i, j int) bool {
...
@@ -68,6 +68,22 @@ func (s SortedContainerStatuses) Less(i, j int) bool {
return
s
[
i
]
.
Name
<
s
[
j
]
.
Name
return
s
[
i
]
.
Name
<
s
[
j
]
.
Name
}
}
// SortInitContainerStatuses ensures that statuses are in the order that their
// init container appears in the pod spec
func
SortInitContainerStatuses
(
p
*
api
.
Pod
,
statuses
[]
api
.
ContainerStatus
)
{
containers
:=
p
.
Spec
.
InitContainers
current
:=
0
for
_
,
container
:=
range
containers
{
for
j
:=
current
;
j
<
len
(
statuses
);
j
++
{
if
container
.
Name
==
statuses
[
j
]
.
Name
{
statuses
[
current
],
statuses
[
j
]
=
statuses
[
j
],
statuses
[
current
]
current
++
break
}
}
}
}
// Reservation represents reserved resources for non-pod components.
// Reservation represents reserved resources for non-pod components.
type
Reservation
struct
{
type
Reservation
struct
{
// System represents resources reserved for non-kubernetes components.
// System represents resources reserved for non-kubernetes components.
...
...
pkg/kubelet/types/types_test.go
0 → 100644
View file @
2b46aea4
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
types
import
(
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
)
func
TestSortInitContainerStatuses
(
t
*
testing
.
T
)
{
pod
:=
api
.
Pod
{
Spec
:
api
.
PodSpec
{},
}
var
cases
=
[]
struct
{
containers
[]
api
.
Container
statuses
[]
api
.
ContainerStatus
sortedStatuses
[]
api
.
ContainerStatus
}{
{
containers
:
[]
api
.
Container
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
statuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
sortedStatuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
},
{
containers
:
[]
api
.
Container
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
statuses
:
[]
api
.
ContainerStatus
{{
Name
:
"second"
},
{
Name
:
"first"
},
{
Name
:
"fourth"
},
{
Name
:
"third"
}},
sortedStatuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
},
{
containers
:
[]
api
.
Container
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
statuses
:
[]
api
.
ContainerStatus
{{
Name
:
"fourth"
},
{
Name
:
"first"
}},
sortedStatuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"fourth"
}},
},
{
containers
:
[]
api
.
Container
{{
Name
:
"first"
},
{
Name
:
"second"
},
{
Name
:
"third"
},
{
Name
:
"fourth"
}},
statuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"third"
}},
sortedStatuses
:
[]
api
.
ContainerStatus
{{
Name
:
"first"
},
{
Name
:
"third"
}},
},
}
for
_
,
data
:=
range
cases
{
pod
.
Spec
.
InitContainers
=
data
.
containers
SortInitContainerStatuses
(
&
pod
,
data
.
statuses
)
if
!
reflect
.
DeepEqual
(
data
.
statuses
,
data
.
sortedStatuses
)
{
t
.
Errorf
(
"SortInitContainerStatuses result wrong:
\n
Containers order: %v
\n
Expected order: %v
\n
Returne order: %v"
,
data
.
containers
,
data
.
sortedStatuses
,
data
.
statuses
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment