// Classify first filters out inactive pods, then it classify the remaining pods // into three categories: 1. matchesAndControlled are the pods whose labels // match the selector of the RC, and have a controllerRef pointing to the // controller 2. matchesNeedsController are the pods whose labels match the RC, // but don't have a controllerRef. (Pods with matching labels but with a // controllerRef pointing to other object are ignored) 3. controlledDoesNotMatch // are the pods that have a controllerRef pointing to the controller, but their // labels no longer match the selector. func (m *PodControllerRefManager) Classify(pods []*v1.Pod) ( matchesAndControlled []*v1.Pod, matchesNeedsController []*v1.Pod, controlledDoesNotMatch []*v1.Pod) { for i := range pods { pod := pods[i] if !IsPodActive(pod) { glog.V(4).Infof("Ignoring inactive pod %v/%v in state %v, deletion time %v", pod.Namespace, pod.Name, pod.Status.Phase, pod.DeletionTimestamp) continue } controllerRef := GetControllerOf(&pod.ObjectMeta) if controllerRef != nil { if controllerRef.UID == m.controllerObject.UID { // already controlled if m.controllerSelector.Matches(labels.Set(pod.Labels)) { matchesAndControlled = append(matchesAndControlled, pod) } else { controlledDoesNotMatch = append(controlledDoesNotMatch, pod) } } else { // ignoring the pod controlled by other controller glog.V(4).Infof("Ignoring pod %v/%v, it's owned by [%s/%s, name: %s, uid: %s]", pod.Namespace, pod.Name, controllerRef.APIVersion, controllerRef.Kind, controllerRef.Name, controllerRef.UID) continue } } else { if !m.controllerSelector.Matches(labels.Set(pod.Labels)) { continue } matchesNeedsController = append(matchesNeedsController, pod) } } return matchesAndControlled, matchesNeedsController, controlledDoesNotMatch }
// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found. func (s *StoreToReplicationControllerLister) GetPodControllers(pod *v1.Pod) (controllers []*v1.ReplicationController, err error) { if len(pod.Labels) == 0 { err = fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name) return } key := &v1.ReplicationController{ObjectMeta: metav1.ObjectMeta{Namespace: pod.Namespace}} items, err := s.Indexer.Index(NamespaceIndex, key) if err != nil { return } for _, m := range items { rc := m.(*v1.ReplicationController) selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated() // If an rc with a nil or empty selector creeps in, it should match nothing, not everything. if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } controllers = append(controllers, rc) } if len(controllers) == 0 { err = fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) } return }
// Classify, classifies the ReplicaSets into three categories: // 1. matchesAndControlled are the ReplicaSets whose labels // match the selector of the Deployment, and have a controllerRef pointing to the // Deployment. // 2. matchesNeedsController are ReplicaSets ,whose labels match the Deployment, // but don't have a controllerRef. (ReplicaSets with matching labels but with a // controllerRef pointing to other object are ignored) // 3. controlledDoesNotMatch are the ReplicaSets that have a controllerRef pointing // to the Deployment, but their labels no longer match the selector. func (m *ReplicaSetControllerRefManager) Classify(replicaSets []*extensions.ReplicaSet) ( matchesAndControlled []*extensions.ReplicaSet, matchesNeedsController []*extensions.ReplicaSet, controlledDoesNotMatch []*extensions.ReplicaSet) { for i := range replicaSets { replicaSet := replicaSets[i] controllerRef := GetControllerOf(&replicaSet.ObjectMeta) if controllerRef != nil { if controllerRef.UID != m.controllerObject.UID { // ignoring the ReplicaSet controlled by other Deployment glog.V(4).Infof("Ignoring ReplicaSet %v/%v, it's owned by [%s/%s, name: %s, uid: %s]", replicaSet.Namespace, replicaSet.Name, controllerRef.APIVersion, controllerRef.Kind, controllerRef.Name, controllerRef.UID) continue } // already controlled by this Deployment if m.controllerSelector.Matches(labels.Set(replicaSet.Labels)) { matchesAndControlled = append(matchesAndControlled, replicaSet) } else { controlledDoesNotMatch = append(controlledDoesNotMatch, replicaSet) } } else { if !m.controllerSelector.Matches(labels.Set(replicaSet.Labels)) { continue } matchesNeedsController = append(matchesNeedsController, replicaSet) } } return matchesAndControlled, matchesNeedsController, controlledDoesNotMatch }
// CalculateAntiAffinityPriority spreads pods by minimizing the number of pods belonging to the same service // on machines with the same value for a particular label. // The label to be considered is provided to the struct (ServiceAntiAffinity). func (s *ServiceAntiAffinity) CalculateAntiAffinityPriority(pod *v1.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodes []*v1.Node) (schedulerapi.HostPriorityList, error) { var nsServicePods []*v1.Pod if services, err := s.serviceLister.GetPodServices(pod); err == nil && len(services) > 0 { // just use the first service and get the other pods within the service // TODO: a separate predicate can be created that tries to handle all services for the pod selector := labels.SelectorFromSet(services[0].Spec.Selector) pods, err := s.podLister.List(selector) if err != nil { return nil, err } // consider only the pods that belong to the same namespace for _, nsPod := range pods { if nsPod.Namespace == pod.Namespace { nsServicePods = append(nsServicePods, nsPod) } } } // separate out the nodes that have the label from the ones that don't otherNodes := []string{} labeledNodes := map[string]string{} for _, node := range nodes { if labels.Set(node.Labels).Has(s.label) { label := labels.Set(node.Labels).Get(s.label) labeledNodes[node.Name] = label } else { otherNodes = append(otherNodes, node.Name) } } podCounts := map[string]int{} for _, pod := range nsServicePods { label, exists := labeledNodes[pod.Spec.NodeName] if !exists { continue } podCounts[label]++ } numServicePods := len(nsServicePods) result := []schedulerapi.HostPriority{} //score int - scale of 0-maxPriority // 0 being the lowest priority and maxPriority being the highest for node := range labeledNodes { // initializing to the default/max node score of maxPriority fScore := float32(maxPriority) if numServicePods > 0 { fScore = maxPriority * (float32(numServicePods-podCounts[labeledNodes[node]]) / float32(numServicePods)) } result = append(result, schedulerapi.HostPriority{Host: node, Score: int(fScore)}) } // add the open nodes with a score of 0 for _, node := range otherNodes { result = append(result, schedulerapi.HostPriority{Host: node, Score: 0}) } return result, nil }
// isControllerMatch take a Pod and ReplicationController, return whether the Pod and ReplicationController are matching // TODO(mqliang): This logic is a copy from GetPodControllers(), remove the duplication func isControllerMatch(pod *v1.Pod, rc *v1.ReplicationController) bool { if rc.Namespace != pod.Namespace { return false } selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated() // If an rc 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 }
// 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 }
// getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller. func getOverlappingControllers(rcClient coreclient.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) { rcs, err := rcClient.List(api.ListOptions{}) if err != nil { return nil, fmt.Errorf("error getting replication controllers: %v", err) } var matchingRCs []api.ReplicationController rcLabels := labels.Set(rc.Spec.Selector) for _, controller := range rcs.Items { newRCLabels := labels.Set(controller.Spec.Selector) if labels.SelectorFromSet(newRCLabels).Matches(rcLabels) || labels.SelectorFromSet(rcLabels).Matches(newRCLabels) { matchingRCs = append(matchingRCs, controller) } } return matchingRCs, nil }
// 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 }
// 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 }
func checkDaemonPodOnNodes(f *framework.Framework, selector map[string]string, nodeNames []string) func() (bool, error) { return func() (bool, error) { selector := labels.Set(selector).AsSelector() options := v1.ListOptions{LabelSelector: selector.String()} podList, err := f.ClientSet.Core().Pods(f.Namespace.Name).List(options) if err != nil { return false, nil } pods := podList.Items nodesToPodCount := make(map[string]int) for _, pod := range pods { nodesToPodCount[pod.Spec.NodeName] += 1 } framework.Logf("nodesToPodCount: %#v", nodesToPodCount) // Ensure that exactly 1 pod is running on all nodes in nodeNames. for _, nodeName := range nodeNames { if nodesToPodCount[nodeName] != 1 { return false, nil } } // Ensure that sizes of the lists are the same. We've verified that every element of nodeNames is in // nodesToPodCount, so verifying the lengths are equal ensures that there aren't pods running on any // other nodes. return len(nodesToPodCount) == len(nodeNames), 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 }
// 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 }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { networkPolicy, ok := obj.(*extensions.NetworkPolicy) if !ok { return nil, nil, fmt.Errorf("given object is not a NetworkPolicy.") } return labels.Set(networkPolicy.ObjectMeta.Labels), NetworkPolicyToSelectableFields(networkPolicy), nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { sa, ok := obj.(*api.ServiceAccount) if !ok { return nil, nil, fmt.Errorf("not a serviceaccount") } return labels.Set(sa.Labels), SelectableFields(sa), nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { psp, ok := obj.(*extensions.PodSecurityPolicy) if !ok { return nil, nil, fmt.Errorf("given object is not a pod security policy.") } return labels.Set(psp.ObjectMeta.Labels), PodSecurityPolicyToSelectableFields(psp), nil }
func (r RealPodControl) createPods(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error { pod, err := GetPodFromTemplate(template, object, controllerRef) if err != nil { return err } if len(nodeName) != 0 { pod.Spec.NodeName = nodeName } if labels.Set(pod.Labels).AsSelectorPreValidated().Empty() { return fmt.Errorf("unable to create pods, no labels") } if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil { r.Recorder.Eventf(object, v1.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err) return fmt.Errorf("unable to create pods: %v", err) } else { accessor, err := meta.Accessor(object) if err != nil { glog.Errorf("parentObject does not have ObjectMeta, %v", err) return nil } glog.V(4).Infof("Controller %v created pod %v", accessor.GetName(), newPod.Name) r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name) } return nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { cls, ok := obj.(*storage.StorageClass) if !ok { return nil, nil, fmt.Errorf("given object is not of type StorageClass") } return labels.Set(cls.ObjectMeta.Labels), StorageClassToSelectableFields(cls), nil }
// GetPodServices gets the services that have the selector that match the labels on the given pod. func (f FakeServiceLister) GetPodServices(pod *v1.Pod) (services []*v1.Service, err error) { var selector labels.Selector for i := range f { service := f[i] // consider only services that are in the same namespace as the pod if service.Namespace != pod.Namespace { continue } selector = labels.Set(service.Spec.Selector).AsSelectorPreValidated() if selector.Matches(labels.Set(pod.Labels)) { services = append(services, service) } } return }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { persistentvolumeObj, ok := obj.(*api.PersistentVolume) if !ok { return nil, nil, fmt.Errorf("not a persistentvolume") } return labels.Set(persistentvolumeObj.Labels), PersistentVolumeToSelectableFields(persistentvolumeObj), nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { deployment, ok := obj.(*extensions.Deployment) if !ok { return nil, nil, fmt.Errorf("given object is not a deployment.") } return labels.Set(deployment.ObjectMeta.Labels), DeploymentToSelectableFields(deployment), nil }
// 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 }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { job, ok := obj.(*batch.Job) if !ok { return nil, nil, fmt.Errorf("Given object is not a job.") } return labels.Set(job.ObjectMeta.Labels), JobToSelectableFields(job), nil }
func (j *ServiceTestJig) waitForPodsCreated(namespace string, replicas int) ([]string, error) { timeout := 2 * time.Minute // List the pods, making sure we observe all the replicas. label := labels.SelectorFromSet(labels.Set(j.Labels)) Logf("Waiting up to %v for %d pods to be created", timeout, replicas) for start := time.Now(); time.Since(start) < timeout; time.Sleep(2 * time.Second) { options := v1.ListOptions{LabelSelector: label.String()} pods, err := j.Client.Core().Pods(namespace).List(options) if err != nil { return nil, err } found := []string{} for _, pod := range pods.Items { if pod.DeletionTimestamp != nil { continue } found = append(found, pod.Name) } if len(found) == replicas { Logf("Found all %d pods", replicas) return found, nil } Logf("Found %d/%d pods - will retry", len(found), replicas) } return nil, fmt.Errorf("Timeout waiting for %d pods to be created", replicas) }
func reportLogsFromFluentdPod(f *framework.Framework) error { synthLoggerPod, err := f.PodClient().Get(synthLoggerPodName, metav1.GetOptions{}) if err != nil { return fmt.Errorf("Failed to get synth logger pod due to %v", err) } synthLoggerNodeName := synthLoggerPod.Spec.NodeName if synthLoggerNodeName == "" { return errors.New("Synthlogger pod is not assigned to the node") } label := labels.SelectorFromSet(labels.Set(map[string]string{"k8s-app": "fluentd-logging"})) options := v1.ListOptions{LabelSelector: label.String()} fluentdPods, err := f.ClientSet.Core().Pods(api.NamespaceSystem).List(options) for _, fluentdPod := range fluentdPods.Items { if fluentdPod.Spec.NodeName == synthLoggerNodeName { containerName := fluentdPod.Spec.Containers[0].Name logs, err := framework.GetPodLogs(f.ClientSet, api.NamespaceSystem, fluentdPod.Name, containerName) if err != nil { return fmt.Errorf("Failed to get logs from fluentd pod %s due to %v", fluentdPod.Name, err) } framework.Logf("Logs from fluentd pod %s:\n%s", fluentdPod.Name, logs) return nil } } return fmt.Errorf("Failed to find fluentd pod running on node %s", synthLoggerNodeName) }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { secret, ok := obj.(*api.Secret) if !ok { return nil, nil, fmt.Errorf("not a secret") } return labels.Set(secret.Labels), SelectableFields(secret), nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { event, ok := obj.(*api.Event) if !ok { return nil, nil, fmt.Errorf("not an event") } return labels.Set(event.Labels), EventToSelectableFields(event), nil }
// 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 }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { sa, ok := obj.(*certificates.CertificateSigningRequest) if !ok { return nil, nil, fmt.Errorf("not a CertificateSigningRequest") } return labels.Set(sa.Labels), SelectableFields(sa), nil }
// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { tprd, ok := obj.(*extensions.ThirdPartyResourceData) if !ok { return nil, nil, fmt.Errorf("not a ThirdPartyResourceData") } return labels.Set(tprd.Labels), SelectableFields(tprd), nil }
// Simplified version of RunRC, that does not create RC, but creates plain Pods. // Optionally waits for pods to start running (if waitForRunning == true). // The number of replicas must be non-zero. func StartPods(c clientset.Interface, replicas int, namespace string, podNamePrefix string, pod v1.Pod, waitForRunning bool, logFunc func(fmt string, args ...interface{})) error { // no pod to start if replicas < 1 { panic("StartPods: number of replicas must be non-zero") } startPodsID := string(uuid.NewUUID()) // So that we can label and find them for i := 0; i < replicas; i++ { podName := fmt.Sprintf("%v-%v", podNamePrefix, i) pod.ObjectMeta.Name = podName pod.ObjectMeta.Labels["name"] = podName pod.ObjectMeta.Labels["startPodsID"] = startPodsID pod.Spec.Containers[0].Name = podName _, err := c.Core().Pods(namespace).Create(&pod) if err != nil { return err } } logFunc("Waiting for running...") if waitForRunning { label := labels.SelectorFromSet(labels.Set(map[string]string{"startPodsID": startPodsID})) err := WaitForPodsWithLabelRunning(c, namespace, label) if err != nil { return fmt.Errorf("Error waiting for %d pods to be running - probably a timeout: %v", replicas, err) } } return nil }