Skip to content

Commit 71839b5

Browse files
authored
Merge pull request kubernetes#89186 from andrewsykim/e2e-framework-deployment-util
e2e/framework: remove direct imports to pkg/controller/deployment/util
2 parents 9bee074 + c1e2f14 commit 71839b5

File tree

2 files changed

+79
-10
lines changed

2 files changed

+79
-10
lines changed

test/e2e/framework/deployment/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ go_library(
1010
],
1111
importpath = "k8s.io/kubernetes/test/e2e/framework/deployment",
1212
deps = [
13-
"//pkg/controller/deployment/util:go_default_library",
1413
"//staging/src/k8s.io/api/apps/v1:go_default_library",
1514
"//staging/src/k8s.io/api/core/v1:go_default_library",
15+
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
1616
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
1717
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
1818
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",

test/e2e/framework/deployment/fixtures.go

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ package deployment
1919
import (
2020
"context"
2121
"fmt"
22+
"sort"
2223

2324
appsv1 "k8s.io/api/apps/v1"
2425
v1 "k8s.io/api/core/v1"
26+
apiequality "k8s.io/apimachinery/pkg/api/equality"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/apimachinery/pkg/util/uuid"
2729
clientset "k8s.io/client-go/kubernetes"
28-
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
2930
"k8s.io/kubernetes/test/e2e/framework"
3031
testutils "k8s.io/kubernetes/test/utils"
3132
imageutils "k8s.io/kubernetes/test/utils/image"
@@ -86,22 +87,90 @@ func CreateDeployment(client clientset.Interface, replicas int32, podLabels map[
8687

8788
// GetPodsForDeployment gets pods for the given deployment
8889
func GetPodsForDeployment(client clientset.Interface, deployment *appsv1.Deployment) (*v1.PodList, error) {
89-
replicaSet, err := deploymentutil.GetNewReplicaSet(deployment, client.AppsV1())
90+
replicaSetSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
9091
if err != nil {
91-
return nil, fmt.Errorf("Failed to get new replica set for deployment %q: %v", deployment.Name, err)
92+
return nil, err
9293
}
94+
95+
replicaSetListOptions := metav1.ListOptions{LabelSelector: replicaSetSelector.String()}
96+
allReplicaSets, err := client.AppsV1().ReplicaSets(deployment.Namespace).List(context.TODO(), replicaSetListOptions)
97+
if err != nil {
98+
return nil, err
99+
}
100+
101+
ownedReplicaSets := make([]*appsv1.ReplicaSet, 0, len(allReplicaSets.Items))
102+
for _, rs := range allReplicaSets.Items {
103+
if !metav1.IsControlledBy(&rs, deployment) {
104+
continue
105+
}
106+
107+
ownedReplicaSets = append(ownedReplicaSets, &rs)
108+
}
109+
110+
// We ignore pod-template-hash because:
111+
// 1. The hash result would be different upon podTemplateSpec API changes
112+
// (e.g. the addition of a new field will cause the hash code to change)
113+
// 2. The deployment template won't have hash labels
114+
podTemplatesEqualsIgnoringHash := func(template1, template2 *v1.PodTemplateSpec) bool {
115+
t1Copy := template1.DeepCopy()
116+
t2Copy := template2.DeepCopy()
117+
// Remove hash labels from template.Labels before comparing
118+
delete(t1Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey)
119+
delete(t2Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey)
120+
return apiequality.Semantic.DeepEqual(t1Copy, t2Copy)
121+
}
122+
123+
var replicaSet *appsv1.ReplicaSet
124+
// In rare cases, such as after cluster upgrades, Deployment may end up with
125+
// having more than one new ReplicaSets that have the same template as its template,
126+
// see https://github.com/kubernetes/kubernetes/issues/40415
127+
// We deterministically choose the oldest new ReplicaSet.
128+
sort.Sort(replicaSetsByCreationTimestamp(ownedReplicaSets))
129+
for _, rs := range ownedReplicaSets {
130+
if !podTemplatesEqualsIgnoringHash(&rs.Spec.Template, &deployment.Spec.Template) {
131+
continue
132+
}
133+
134+
replicaSet = rs
135+
break
136+
}
137+
93138
if replicaSet == nil {
94139
return nil, fmt.Errorf("expected a new replica set for deployment %q, found none", deployment.Name)
95140
}
96-
podListFunc := func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
97-
return client.CoreV1().Pods(namespace).List(context.TODO(), options)
141+
142+
podSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
143+
if err != nil {
144+
return nil, err
98145
}
99-
rsList := []*appsv1.ReplicaSet{replicaSet}
100-
podList, err := deploymentutil.ListPods(deployment, rsList, podListFunc)
146+
podListOptions := metav1.ListOptions{LabelSelector: podSelector.String()}
147+
allPods, err := client.CoreV1().Pods(deployment.Namespace).List(context.TODO(), podListOptions)
101148
if err != nil {
102-
return nil, fmt.Errorf("Failed to list Pods of Deployment %q: %v", deployment.Name, err)
149+
return nil, err
150+
}
151+
152+
replicaSetUID := replicaSet.UID
153+
ownedPods := &v1.PodList{Items: make([]v1.Pod, 0, len(allPods.Items))}
154+
for _, pod := range allPods.Items {
155+
controllerRef := metav1.GetControllerOf(&pod)
156+
if controllerRef != nil && controllerRef.UID == replicaSetUID {
157+
ownedPods.Items = append(ownedPods.Items, pod)
158+
}
159+
}
160+
161+
return ownedPods, nil
162+
}
163+
164+
// replicaSetsByCreationTimestamp sorts a list of ReplicaSet by creation timestamp, using their names as a tie breaker.
165+
type replicaSetsByCreationTimestamp []*appsv1.ReplicaSet
166+
167+
func (o replicaSetsByCreationTimestamp) Len() int { return len(o) }
168+
func (o replicaSetsByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
169+
func (o replicaSetsByCreationTimestamp) Less(i, j int) bool {
170+
if o[i].CreationTimestamp.Equal(&o[j].CreationTimestamp) {
171+
return o[i].Name < o[j].Name
103172
}
104-
return podList, nil
173+
return o[i].CreationTimestamp.Before(&o[j].CreationTimestamp)
105174
}
106175

107176
// testDeployment creates a deployment definition based on the namespace. The deployment references the PVC's

0 commit comments

Comments
 (0)