...

Source file src/k8s.io/kubernetes/test/e2e/apps/wait.go

Documentation: k8s.io/kubernetes/test/e2e/apps

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package apps
    18  
    19  import (
    20  	"context"
    21  
    22  	appsv1 "k8s.io/api/apps/v1"
    23  	v1 "k8s.io/api/core/v1"
    24  	clientset "k8s.io/client-go/kubernetes"
    25  
    26  	podutil "k8s.io/kubernetes/pkg/api/v1/pod"
    27  	"k8s.io/kubernetes/test/e2e/framework"
    28  	e2estatefulset "k8s.io/kubernetes/test/e2e/framework/statefulset"
    29  )
    30  
    31  // waitForPartitionedRollingUpdate waits for all Pods in set to exist and have the correct revision. set must have
    32  // a RollingUpdateStatefulSetStrategyType with a non-nil RollingUpdate and Partition. All Pods with ordinals less
    33  // than or equal to the Partition are expected to be at set's current revision. All other Pods are expected to be
    34  // at its update revision.
    35  func waitForPartitionedRollingUpdate(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet) (*appsv1.StatefulSet, *v1.PodList) {
    36  	var pods *v1.PodList
    37  	if set.Spec.UpdateStrategy.Type != appsv1.RollingUpdateStatefulSetStrategyType {
    38  		framework.Failf("StatefulSet %s/%s attempt to wait for partitioned update with updateStrategy %s",
    39  			set.Namespace,
    40  			set.Name,
    41  			set.Spec.UpdateStrategy.Type)
    42  	}
    43  	if set.Spec.UpdateStrategy.RollingUpdate == nil || set.Spec.UpdateStrategy.RollingUpdate.Partition == nil {
    44  		framework.Failf("StatefulSet %s/%s attempt to wait for partitioned update with nil RollingUpdate or nil Partition",
    45  			set.Namespace,
    46  			set.Name)
    47  	}
    48  	e2estatefulset.WaitForState(ctx, c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
    49  		set = set2
    50  		pods = pods2
    51  		partition := int(*set.Spec.UpdateStrategy.RollingUpdate.Partition)
    52  		if len(pods.Items) < int(*set.Spec.Replicas) {
    53  			return false, nil
    54  		}
    55  		if partition <= 0 && set.Status.UpdateRevision != set.Status.CurrentRevision {
    56  			framework.Logf("Waiting for StatefulSet %s/%s to complete update",
    57  				set.Namespace,
    58  				set.Name,
    59  			)
    60  			e2estatefulset.SortStatefulPods(pods)
    61  			for i := range pods.Items {
    62  				if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
    63  					framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
    64  						pods.Items[i].Namespace,
    65  						pods.Items[i].Name,
    66  						set.Status.UpdateRevision,
    67  						pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
    68  				}
    69  			}
    70  			return false, nil
    71  		}
    72  		for i := int(*set.Spec.Replicas) - 1; i >= partition; i-- {
    73  			if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
    74  				framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
    75  					pods.Items[i].Namespace,
    76  					pods.Items[i].Name,
    77  					set.Status.UpdateRevision,
    78  					pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
    79  				return false, nil
    80  			}
    81  		}
    82  		return true, nil
    83  	})
    84  	return set, pods
    85  }
    86  
    87  // waitForStatus waits for the StatefulSetStatus's ObservedGeneration to be greater than or equal to set's Generation.
    88  // The returned StatefulSet contains such a StatefulSetStatus
    89  func waitForStatus(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet) *appsv1.StatefulSet {
    90  	e2estatefulset.WaitForState(ctx, c, set, func(set2 *appsv1.StatefulSet, pods *v1.PodList) (bool, error) {
    91  		if set2.Status.ObservedGeneration >= set.Generation {
    92  			set = set2
    93  			return true, nil
    94  		}
    95  		return false, nil
    96  	})
    97  	return set
    98  }
    99  
   100  // waitForPodNames waits for the StatefulSet's pods to match expected names.
   101  func waitForPodNames(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet, expectedPodNames []string) {
   102  	e2estatefulset.WaitForState(ctx, c, set,
   103  		func(intSet *appsv1.StatefulSet, pods *v1.PodList) (bool, error) {
   104  			if err := expectPodNames(pods, expectedPodNames); err != nil {
   105  				framework.Logf("Currently %v", err)
   106  				return false, nil
   107  			}
   108  			return true, nil
   109  		})
   110  }
   111  
   112  // waitForStatus waits for the StatefulSetStatus's CurrentReplicas to be equal to expectedReplicas
   113  // The returned StatefulSet contains such a StatefulSetStatus
   114  func waitForStatusCurrentReplicas(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet, expectedReplicas int32) *appsv1.StatefulSet {
   115  	e2estatefulset.WaitForState(ctx, c, set, func(set2 *appsv1.StatefulSet, pods *v1.PodList) (bool, error) {
   116  		if set2.Status.ObservedGeneration >= set.Generation && set2.Status.CurrentReplicas == expectedReplicas {
   117  			set = set2
   118  			return true, nil
   119  		}
   120  		return false, nil
   121  	})
   122  	return set
   123  }
   124  
   125  // waitForPodNotReady waits for the Pod named podName in set to exist and to not have a Ready condition.
   126  func waitForPodNotReady(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet, podName string) (*appsv1.StatefulSet, *v1.PodList) {
   127  	var pods *v1.PodList
   128  	e2estatefulset.WaitForState(ctx, c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
   129  		set = set2
   130  		pods = pods2
   131  		for i := range pods.Items {
   132  			if pods.Items[i].Name == podName {
   133  				return !podutil.IsPodReady(&pods.Items[i]), nil
   134  			}
   135  		}
   136  		return false, nil
   137  	})
   138  	return set, pods
   139  }
   140  
   141  // waitForRollingUpdate waits for all Pods in set to exist and have the correct revision and for the RollingUpdate to
   142  // complete. set must have a RollingUpdateStatefulSetStrategyType.
   143  func waitForRollingUpdate(ctx context.Context, c clientset.Interface, set *appsv1.StatefulSet) (*appsv1.StatefulSet, *v1.PodList) {
   144  	var pods *v1.PodList
   145  	if set.Spec.UpdateStrategy.Type != appsv1.RollingUpdateStatefulSetStrategyType {
   146  		framework.Failf("StatefulSet %s/%s attempt to wait for rolling update with updateStrategy %s",
   147  			set.Namespace,
   148  			set.Name,
   149  			set.Spec.UpdateStrategy.Type)
   150  	}
   151  	e2estatefulset.WaitForState(ctx, c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
   152  		set = set2
   153  		pods = pods2
   154  		if len(pods.Items) < int(*set.Spec.Replicas) {
   155  			return false, nil
   156  		}
   157  		if set.Status.UpdateRevision != set.Status.CurrentRevision {
   158  			framework.Logf("Waiting for StatefulSet %s/%s to complete update",
   159  				set.Namespace,
   160  				set.Name,
   161  			)
   162  			e2estatefulset.SortStatefulPods(pods)
   163  			for i := range pods.Items {
   164  				if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
   165  					framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
   166  						pods.Items[i].Namespace,
   167  						pods.Items[i].Name,
   168  						set.Status.UpdateRevision,
   169  						pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
   170  				}
   171  			}
   172  			return false, nil
   173  		}
   174  		return true, nil
   175  	})
   176  	return set, pods
   177  }
   178  
   179  // waitForRunningAndNotReady waits for numStatefulPods in ss to be Running and not Ready.
   180  func waitForRunningAndNotReady(ctx context.Context, c clientset.Interface, numStatefulPods int32, ss *appsv1.StatefulSet) {
   181  	e2estatefulset.WaitForRunning(ctx, c, numStatefulPods, 0, ss)
   182  }
   183  

View as plain text