mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Merge pull request #89186 from andrewsykim/e2e-framework-deployment-util
e2e/framework: remove direct imports to pkg/controller/deployment/util
This commit is contained in:
commit
71839b58e3
@ -10,9 +10,9 @@ go_library(
|
|||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/test/e2e/framework/deployment",
|
importpath = "k8s.io/kubernetes/test/e2e/framework/deployment",
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/controller/deployment/util:go_default_library",
|
|
||||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
|
@ -19,13 +19,14 @@ package deployment
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
|
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
testutils "k8s.io/kubernetes/test/utils"
|
testutils "k8s.io/kubernetes/test/utils"
|
||||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||||
@ -86,22 +87,90 @@ func CreateDeployment(client clientset.Interface, replicas int32, podLabels map[
|
|||||||
|
|
||||||
// GetPodsForDeployment gets pods for the given deployment
|
// GetPodsForDeployment gets pods for the given deployment
|
||||||
func GetPodsForDeployment(client clientset.Interface, deployment *appsv1.Deployment) (*v1.PodList, error) {
|
func GetPodsForDeployment(client clientset.Interface, deployment *appsv1.Deployment) (*v1.PodList, error) {
|
||||||
replicaSet, err := deploymentutil.GetNewReplicaSet(deployment, client.AppsV1())
|
replicaSetSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to get new replica set for deployment %q: %v", deployment.Name, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replicaSetListOptions := metav1.ListOptions{LabelSelector: replicaSetSelector.String()}
|
||||||
|
allReplicaSets, err := client.AppsV1().ReplicaSets(deployment.Namespace).List(context.TODO(), replicaSetListOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ownedReplicaSets := make([]*appsv1.ReplicaSet, 0, len(allReplicaSets.Items))
|
||||||
|
for _, rs := range allReplicaSets.Items {
|
||||||
|
if !metav1.IsControlledBy(&rs, deployment) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ownedReplicaSets = append(ownedReplicaSets, &rs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We ignore pod-template-hash because:
|
||||||
|
// 1. The hash result would be different upon podTemplateSpec API changes
|
||||||
|
// (e.g. the addition of a new field will cause the hash code to change)
|
||||||
|
// 2. The deployment template won't have hash labels
|
||||||
|
podTemplatesEqualsIgnoringHash := func(template1, template2 *v1.PodTemplateSpec) bool {
|
||||||
|
t1Copy := template1.DeepCopy()
|
||||||
|
t2Copy := template2.DeepCopy()
|
||||||
|
// Remove hash labels from template.Labels before comparing
|
||||||
|
delete(t1Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey)
|
||||||
|
delete(t2Copy.Labels, appsv1.DefaultDeploymentUniqueLabelKey)
|
||||||
|
return apiequality.Semantic.DeepEqual(t1Copy, t2Copy)
|
||||||
|
}
|
||||||
|
|
||||||
|
var replicaSet *appsv1.ReplicaSet
|
||||||
|
// In rare cases, such as after cluster upgrades, Deployment may end up with
|
||||||
|
// having more than one new ReplicaSets that have the same template as its template,
|
||||||
|
// see https://github.com/kubernetes/kubernetes/issues/40415
|
||||||
|
// We deterministically choose the oldest new ReplicaSet.
|
||||||
|
sort.Sort(replicaSetsByCreationTimestamp(ownedReplicaSets))
|
||||||
|
for _, rs := range ownedReplicaSets {
|
||||||
|
if !podTemplatesEqualsIgnoringHash(&rs.Spec.Template, &deployment.Spec.Template) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
replicaSet = rs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if replicaSet == nil {
|
if replicaSet == nil {
|
||||||
return nil, fmt.Errorf("expected a new replica set for deployment %q, found none", deployment.Name)
|
return nil, fmt.Errorf("expected a new replica set for deployment %q, found none", deployment.Name)
|
||||||
}
|
}
|
||||||
podListFunc := func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
|
|
||||||
return client.CoreV1().Pods(namespace).List(context.TODO(), options)
|
podSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||||
}
|
|
||||||
rsList := []*appsv1.ReplicaSet{replicaSet}
|
|
||||||
podList, err := deploymentutil.ListPods(deployment, rsList, podListFunc)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to list Pods of Deployment %q: %v", deployment.Name, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
return podList, nil
|
podListOptions := metav1.ListOptions{LabelSelector: podSelector.String()}
|
||||||
|
allPods, err := client.CoreV1().Pods(deployment.Namespace).List(context.TODO(), podListOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
replicaSetUID := replicaSet.UID
|
||||||
|
ownedPods := &v1.PodList{Items: make([]v1.Pod, 0, len(allPods.Items))}
|
||||||
|
for _, pod := range allPods.Items {
|
||||||
|
controllerRef := metav1.GetControllerOf(&pod)
|
||||||
|
if controllerRef != nil && controllerRef.UID == replicaSetUID {
|
||||||
|
ownedPods.Items = append(ownedPods.Items, pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ownedPods, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// replicaSetsByCreationTimestamp sorts a list of ReplicaSet by creation timestamp, using their names as a tie breaker.
|
||||||
|
type replicaSetsByCreationTimestamp []*appsv1.ReplicaSet
|
||||||
|
|
||||||
|
func (o replicaSetsByCreationTimestamp) Len() int { return len(o) }
|
||||||
|
func (o replicaSetsByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||||
|
func (o replicaSetsByCreationTimestamp) Less(i, j int) bool {
|
||||||
|
if o[i].CreationTimestamp.Equal(&o[j].CreationTimestamp) {
|
||||||
|
return o[i].Name < o[j].Name
|
||||||
|
}
|
||||||
|
return o[i].CreationTimestamp.Before(&o[j].CreationTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// testDeployment creates a deployment definition based on the namespace. The deployment references the PVC's
|
// testDeployment creates a deployment definition based on the namespace. The deployment references the PVC's
|
||||||
|
Loading…
Reference in New Issue
Block a user