mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Deployment/util: Filter by ControllerRef.
The list functions in deployment/util are used outside the Deployment controller itself. Therefore, they don't do actual adoption/orphaning. However, they still need to avoid listing things that don't belong.
This commit is contained in:
		@@ -37,6 +37,7 @@ go_library(
 | 
				
			|||||||
        "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/labels",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/labels",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/runtime",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/runtime",
 | 
				
			||||||
 | 
					        "//vendor:k8s.io/apimachinery/pkg/types",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/util/errors",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/util/errors",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/util/intstr",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/util/intstr",
 | 
				
			||||||
        "//vendor:k8s.io/apimachinery/pkg/util/wait",
 | 
					        "//vendor:k8s.io/apimachinery/pkg/util/wait",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,6 +30,7 @@ import (
 | 
				
			|||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/labels"
 | 
						"k8s.io/apimachinery/pkg/labels"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/errors"
 | 
						"k8s.io/apimachinery/pkg/util/errors"
 | 
				
			||||||
	intstrutil "k8s.io/apimachinery/pkg/util/intstr"
 | 
						intstrutil "k8s.io/apimachinery/pkg/util/intstr"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
@@ -507,7 +508,7 @@ func GetAllReplicaSets(deployment *extensions.Deployment, c clientset.Interface)
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, nil, err
 | 
							return nil, nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	podList, err := listPods(deployment, c)
 | 
						podList, err := listPods(deployment, rsList, c)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, nil, err
 | 
							return nil, nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -529,7 +530,7 @@ func GetOldReplicaSets(deployment *extensions.Deployment, c clientset.Interface)
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	podList, err := listPods(deployment, c)
 | 
						podList, err := listPods(deployment, rsList, c)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -563,8 +564,8 @@ func listReplicaSets(deployment *extensions.Deployment, c clientset.Interface) (
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// listReplicaSets lists all Pods the given deployment targets with the given client interface.
 | 
					// listReplicaSets lists all Pods the given deployment targets with the given client interface.
 | 
				
			||||||
func listPods(deployment *extensions.Deployment, c clientset.Interface) (*v1.PodList, error) {
 | 
					func listPods(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet, c clientset.Interface) (*v1.PodList, error) {
 | 
				
			||||||
	return ListPods(deployment,
 | 
						return ListPods(deployment, rsList,
 | 
				
			||||||
		func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
 | 
							func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
 | 
				
			||||||
			return c.Core().Pods(namespace).List(options)
 | 
								return c.Core().Pods(namespace).List(options)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -575,28 +576,65 @@ type rsListFunc func(string, metav1.ListOptions) ([]*extensions.ReplicaSet, erro
 | 
				
			|||||||
type podListFunc func(string, metav1.ListOptions) (*v1.PodList, error)
 | 
					type podListFunc func(string, metav1.ListOptions) (*v1.PodList, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ListReplicaSets returns a slice of RSes the given deployment targets.
 | 
					// ListReplicaSets returns a slice of RSes the given deployment targets.
 | 
				
			||||||
 | 
					// Note that this does NOT attempt to reconcile ControllerRef (adopt/orphan),
 | 
				
			||||||
 | 
					// because only the controller itself should do that.
 | 
				
			||||||
 | 
					// However, it does filter out anything whose ControllerRef doesn't match.
 | 
				
			||||||
func ListReplicaSets(deployment *extensions.Deployment, getRSList rsListFunc) ([]*extensions.ReplicaSet, error) {
 | 
					func ListReplicaSets(deployment *extensions.Deployment, getRSList rsListFunc) ([]*extensions.ReplicaSet, error) {
 | 
				
			||||||
	// TODO: Right now we list replica sets by their labels. We should list them by selector, i.e. the replica set's selector
 | 
						// TODO: Right now we list replica sets by their labels. We should list them by selector, i.e. the replica set's selector
 | 
				
			||||||
	//       should be a superset of the deployment's selector, see https://github.com/kubernetes/kubernetes/issues/19830;
 | 
						//       should be a superset of the deployment's selector, see https://github.com/kubernetes/kubernetes/issues/19830.
 | 
				
			||||||
	//       or use controllerRef, see https://github.com/kubernetes/kubernetes/issues/2210
 | 
					 | 
				
			||||||
	namespace := deployment.Namespace
 | 
						namespace := deployment.Namespace
 | 
				
			||||||
	selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
 | 
						selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	options := metav1.ListOptions{LabelSelector: selector.String()}
 | 
						options := metav1.ListOptions{LabelSelector: selector.String()}
 | 
				
			||||||
	return getRSList(namespace, options)
 | 
						all, err := getRSList(namespace, options)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return all, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Only include those whose ControllerRef matches the Deployment.
 | 
				
			||||||
 | 
						owned := make([]*extensions.ReplicaSet, 0, len(all))
 | 
				
			||||||
 | 
						for _, rs := range all {
 | 
				
			||||||
 | 
							controllerRef := controller.GetControllerOf(rs)
 | 
				
			||||||
 | 
							if controllerRef != nil && controllerRef.UID == deployment.UID {
 | 
				
			||||||
 | 
								owned = append(owned, rs)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return owned, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ListPods returns a list of pods the given deployment targets.
 | 
					// ListPods returns a list of pods the given deployment targets.
 | 
				
			||||||
func ListPods(deployment *extensions.Deployment, getPodList podListFunc) (*v1.PodList, error) {
 | 
					// This needs a list of ReplicaSets for the Deployment,
 | 
				
			||||||
 | 
					// which can be found with ListReplicaSets().
 | 
				
			||||||
 | 
					// Note that this does NOT attempt to reconcile ControllerRef (adopt/orphan),
 | 
				
			||||||
 | 
					// because only the controller itself should do that.
 | 
				
			||||||
 | 
					// However, it does filter out anything whose ControllerRef doesn't match.
 | 
				
			||||||
 | 
					func ListPods(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet, getPodList podListFunc) (*v1.PodList, error) {
 | 
				
			||||||
	namespace := deployment.Namespace
 | 
						namespace := deployment.Namespace
 | 
				
			||||||
	selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
 | 
						selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	options := metav1.ListOptions{LabelSelector: selector.String()}
 | 
						options := metav1.ListOptions{LabelSelector: selector.String()}
 | 
				
			||||||
	return getPodList(namespace, options)
 | 
						all, err := getPodList(namespace, options)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return all, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Only include those whose ControllerRef points to a ReplicaSet that is in
 | 
				
			||||||
 | 
						// turn owned by this Deployment.
 | 
				
			||||||
 | 
						rsMap := make(map[types.UID]bool, len(rsList))
 | 
				
			||||||
 | 
						for _, rs := range rsList {
 | 
				
			||||||
 | 
							rsMap[rs.UID] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						owned := &v1.PodList{Items: make([]v1.Pod, 0, len(all.Items))}
 | 
				
			||||||
 | 
						for i := range all.Items {
 | 
				
			||||||
 | 
							pod := &all.Items[i]
 | 
				
			||||||
 | 
							controllerRef := controller.GetControllerOf(pod)
 | 
				
			||||||
 | 
							if controllerRef != nil && rsMap[controllerRef.UID] {
 | 
				
			||||||
 | 
								owned.Items = append(owned.Items, *pod)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return owned, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EqualIgnoreHash returns true if two given podTemplateSpec are equal, ignoring the diff in value of Labels[pod-template-hash]
 | 
					// EqualIgnoreHash returns true if two given podTemplateSpec are equal, ignoring the diff in value of Labels[pod-template-hash]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,11 +105,23 @@ func newPod(now time.Time, ready bool, beforeSec int) v1.Pod {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newRSControllerRef(rs *extensions.ReplicaSet) *metav1.OwnerReference {
 | 
				
			||||||
 | 
						isController := true
 | 
				
			||||||
 | 
						return &metav1.OwnerReference{
 | 
				
			||||||
 | 
							APIVersion: "extensions/v1beta1",
 | 
				
			||||||
 | 
							Kind:       "ReplicaSet",
 | 
				
			||||||
 | 
							Name:       rs.GetName(),
 | 
				
			||||||
 | 
							UID:        rs.GetUID(),
 | 
				
			||||||
 | 
							Controller: &isController,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// generatePodFromRS creates a pod, with the input ReplicaSet's selector and its template
 | 
					// generatePodFromRS creates a pod, with the input ReplicaSet's selector and its template
 | 
				
			||||||
func generatePodFromRS(rs extensions.ReplicaSet) v1.Pod {
 | 
					func generatePodFromRS(rs extensions.ReplicaSet) v1.Pod {
 | 
				
			||||||
	return v1.Pod{
 | 
						return v1.Pod{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
			Labels: rs.Labels,
 | 
								Labels:          rs.Labels,
 | 
				
			||||||
 | 
								OwnerReferences: []metav1.OwnerReference{*newRSControllerRef(&rs)},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Spec: rs.Spec.Template.Spec,
 | 
							Spec: rs.Spec.Template.Spec,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -161,14 +173,26 @@ func generateRSWithLabel(labels map[string]string, image string) extensions.Repl
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newDControllerRef(d *extensions.Deployment) *metav1.OwnerReference {
 | 
				
			||||||
 | 
						isController := true
 | 
				
			||||||
 | 
						return &metav1.OwnerReference{
 | 
				
			||||||
 | 
							APIVersion: "extensions/v1beta1",
 | 
				
			||||||
 | 
							Kind:       "Deployment",
 | 
				
			||||||
 | 
							Name:       d.GetName(),
 | 
				
			||||||
 | 
							UID:        d.GetUID(),
 | 
				
			||||||
 | 
							Controller: &isController,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// generateRS creates a replica set, with the input deployment's template as its template
 | 
					// generateRS creates a replica set, with the input deployment's template as its template
 | 
				
			||||||
func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
 | 
					func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
 | 
				
			||||||
	template := GetNewReplicaSetTemplate(&deployment)
 | 
						template := GetNewReplicaSetTemplate(&deployment)
 | 
				
			||||||
	return extensions.ReplicaSet{
 | 
						return extensions.ReplicaSet{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
			UID:    randomUID(),
 | 
								UID:             randomUID(),
 | 
				
			||||||
			Name:   v1.SimpleNameGenerator.GenerateName("replicaset"),
 | 
								Name:            v1.SimpleNameGenerator.GenerateName("replicaset"),
 | 
				
			||||||
			Labels: template.Labels,
 | 
								Labels:          template.Labels,
 | 
				
			||||||
 | 
								OwnerReferences: []metav1.OwnerReference{*newDControllerRef(&deployment)},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Spec: extensions.ReplicaSetSpec{
 | 
							Spec: extensions.ReplicaSetSpec{
 | 
				
			||||||
			Replicas: func() *int32 { i := int32(0); return &i }(),
 | 
								Replicas: func() *int32 { i := int32(0); return &i }(),
 | 
				
			||||||
@@ -291,7 +315,8 @@ func TestGetOldRCs(t *testing.T) {
 | 
				
			|||||||
	oldRS2.Status.FullyLabeledReplicas = *(oldRS2.Spec.Replicas)
 | 
						oldRS2.Status.FullyLabeledReplicas = *(oldRS2.Spec.Replicas)
 | 
				
			||||||
	oldPod2 := generatePodFromRS(oldRS2)
 | 
						oldPod2 := generatePodFromRS(oldRS2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// create 1 ReplicaSet that existed before the deployment, with the same labels as the deployment
 | 
						// create 1 ReplicaSet that existed before the deployment,
 | 
				
			||||||
 | 
						// with the same labels as the deployment, but no ControllerRef.
 | 
				
			||||||
	existedPod := generatePod(newDeployment.Spec.Template.Labels, "foo")
 | 
						existedPod := generatePod(newDeployment.Spec.Template.Labels, "foo")
 | 
				
			||||||
	existedRS := generateRSWithLabel(newDeployment.Spec.Template.Labels, "foo")
 | 
						existedRS := generateRSWithLabel(newDeployment.Spec.Template.Labels, "foo")
 | 
				
			||||||
	existedRS.Status.FullyLabeledReplicas = *(existedRS.Spec.Replicas)
 | 
						existedRS.Status.FullyLabeledReplicas = *(existedRS.Spec.Replicas)
 | 
				
			||||||
@@ -345,7 +370,7 @@ func TestGetOldRCs(t *testing.T) {
 | 
				
			|||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			[]*extensions.ReplicaSet{&oldRS, &oldRS2, &existedRS},
 | 
								[]*extensions.ReplicaSet{&oldRS, &oldRS2},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3515,7 +3515,22 @@ func WaitForDeploymentWithCondition(c clientset.Interface, ns, deploymentName, r
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func logPodsOfDeployment(c clientset.Interface, deployment *extensions.Deployment) {
 | 
					func logPodsOfDeployment(c clientset.Interface, deployment *extensions.Deployment) {
 | 
				
			||||||
	minReadySeconds := deployment.Spec.MinReadySeconds
 | 
						minReadySeconds := deployment.Spec.MinReadySeconds
 | 
				
			||||||
	podList, err := deploymentutil.ListPods(deployment,
 | 
						rsList, err := deploymentutil.ListReplicaSets(deployment,
 | 
				
			||||||
 | 
							func(namespace string, options metav1.ListOptions) ([]*extensions.ReplicaSet, error) {
 | 
				
			||||||
 | 
								rsList, err := c.Extensions().ReplicaSets(namespace).List(options)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								ret := make([]*extensions.ReplicaSet, 0, len(rsList.Items))
 | 
				
			||||||
 | 
								for i := range rsList.Items {
 | 
				
			||||||
 | 
									ret = append(ret, &rsList.Items[i])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return ret, nil
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							Logf("Failed to list ReplicaSets of Deployment %s: %v", deployment.Name, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						podList, err := deploymentutil.ListPods(deployment, rsList,
 | 
				
			||||||
		func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
 | 
							func(namespace string, options metav1.ListOptions) (*v1.PodList, error) {
 | 
				
			||||||
			return c.Core().Pods(namespace).List(options)
 | 
								return c.Core().Pods(namespace).List(options)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user