AllNodesReady waits for all system pods to be running
This commit is contained in:
		| @@ -167,6 +167,13 @@ var ( | ||||
|  | ||||
| 	// For parsing Kubectl version for version-skewed testing. | ||||
| 	gitVersionRegexp = regexp.MustCompile("GitVersion:\"(v.+?)\"") | ||||
|  | ||||
| 	// Slice of regexps for names of pods that have to be running to consider a Node "healthy" | ||||
| 	requiredPerNodePods = []*regexp.Regexp{ | ||||
| 		regexp.MustCompile(".*kube-proxy.*"), | ||||
| 		regexp.MustCompile(".*fluentd-elasticsearch.*"), | ||||
| 		regexp.MustCompile(".*node-problem-detector.*"), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // GetServerArchitecture fetches the architecture of the cluster's apiserver. | ||||
| @@ -4003,7 +4010,10 @@ func WaitForNodeToBe(c *client.Client, name string, conditionType api.NodeCondit | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // checks whether all registered nodes are ready | ||||
| // Checks whether all registered nodes are ready. | ||||
| // TODO: we should change the AllNodesReady call in AfterEach to WaitForAllNodesHealthy, | ||||
| // and figure out how to do it in a configurable way, as we can't expect all setups to run | ||||
| // default test add-ons. | ||||
| func AllNodesReady(c *client.Client, timeout time.Duration) error { | ||||
| 	Logf("Waiting up to %v for all nodes to be ready", timeout) | ||||
|  | ||||
| @@ -4033,6 +4043,71 @@ func AllNodesReady(c *client.Client, timeout time.Duration) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // checks whether all registered nodes are ready and all required Pods are running on them. | ||||
| func WaitForAllNodesHealthy(c *client.Client, timeout time.Duration) error { | ||||
| 	Logf("Waiting up to %v for all nodes to be ready", timeout) | ||||
|  | ||||
| 	var notReady []api.Node | ||||
| 	var missingPodsPerNode map[string][]string | ||||
| 	err := wait.PollImmediate(Poll, timeout, func() (bool, error) { | ||||
| 		notReady = nil | ||||
| 		// It should be OK to list unschedulable Nodes here. | ||||
| 		nodes, err := c.Nodes().List(api.ListOptions{ResourceVersion: "0"}) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
| 		for _, node := range nodes.Items { | ||||
| 			if !IsNodeConditionSetAsExpected(&node, api.NodeReady, true) { | ||||
| 				notReady = append(notReady, node) | ||||
| 			} | ||||
| 		} | ||||
| 		pods, err := c.Pods(api.NamespaceAll).List(api.ListOptions{ResourceVersion: "0"}) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
|  | ||||
| 		systemPodsPerNode := make(map[string][]string) | ||||
| 		for _, pod := range pods.Items { | ||||
| 			if pod.Namespace == api.NamespaceSystem && pod.Status.Phase == api.PodRunning { | ||||
| 				if pod.Spec.NodeName != "" { | ||||
| 					systemPodsPerNode[pod.Spec.NodeName] = append(systemPodsPerNode[pod.Spec.NodeName], pod.Name) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		missingPodsPerNode = make(map[string][]string) | ||||
| 		for _, node := range nodes.Items { | ||||
| 			if !system.IsMasterNode(&node) { | ||||
| 				for _, requiredPod := range requiredPerNodePods { | ||||
| 					foundRequired := false | ||||
| 					for _, presentPod := range systemPodsPerNode[node.Name] { | ||||
| 						if requiredPod.MatchString(presentPod) { | ||||
| 							foundRequired = true | ||||
| 							break | ||||
| 						} | ||||
| 					} | ||||
| 					if !foundRequired { | ||||
| 						missingPodsPerNode[node.Name] = append(missingPodsPerNode[node.Name], requiredPod.String()) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return len(notReady) == 0 && len(missingPodsPerNode) == 0, nil | ||||
| 	}) | ||||
|  | ||||
| 	if err != nil && err != wait.ErrWaitTimeout { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if len(notReady) > 0 { | ||||
| 		return fmt.Errorf("Not ready nodes: %v", notReady) | ||||
| 	} | ||||
| 	if len(missingPodsPerNode) > 0 { | ||||
| 		return fmt.Errorf("Not running system Pods: %v", missingPodsPerNode) | ||||
| 	} | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // Filters nodes in NodeList in place, removing nodes that do not | ||||
| // satisfy the given condition | ||||
| // TODO: consider merging with pkg/client/cache.NodeLister | ||||
|   | ||||
| @@ -198,6 +198,7 @@ var _ = framework.KubeDescribe("SchedulerPredicates [Serial]", func() { | ||||
| 		ns = f.Namespace.Name | ||||
| 		nodeList = &api.NodeList{} | ||||
|  | ||||
| 		framework.WaitForAllNodesHealthy(c, time.Minute) | ||||
| 		masterNodes, nodeList = framework.GetMasterAndWorkerNodesOrDie(c) | ||||
|  | ||||
| 		err := framework.CheckTestingNSDeletedExcept(c, ns) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 gmarek
					gmarek