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
63fb075f
Commit
63fb075f
authored
Jun 14, 2016
by
Chao Xu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix updatePod of replication controller manager and replica set controller to
handle pod label updates that match no rc or rs
parent
77419c48
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
63 additions
and
25 deletions
+63
-25
replica_set.go
pkg/controller/replicaset/replica_set.go
+10
-8
replica_set_test.go
pkg/controller/replicaset/replica_set_test.go
+21
-5
replication_controller.go
pkg/controller/replication/replication_controller.go
+11
-7
replication_controller_test.go
pkg/controller/replication/replication_controller_test.go
+21
-5
No files found.
pkg/controller/replicaset/replica_set.go
View file @
63fb075f
...
@@ -326,12 +326,8 @@ func (rsc *ReplicaSetController) updatePod(old, cur interface{}) {
...
@@ -326,12 +326,8 @@ func (rsc *ReplicaSetController) updatePod(old, cur interface{}) {
}
}
curPod
:=
cur
.
(
*
api
.
Pod
)
curPod
:=
cur
.
(
*
api
.
Pod
)
oldPod
:=
old
.
(
*
api
.
Pod
)
oldPod
:=
old
.
(
*
api
.
Pod
)
glog
.
V
(
4
)
.
Infof
(
"Pod %s updated %+v -> %+v."
,
curPod
.
Name
,
oldPod
,
curPod
)
glog
.
V
(
4
)
.
Infof
(
"Pod %s updated, objectMeta %+v -> %+v."
,
curPod
.
Name
,
oldPod
.
ObjectMeta
,
curPod
.
ObjectMeta
)
rs
:=
rsc
.
getPodReplicaSet
(
curPod
)
labelChanged
:=
!
reflect
.
DeepEqual
(
curPod
.
Labels
,
oldPod
.
Labels
)
if
rs
==
nil
{
return
}
if
curPod
.
DeletionTimestamp
!=
nil
{
if
curPod
.
DeletionTimestamp
!=
nil
{
// when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period,
// when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period,
// and after such time has passed, the kubelet actually deletes it from the store. We receive an update
// and after such time has passed, the kubelet actually deletes it from the store. We receive an update
...
@@ -339,11 +335,17 @@ func (rsc *ReplicaSetController) updatePod(old, cur interface{}) {
...
@@ -339,11 +335,17 @@ func (rsc *ReplicaSetController) updatePod(old, cur interface{}) {
// until the kubelet actually deletes the pod. This is different from the Phase of a pod changing, because
// until the kubelet actually deletes the pod. This is different from the Phase of a pod changing, because
// an rs never initiates a phase change, and so is never asleep waiting for the same.
// an rs never initiates a phase change, and so is never asleep waiting for the same.
rsc
.
deletePod
(
curPod
)
rsc
.
deletePod
(
curPod
)
if
labelChanged
{
// we don't need to check the oldPod.DeletionTimestamp because DeletionTimestamp cannot be unset.
rsc
.
deletePod
(
oldPod
)
}
return
return
}
}
rsc
.
enqueueReplicaSet
(
rs
)
if
rs
:=
rsc
.
getPodReplicaSet
(
curPod
);
rs
!=
nil
{
if
!
reflect
.
DeepEqual
(
curPod
.
Labels
,
oldPod
.
Labels
)
{
rsc
.
enqueueReplicaSet
(
rs
)
}
if
labelChanged
{
// If the old and new ReplicaSet are the same, the first one that syncs
// If the old and new ReplicaSet are the same, the first one that syncs
// will set expectations preventing any damage from the second.
// will set expectations preventing any damage from the second.
if
oldRS
:=
rsc
.
getPodReplicaSet
(
oldPod
);
oldRS
!=
nil
{
if
oldRS
:=
rsc
.
getPodReplicaSet
(
oldPod
);
oldRS
!=
nil
{
...
...
pkg/controller/replicaset/replica_set_test.go
View file @
63fb075f
...
@@ -547,15 +547,13 @@ func TestUpdatePods(t *testing.T) {
...
@@ -547,15 +547,13 @@ func TestUpdatePods(t *testing.T) {
testRSSpec2
.
Name
=
"barfoo"
testRSSpec2
.
Name
=
"barfoo"
manager
.
rsStore
.
Store
.
Add
(
&
testRSSpec2
)
manager
.
rsStore
.
Store
.
Add
(
&
testRSSpec2
)
// Put one pod in the podStore
// case 1: We put in the podStore a pod with labels matching testRSSpec1,
// then update its labels to match testRSSpec2. We expect to receive a sync
// request for both replica sets.
pod1
:=
newPodList
(
manager
.
podStore
.
Indexer
,
1
,
api
.
PodRunning
,
labelMap1
,
testRSSpec1
,
"pod"
)
.
Items
[
0
]
pod1
:=
newPodList
(
manager
.
podStore
.
Indexer
,
1
,
api
.
PodRunning
,
labelMap1
,
testRSSpec1
,
"pod"
)
.
Items
[
0
]
pod2
:=
pod1
pod2
:=
pod1
pod2
.
Labels
=
labelMap2
pod2
.
Labels
=
labelMap2
// Send an update of the same pod with modified labels, and confirm we get a sync request for
// both controllers
manager
.
updatePod
(
&
pod1
,
&
pod2
)
manager
.
updatePod
(
&
pod1
,
&
pod2
)
expected
:=
sets
.
NewString
(
testRSSpec1
.
Name
,
testRSSpec2
.
Name
)
expected
:=
sets
.
NewString
(
testRSSpec1
.
Name
,
testRSSpec2
.
Name
)
for
_
,
name
:=
range
expected
.
List
()
{
for
_
,
name
:=
range
expected
.
List
()
{
t
.
Logf
(
"Expecting update for %+v"
,
name
)
t
.
Logf
(
"Expecting update for %+v"
,
name
)
...
@@ -568,6 +566,24 @@ func TestUpdatePods(t *testing.T) {
...
@@ -568,6 +566,24 @@ func TestUpdatePods(t *testing.T) {
t
.
Errorf
(
"Expected update notifications for replica sets within 100ms each"
)
t
.
Errorf
(
"Expected update notifications for replica sets within 100ms each"
)
}
}
}
}
// case 2: pod1 in the podStore has labels matching testRSSpec1. We update
// its labels to match no replica set. We expect to receive a sync request
// for testRSSpec1.
pod2
.
Labels
=
make
(
map
[
string
]
string
)
manager
.
updatePod
(
&
pod1
,
&
pod2
)
expected
=
sets
.
NewString
(
testRSSpec1
.
Name
)
for
_
,
name
:=
range
expected
.
List
()
{
t
.
Logf
(
"Expecting update for %+v"
,
name
)
select
{
case
got
:=
<-
received
:
if
!
expected
.
Has
(
got
)
{
t
.
Errorf
(
"Expected keys %#v got %v"
,
expected
,
got
)
}
case
<-
time
.
After
(
wait
.
ForeverTestTimeout
)
:
t
.
Errorf
(
"Expected update notifications for replica sets within 100ms each"
)
}
}
}
}
func
TestControllerUpdateRequeue
(
t
*
testing
.
T
)
{
func
TestControllerUpdateRequeue
(
t
*
testing
.
T
)
{
...
...
pkg/controller/replication/replication_controller.go
View file @
63fb075f
...
@@ -353,12 +353,9 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) {
...
@@ -353,12 +353,9 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) {
return
return
}
}
curPod
:=
cur
.
(
*
api
.
Pod
)
curPod
:=
cur
.
(
*
api
.
Pod
)
rc
:=
rm
.
getPodController
(
curPod
)
if
rc
==
nil
{
return
}
oldPod
:=
old
.
(
*
api
.
Pod
)
oldPod
:=
old
.
(
*
api
.
Pod
)
glog
.
V
(
4
)
.
Infof
(
"Pod %s updated, objectMeta %+v -> %+v."
,
curPod
.
Name
,
oldPod
.
ObjectMeta
,
curPod
.
ObjectMeta
)
labelChanged
:=
!
reflect
.
DeepEqual
(
curPod
.
Labels
,
oldPod
.
Labels
)
if
curPod
.
DeletionTimestamp
!=
nil
{
if
curPod
.
DeletionTimestamp
!=
nil
{
// when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period,
// when a pod is deleted gracefully it's deletion timestamp is first modified to reflect a grace period,
// and after such time has passed, the kubelet actually deletes it from the store. We receive an update
// and after such time has passed, the kubelet actually deletes it from the store. We receive an update
...
@@ -366,11 +363,18 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) {
...
@@ -366,11 +363,18 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) {
// until the kubelet actually deletes the pod. This is different from the Phase of a pod changing, because
// until the kubelet actually deletes the pod. This is different from the Phase of a pod changing, because
// an rc never initiates a phase change, and so is never asleep waiting for the same.
// an rc never initiates a phase change, and so is never asleep waiting for the same.
rm
.
deletePod
(
curPod
)
rm
.
deletePod
(
curPod
)
if
labelChanged
{
// we don't need to check the oldPod.DeletionTimestamp because DeletionTimestamp cannot be unset.
rm
.
deletePod
(
oldPod
)
}
return
return
}
}
rm
.
enqueueController
(
rc
)
if
rc
:=
rm
.
getPodController
(
curPod
);
rc
!=
nil
{
rm
.
enqueueController
(
rc
)
}
// Only need to get the old controller if the labels changed.
// Only need to get the old controller if the labels changed.
if
!
reflect
.
DeepEqual
(
curPod
.
Labels
,
oldPod
.
Labels
)
{
if
labelChanged
{
// If the old and new rc are the same, the first one that syncs
// If the old and new rc are the same, the first one that syncs
// will set expectations preventing any damage from the second.
// will set expectations preventing any damage from the second.
if
oldRC
:=
rm
.
getPodController
(
oldPod
);
oldRC
!=
nil
{
if
oldRC
:=
rm
.
getPodController
(
oldPod
);
oldRC
!=
nil
{
...
...
pkg/controller/replication/replication_controller_test.go
View file @
63fb075f
...
@@ -531,15 +531,13 @@ func TestUpdatePods(t *testing.T) {
...
@@ -531,15 +531,13 @@ func TestUpdatePods(t *testing.T) {
testControllerSpec2
.
Name
=
"barfoo"
testControllerSpec2
.
Name
=
"barfoo"
manager
.
rcStore
.
Indexer
.
Add
(
&
testControllerSpec2
)
manager
.
rcStore
.
Indexer
.
Add
(
&
testControllerSpec2
)
// Put one pod in the podStore
// case 1: We put in the podStore a pod with labels matching
// testControllerSpec1, then update its labels to match testControllerSpec2.
// We expect to receive a sync request for both controllers.
pod1
:=
newPodList
(
manager
.
podStore
.
Indexer
,
1
,
api
.
PodRunning
,
testControllerSpec1
,
"pod"
)
.
Items
[
0
]
pod1
:=
newPodList
(
manager
.
podStore
.
Indexer
,
1
,
api
.
PodRunning
,
testControllerSpec1
,
"pod"
)
.
Items
[
0
]
pod2
:=
pod1
pod2
:=
pod1
pod2
.
Labels
=
testControllerSpec2
.
Spec
.
Selector
pod2
.
Labels
=
testControllerSpec2
.
Spec
.
Selector
// Send an update of the same pod with modified labels, and confirm we get a sync request for
// both controllers
manager
.
updatePod
(
&
pod1
,
&
pod2
)
manager
.
updatePod
(
&
pod1
,
&
pod2
)
expected
:=
sets
.
NewString
(
testControllerSpec1
.
Name
,
testControllerSpec2
.
Name
)
expected
:=
sets
.
NewString
(
testControllerSpec1
.
Name
,
testControllerSpec2
.
Name
)
for
_
,
name
:=
range
expected
.
List
()
{
for
_
,
name
:=
range
expected
.
List
()
{
t
.
Logf
(
"Expecting update for %+v"
,
name
)
t
.
Logf
(
"Expecting update for %+v"
,
name
)
...
@@ -552,6 +550,24 @@ func TestUpdatePods(t *testing.T) {
...
@@ -552,6 +550,24 @@ func TestUpdatePods(t *testing.T) {
t
.
Errorf
(
"Expected update notifications for controllers within 100ms each"
)
t
.
Errorf
(
"Expected update notifications for controllers within 100ms each"
)
}
}
}
}
// case 2: pod1 in the podStore has labels matching testControllerSpec1.
// We update its labels to match no replication controller. We expect to
// receive a sync request for testControllerSpec1.
pod2
.
Labels
=
make
(
map
[
string
]
string
)
manager
.
updatePod
(
&
pod1
,
&
pod2
)
expected
=
sets
.
NewString
(
testControllerSpec1
.
Name
)
for
_
,
name
:=
range
expected
.
List
()
{
t
.
Logf
(
"Expecting update for %+v"
,
name
)
select
{
case
got
:=
<-
received
:
if
!
expected
.
Has
(
got
)
{
t
.
Errorf
(
"Expected keys %#v got %v"
,
expected
,
got
)
}
case
<-
time
.
After
(
wait
.
ForeverTestTimeout
)
:
t
.
Errorf
(
"Expected update notifications for controllers within 100ms each"
)
}
}
}
}
func
TestControllerUpdateRequeue
(
t
*
testing
.
T
)
{
func
TestControllerUpdateRequeue
(
t
*
testing
.
T
)
{
...
...
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