// OverlapsWith returns true when two given deployments are different and overlap with each other func OverlapsWith(current, other *extensions.Deployment) (bool, error) { if current.UID == other.UID { return false, nil } currentSelector, err := metav1.LabelSelectorAsSelector(current.Spec.Selector) if err != nil { return false, fmt.Errorf("deployment %s/%s has invalid label selector: %v", current.Namespace, current.Name, err) } otherSelector, err := metav1.LabelSelectorAsSelector(other.Spec.Selector) if err != nil { return false, fmt.Errorf("deployment %s/%s has invalid label selector: %v", other.Namespace, other.Name, err) } return (!currentSelector.Empty() && currentSelector.Matches(labels.Set(other.Spec.Template.Labels))) || (!otherSelector.Empty() && otherSelector.Matches(labels.Set(current.Spec.Template.Labels))), nil }
// getPodDisruptionBudgets returns any PDBs that match the pod or err if there's an error. func (r *EvictionREST) getPodDisruptionBudgets(ctx api.Context, pod *api.Pod) ([]policy.PodDisruptionBudget, error) { if len(pod.Labels) == 0 { return nil, nil } pdbList, err := r.podDisruptionBudgetClient.PodDisruptionBudgets(pod.Namespace).List(api.ListOptions{}) if err != nil { return nil, err } var pdbs []policy.PodDisruptionBudget for _, pdb := range pdbList.Items { if pdb.Namespace != pod.Namespace { continue } selector, err := metav1.LabelSelectorAsSelector(pdb.Spec.Selector) if err != nil { continue } // If a PDB with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } pdbs = append(pdbs, pdb) } return pdbs, nil }
// GetPodDaemonSets returns a list of daemon sets managing a pod. // Returns an error if and only if no matching daemon sets are found. func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *v1.Pod) (daemonSets []extensions.DaemonSet, err error) { var selector labels.Selector var daemonSet extensions.DaemonSet if len(pod.Labels) == 0 { err = fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) return } for _, m := range s.Store.List() { daemonSet = *m.(*extensions.DaemonSet) if daemonSet.Namespace != pod.Namespace { continue } selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector) if err != nil { // this should not happen if the DaemonSet passed validation return nil, err } // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } daemonSets = append(daemonSets, daemonSet) } if len(daemonSets) == 0 { err = fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
// ValidateStatefulSetSpec tests if required fields in the StatefulSet spec are set. func ValidateStatefulSetSpec(spec *apps.StatefulSetSpec, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) if spec.Selector == nil { allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) } else { allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) if len(spec.Selector.MatchLabels)+len(spec.Selector.MatchExpressions) == 0 { allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "empty selector is not valid for statefulset.")) } } selector, err := metav1.LabelSelectorAsSelector(spec.Selector) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "")) } else { allErrs = append(allErrs, ValidatePodTemplateSpecForStatefulSet(&spec.Template, selector, fldPath.Child("template"))...) } if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) } return allErrs }
// GetDeploymentsForDeployments returns a list of deployments managing a pod. Returns an error only if no matching deployments are found. // TODO eliminate shallow copies func (s *StoreToDeploymentLister) GetDeploymentsForPod(pod *v1.Pod) (deployments []*extensions.Deployment, err error) { if len(pod.Labels) == 0 { err = fmt.Errorf("no deployments found for Pod %v because it has no labels", pod.Name) return } if len(pod.Labels[extensions.DefaultDeploymentUniqueLabelKey]) == 0 { return } dList, err := s.Deployments(pod.Namespace).List(labels.Everything()) if err != nil { return } for _, d := range dList { selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } // If a deployment with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } deployments = append(deployments, d) } if len(deployments) == 0 { err = fmt.Errorf("could not find deployments set for Pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
// GetPodStatefulSets returns a list of StatefulSets managing a pod. Returns an error only if no matching StatefulSets are found. func (s *StoreToStatefulSetLister) GetPodStatefulSets(pod *v1.Pod) (psList []apps.StatefulSet, err error) { var selector labels.Selector var ps apps.StatefulSet if len(pod.Labels) == 0 { err = fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name) return } for _, m := range s.Store.List() { ps = *m.(*apps.StatefulSet) if ps.Namespace != pod.Namespace { continue } selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector) if err != nil { err = fmt.Errorf("invalid selector: %v", err) return } // If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } psList = append(psList, ps) } if len(psList) == 0 { err = fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
func TestNumberReadyStatus(t *testing.T) { manager, podControl := newTestController() addNodes(manager.nodeStore.Store, 0, 2, simpleNodeLabel) addPods(manager.podStore.Indexer, "node-0", simpleDaemonSetLabel, 1) addPods(manager.podStore.Indexer, "node-1", simpleDaemonSetLabel, 1) daemon := newDaemonSet("foo") manager.dsStore.Add(daemon) syncAndValidateDaemonSets(t, manager, daemon, podControl, 0, 0) if daemon.Status.NumberReady != 0 { t.Errorf("Wrong daemon %s status: %v", daemon.Name, daemon.Status) } selector, _ := metav1.LabelSelectorAsSelector(daemon.Spec.Selector) daemonPods, _ := manager.podStore.Pods(daemon.Namespace).List(selector) for _, pod := range daemonPods { condition := v1.PodCondition{Type: v1.PodReady, Status: v1.ConditionTrue} pod.Status.Conditions = append(pod.Status.Conditions, condition) } syncAndValidateDaemonSets(t, manager, daemon, podControl, 0, 0) if daemon.Status.NumberReady != 2 { t.Errorf("Wrong daemon %s status: %v", daemon.Name, daemon.Status) } }
func TestNumberReadyStatus(t *testing.T) { daemon := newDaemonSet("foo") manager, podControl, clientset := newTestController() var updated *extensions.DaemonSet clientset.PrependReactor("update", "daemonsets", func(action core.Action) (handled bool, ret runtime.Object, err error) { if action.GetSubresource() != "status" { return false, nil, nil } if u, ok := action.(core.UpdateAction); ok { updated = u.GetObject().(*extensions.DaemonSet) } return false, nil, nil }) addNodes(manager.nodeStore.Store, 0, 2, simpleNodeLabel) addPods(manager.podStore.Indexer, "node-0", simpleDaemonSetLabel, 1) addPods(manager.podStore.Indexer, "node-1", simpleDaemonSetLabel, 1) manager.dsStore.Add(daemon) syncAndValidateDaemonSets(t, manager, daemon, podControl, 0, 0) if updated.Status.NumberReady != 0 { t.Errorf("Wrong daemon %s status: %v", updated.Name, updated.Status) } selector, _ := metav1.LabelSelectorAsSelector(daemon.Spec.Selector) daemonPods, _ := manager.podStore.Pods(daemon.Namespace).List(selector) for _, pod := range daemonPods { condition := v1.PodCondition{Type: v1.PodReady, Status: v1.ConditionTrue} pod.Status.Conditions = append(pod.Status.Conditions, condition) } syncAndValidateDaemonSets(t, manager, daemon, podControl, 0, 0) if updated.Status.NumberReady != 2 { t.Errorf("Wrong daemon %s status: %v", updated.Name, updated.Status) } }
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found. func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *v1.Pod) (rss []*extensions.ReplicaSet, err error) { if len(pod.Labels) == 0 { err = fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) return } list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything()) if err != nil { return } for _, rs := range list { if rs.Namespace != pod.Namespace { continue } selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid selector: %v", err) } // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } rss = append(rss, rs) } if len(rss) == 0 { err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
// GetDeploymentsForReplicaSet returns a list of deployments managing a replica set. Returns an error only if no matching deployments are found. func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) (deployments []*extensions.Deployment, err error) { if len(rs.Labels) == 0 { err = fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name) return } // TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label dList, err := s.Deployments(rs.Namespace).List(labels.Everything()) if err != nil { return } for _, d := range dList { selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } // If a deployment with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) { continue } deployments = append(deployments, d) } if len(deployments) == 0 { err = fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels) } return }
func (c *PodAffinityChecker) getMatchingAntiAffinityTerms(pod *v1.Pod, allPods []*v1.Pod) ([]matchingPodAntiAffinityTerm, error) { var result []matchingPodAntiAffinityTerm for _, existingPod := range allPods { affinity, err := v1.GetAffinityFromPodAnnotations(existingPod.Annotations) if err != nil { return nil, err } if affinity != nil && affinity.PodAntiAffinity != nil { existingPodNode, err := c.info.GetNodeInfo(existingPod.Spec.NodeName) if err != nil { return nil, err } for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(existingPod, &term) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { return nil, err } match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) if match { result = append(result, matchingPodAntiAffinityTerm{term: &term, node: existingPodNode}) } } } } return result, nil }
func (p *statefulSetTester) getPodList(ps *apps.StatefulSet) *v1.PodList { selector, err := metav1.LabelSelectorAsSelector(ps.Spec.Selector) framework.ExpectNoError(err) podList, err := p.c.Core().Pods(ps.Namespace).List(v1.ListOptions{LabelSelector: selector.String()}) framework.ExpectNoError(err) return podList }
// A function that calculates how many pods from the list are in one of // the meaningful (from the replica set perspective) states. This function is // a temporary workaround against the current lack of ownerRef in pods. func AnalysePods(selectorv1 *metav1.LabelSelector, allPods []util.FederatedObject, currentTime time.Time) (map[string]PodAnalysisResult, error) { selector, err := metav1.LabelSelectorAsSelector(selectorv1) if err != nil { return nil, fmt.Errorf("invalid selector: %v", err) } result := make(map[string]PodAnalysisResult) for _, fedObject := range allPods { pod, isPod := fedObject.Object.(*api_v1.Pod) if !isPod { return nil, fmt.Errorf("invalid arg content - not a *pod") } if !selector.Empty() && selector.Matches(labels.Set(pod.Labels)) { status := result[fedObject.ClusterName] status.Total++ for _, condition := range pod.Status.Conditions { if pod.Status.Phase == api_v1.PodRunning { if condition.Type == api_v1.PodReady { status.RunningAndReady++ } } else { if condition.Type == api_v1.PodScheduled && condition.Status == api_v1.ConditionFalse && condition.Reason == "Unschedulable" && condition.LastTransitionTime.Add(UnschedulableThreshold).Before(currentTime) { status.Unschedulable++ } } } result[fedObject.ClusterName] = status } } return result, nil }
// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found. func (s *StoreToPodDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *v1.Pod) (pdbList []policy.PodDisruptionBudget, err error) { var selector labels.Selector if len(pod.Labels) == 0 { err = fmt.Errorf("no PodDisruptionBudgets found for pod %v because it has no labels", pod.Name) return } for _, m := range s.Store.List() { pdb, ok := m.(*policy.PodDisruptionBudget) if !ok { glog.Errorf("Unexpected: %v is not a PodDisruptionBudget", m) continue } if pdb.Namespace != pod.Namespace { continue } selector, err = metav1.LabelSelectorAsSelector(pdb.Spec.Selector) if err != nil { glog.Warningf("invalid selector: %v", err) // TODO(mml): add an event to the PDB continue } // If a PDB with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } pdbList = append(pdbList, *pdb) } if len(pdbList) == 0 { err = fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
func getMatchingAntiAffinityTerms(pod *v1.Pod, nodeInfoMap map[string]*schedulercache.NodeInfo) ([]matchingPodAntiAffinityTerm, error) { allNodeNames := make([]string, 0, len(nodeInfoMap)) for name := range nodeInfoMap { allNodeNames = append(allNodeNames, name) } var lock sync.Mutex var result []matchingPodAntiAffinityTerm var firstError error appendResult := func(toAppend []matchingPodAntiAffinityTerm) { lock.Lock() defer lock.Unlock() result = append(result, toAppend...) } catchError := func(err error) { lock.Lock() defer lock.Unlock() if firstError == nil { firstError = err } } processNode := func(i int) { nodeInfo := nodeInfoMap[allNodeNames[i]] node := nodeInfo.Node() if node == nil { catchError(fmt.Errorf("node not found")) return } var nodeResult []matchingPodAntiAffinityTerm for _, existingPod := range nodeInfo.PodsWithAffinity() { affinity, err := v1.GetAffinityFromPodAnnotations(existingPod.Annotations) if err != nil { catchError(err) return } if affinity == nil { continue } for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(pod, &term) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { catchError(err) return } match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) if match { nodeResult = append(nodeResult, matchingPodAntiAffinityTerm{term: &term, node: node}) } } } if len(nodeResult) > 0 { appendResult(nodeResult) } } workqueue.Parallelize(16, len(allNodeNames), processNode) return result, firstError }
func (f *factory) LogsForObject(object, options runtime.Object) (*restclient.Request, error) { clientset, err := f.clients.ClientSetForVersion(nil) if err != nil { return nil, err } switch t := object.(type) { case *api.Pod: opts, ok := options.(*api.PodLogOptions) if !ok { return nil, errors.New("provided options object is not a PodLogOptions") } return clientset.Core().Pods(t.Namespace).GetLogs(t.Name, opts), nil case *api.ReplicationController: opts, ok := options.(*api.PodLogOptions) if !ok { return nil, errors.New("provided options object is not a PodLogOptions") } selector := labels.SelectorFromSet(t.Spec.Selector) sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) } pod, numPods, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 20*time.Second, sortBy) if err != nil { return nil, err } if numPods > 1 { fmt.Fprintf(os.Stderr, "Found %v pods, using pod/%v\n", numPods, pod.Name) } return clientset.Core().Pods(pod.Namespace).GetLogs(pod.Name, opts), nil case *extensions.ReplicaSet: opts, ok := options.(*api.PodLogOptions) if !ok { return nil, errors.New("provided options object is not a PodLogOptions") } selector, err := metav1.LabelSelectorAsSelector(t.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) } pod, numPods, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 20*time.Second, sortBy) if err != nil { return nil, err } if numPods > 1 { fmt.Fprintf(os.Stderr, "Found %v pods, using pod/%v\n", numPods, pod.Name) } return clientset.Core().Pods(pod.Namespace).GetLogs(pod.Name, opts), nil default: gvks, _, err := api.Scheme.ObjectKinds(object) if err != nil { return nil, err } return nil, fmt.Errorf("cannot get the logs from %v", gvks[0]) } }
// OverlapsWith returns true when two given deployments are different and overlap with each other func OverlapsWith(current, other *extensions.Deployment) (bool, error) { if current.UID == other.UID { return false, nil } currentSelector, err := metav1.LabelSelectorAsSelector(current.Spec.Selector) if err != nil { return false, fmt.Errorf("deployment %s/%s has invalid label selector: %v", current.Namespace, current.Name, err) } otherSelector, err := metav1.LabelSelectorAsSelector(other.Spec.Selector) if err != nil { // Broken selectors from other deployments shouldn't block current deployment. Just log the error and continue. glog.V(2).Infof("Skip overlapping check: deployment %s/%s has invalid label selector: %v", other.Namespace, other.Name, err) return false, nil } return (!currentSelector.Empty() && currentSelector.Matches(labels.Set(other.Spec.Template.Labels))) || (!otherSelector.Empty() && otherSelector.Matches(labels.Set(current.Spec.Template.Labels))), nil }
// ListPods returns a list of pods the given deployment targets. func ListPods(deployment *extensions.Deployment, getPodList podListFunc) (*v1.PodList, error) { namespace := deployment.Namespace selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector) if err != nil { return nil, err } options := v1.ListOptions{LabelSelector: selector.String()} return getPodList(namespace, options) }
func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error { deployments := reaper.dClient.Deployments(namespace) replicaSets := reaper.rsClient.ReplicaSets(namespace) rsReaper := &ReplicaSetReaper{reaper.rsClient, reaper.pollInterval, reaper.timeout} deployment, err := reaper.updateDeploymentWithRetries(namespace, name, func(d *extensions.Deployment) { // set deployment's history and scale to 0 // TODO replace with patch when available: https://github.com/kubernetes/kubernetes/issues/20527 d.Spec.RevisionHistoryLimit = util.Int32Ptr(0) d.Spec.Replicas = 0 d.Spec.Paused = true }) if err != nil { return err } // Use observedGeneration to determine if the deployment controller noticed the pause. if err := deploymentutil.WaitForObservedDeploymentInternal(func() (*extensions.Deployment, error) { return deployments.Get(name, metav1.GetOptions{}) }, deployment.Generation, 1*time.Second, 1*time.Minute); err != nil { return err } // Do not cascade deletion for overlapping deployments. if len(deployment.Annotations[deploymentutil.OverlapAnnotation]) > 0 { return deployments.Delete(name, nil) } // Stop all replica sets. selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector) if err != nil { return err } options := api.ListOptions{LabelSelector: selector} rsList, err := replicaSets.List(options) if err != nil { return err } errList := []error{} for _, rc := range rsList.Items { if err := rsReaper.Stop(rc.Namespace, rc.Name, timeout, gracePeriod); err != nil { scaleGetErr, ok := err.(ScaleError) if errors.IsNotFound(err) || (ok && errors.IsNotFound(scaleGetErr.ActualError)) { continue } errList = append(errList, err) } } if len(errList) > 0 { return utilerrors.NewAggregate(errList) } // Delete deployment at the end. // Note: We delete deployment at the end so that if removing RSs fails, we at least have the deployment to retry. return deployments.Delete(name, nil) }
// PodMatchesTermsNamespaceAndSelector returns true if the given <pod> // matches the namespace and selector defined by <affinityPod>`s <term>. func PodMatchesTermsNamespaceAndSelector(pod *v1.Pod, affinityPod *v1.Pod, term *v1.PodAffinityTerm) (bool, error) { namespaces := getNamespacesFromPodAffinityTerm(affinityPod, *term) if len(namespaces) != 0 && !namespaces.Has(pod.Namespace) { return false, nil } selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil || !selector.Matches(labels.Set(pod.Labels)) { return false, err } return true, nil }
// ListReplicaSets returns a slice of RSes the given deployment targets. 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 // 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 selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector) if err != nil { return nil, err } options := v1.ListOptions{LabelSelector: selector.String()} return getRSList(namespace, options) }
// Checks if scheduling the pod onto this node would break any rules of this pod. func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node *v1.Node, affinity *v1.Affinity) bool { allPods, err := c.podLister.List(labels.Everything()) if err != nil { return false } // Check all affinity terms. for _, term := range getPodAffinityTerms(affinity.PodAffinity) { termMatches, matchingPodExists, err := c.anyPodMatchesPodAffinityTerm(pod, allPods, node, &term) if err != nil { glog.V(10).Infof("Cannot schedule pod %+v onto node %v,because of PodAffinityTerm %v, err: %v", podName(pod), node.Name, term, err) return false } if !termMatches { // If the requirement matches a pod's own labels are namespace, and there are // no other such pods, then disregard the requirement. This is necessary to // not block forever because the first pod of the collection can't be scheduled. namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(pod, &term) selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) if err != nil { glog.V(10).Infof("Cannot parse selector on term %v for pod %v. Details %v", term, podName(pod), err) return false } match := priorityutil.PodMatchesTermsNamespaceAndSelector(pod, namespaces, selector) if !match || matchingPodExists { glog.V(10).Infof("Cannot schedule pod %+v onto node %v,because of PodAffinityTerm %v, err: %v", podName(pod), node.Name, term, err) return false } } } // Check all anti-affinity terms. for _, term := range getPodAntiAffinityTerms(affinity.PodAntiAffinity) { termMatches, _, err := c.anyPodMatchesPodAffinityTerm(pod, allPods, node, &term) if err != nil || termMatches { glog.V(10).Infof("Cannot schedule pod %+v onto node %v,because of PodAntiAffinityTerm %v, err: %v", podName(pod), node.Name, term, err) return false } } if glog.V(10) { // We explicitly don't do glog.V(10).Infof() to avoid computing all the parameters if this is // not logged. There is visible performance gain from it. glog.Infof("Schedule Pod %+v on Node %+v is allowed, pod afinnity/anti-affinity constraints satisfied.", podName(pod), node.Name) } return true }
// MatchingPodsFunc returns a filter function for pods with matching labels func MatchingPodsFunc(rs *extensions.ReplicaSet) (func(v1.Pod) bool, error) { if rs == nil { return nil, nil } selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } return func(pod v1.Pod) bool { podLabelsSelector := labels.Set(pod.ObjectMeta.Labels) return selector.Matches(podLabelsSelector) }, nil }
func (f *factory) AttachablePodForObject(object runtime.Object) (*api.Pod, error) { clientset, err := f.clients.ClientSetForVersion(nil) if err != nil { return nil, err } switch t := object.(type) { case *api.ReplicationController: selector := labels.SelectorFromSet(t.Spec.Selector) sortBy := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) } pod, _, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *extensions.Deployment: selector, err := metav1.LabelSelectorAsSelector(t.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } sortBy := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) } pod, _, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *batch.Job: selector, err := metav1.LabelSelectorAsSelector(t.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } sortBy := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) } pod, _, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *api.Pod: return t, nil default: gvks, _, err := api.Scheme.ObjectKinds(object) if err != nil { return nil, err } return nil, fmt.Errorf("cannot attach to %v: not implemented", gvks[0]) } }
// isDaemonSetMatch take a Pod and DaemonSet, return whether the Pod and DaemonSet are matching // TODO(mqliang): This logic is a copy from GetPodDaemonSets(), remove the duplication func isDaemonSetMatch(pod *v1.Pod, ds *extensions.DaemonSet) bool { if ds.Namespace != pod.Namespace { return false } selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) if err != nil { err = fmt.Errorf("invalid selector: %v", err) return false } // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { return false } return true }
// getPodsForStatefulSets returns the pods that match the selectors of the given statefulset. func (psc *StatefulSetController) getPodsForStatefulSet(ps *apps.StatefulSet) ([]*v1.Pod, error) { // TODO: Do we want the statefulset to fight with RCs? check parent statefulset annotation, or name prefix? sel, err := metav1.LabelSelectorAsSelector(ps.Spec.Selector) if err != nil { return []*v1.Pod{}, err } pods, err := psc.podStore.Pods(ps.Namespace).List(sel) if err != nil { return []*v1.Pod{}, err } // TODO: Do we need to copy? result := make([]*v1.Pod, 0, len(pods)) for i := range pods { result = append(result, &(*pods[i])) } return result, nil }
func Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { out.Replicas = int32(in.Replicas) out.Selector = nil out.TargetSelector = "" if in.Selector != nil { if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 { out.Selector = in.Selector.MatchLabels } selector, err := metav1.LabelSelectorAsSelector(in.Selector) if err != nil { return fmt.Errorf("invalid label selector: %v", err) } out.TargetSelector = selector.String() } return nil }
func ValidateJobSpec(spec *batch.JobSpec, fldPath *field.Path) field.ErrorList { allErrs := validateJobSpec(spec, fldPath) if spec.Selector == nil { allErrs = append(allErrs, field.Required(fldPath.Child("selector"), "")) } else { allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) } // Whether manually or automatically generated, the selector of the job must match the pods it will produce. if selector, err := metav1.LabelSelectorAsSelector(spec.Selector); err == nil { labels := labels.Set(spec.Template.Labels) if !selector.Matches(labels) { allErrs = append(allErrs, field.Invalid(fldPath.Child("template", "metadata", "labels"), spec.Template.Labels, "`selector` does not match template `labels`")) } } return allErrs }
// getNodesToDaemonSetPods returns a map from nodes to daemon pods (corresponding to ds) running on the nodes. func (dsc *DaemonSetsController) getNodesToDaemonPods(ds *extensions.DaemonSet) (map[string][]*v1.Pod, error) { nodeToDaemonPods := make(map[string][]*v1.Pod) selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) if err != nil { return nil, err } daemonPods, err := dsc.podStore.Pods(ds.Namespace).List(selector) if err != nil { return nodeToDaemonPods, err } for i := range daemonPods { // TODO: Do we need to copy here? daemonPod := &(*daemonPods[i]) nodeName := daemonPod.Spec.NodeName nodeToDaemonPods[nodeName] = append(nodeToDaemonPods[nodeName], daemonPod) } return nodeToDaemonPods, nil }
func (reaper *StatefulSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error { statefulsets := reaper.client.StatefulSets(namespace) scaler := &StatefulSetScaler{reaper.client} ps, err := statefulsets.Get(name, metav1.GetOptions{}) if err != nil { return err } if timeout == 0 { numPets := ps.Spec.Replicas timeout = Timeout + time.Duration(10*numPets)*time.Second } retry := NewRetryParams(reaper.pollInterval, reaper.timeout) waitForStatefulSet := NewRetryParams(reaper.pollInterval, reaper.timeout) if err = scaler.Scale(namespace, name, 0, nil, retry, waitForStatefulSet); err != nil { return err } // TODO: This shouldn't be needed, see corresponding TODO in StatefulSetHasDesiredPets. // StatefulSet should track generation number. pods := reaper.podClient.Pods(namespace) selector, _ := metav1.LabelSelectorAsSelector(ps.Spec.Selector) options := api.ListOptions{LabelSelector: selector} podList, err := pods.List(options) if err != nil { return err } errList := []error{} for _, pod := range podList.Items { if err := pods.Delete(pod.Name, gracePeriod); err != nil { if !errors.IsNotFound(err) { errList = append(errList, err) } } } if len(errList) > 0 { return utilerrors.NewAggregate(errList) } // TODO: Cleanup volumes? We don't want to accidentally delete volumes from // stop, so just leave this up to the statefulset. return statefulsets.Delete(name, nil) }