func genOneNode(node *api.Node, allPods []*api.Pod) page.Node { conditionMap := make(map[api.NodeConditionType]*api.NodeCondition) NodeAllConditions := []api.NodeConditionType{api.NodeReady} for i := range node.Status.Conditions { cond := node.Status.Conditions[i] conditionMap[cond.Type] = &cond } var status []string for _, validCondition := range NodeAllConditions { if condition, ok := conditionMap[validCondition]; ok { if condition.Status == api.ConditionTrue { status = append(status, string(condition.Type)) } else { status = append(status, "Not"+string(condition.Type)) } } } if len(status) == 0 { status = append(status, "Unknown") } if node.Spec.Unschedulable { status = append(status, "SchedulingDisabled") } labels := make(map[string]string) for k, v := range node.Labels { if !strings.HasPrefix(k, "kubernetes.io") { labels[k] = v } } pods := kube.FilterNodePods(allPods, node) terminated, nonTerminated := kube.FilterTerminatedPods(pods) allocated, _ := computeNodeResources(nonTerminated, node) return page.Node{ Name: node.Name, Status: status, Age: kube.TranslateTimestamp(node.CreationTimestamp), Labels: labels, Capacity: kube.TranslateResourseList(node.Status.Capacity), Pods: pods, TerminatedPods: terminated, NonTerminatedPods: nonTerminated, AllocatedResources: allocated, FractionPods: int64(float64(len(pods)) / float64(node.Status.Capacity.Pods().Value()) * 100), } }
func genOnePod(pod *api.Pod) page.Pod { var containerBirth unversioned.Time restarts := 0 totalContainers := len(pod.Spec.Containers) readyContainers := 0 reason := string(pod.Status.Phase) conditionMap := make(map[api.PodConditionType]*api.PodCondition) PodAllConditions := []api.PodConditionType{api.PodReady} for i := range pod.Status.Conditions { cond := pod.Status.Conditions[i] conditionMap[cond.Type] = &cond } for _, validCondition := range PodAllConditions { if condition, ok := conditionMap[validCondition]; ok { if condition.Status != api.ConditionTrue { reason = "Not" + string(condition.Type) } } } if pod.Status.Reason != "" { reason = pod.Status.Reason } for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- { container := pod.Status.ContainerStatuses[i] restarts += container.RestartCount if container.State.Waiting != nil && container.State.Waiting.Reason != "" { reason = container.State.Waiting.Reason } else if container.State.Terminated != nil && container.State.Terminated.Reason != "" { reason = container.State.Terminated.Reason } else if container.State.Terminated != nil && container.State.Terminated.Reason == "" { if container.State.Terminated.Signal != 0 { reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal) } else { reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode) } } else if container.Ready && container.State.Running != nil { readyContainers++ if containerBirth.Before(container.State.Running.StartedAt) { containerBirth = container.State.Running.StartedAt } if container.Image == PauseImage { reason = "Stopped" } } } if pod.DeletionTimestamp != nil { reason = "Terminating" } podIP := "" portString := "" if pod.Spec.HostNetwork { podIP = "" for i := range pod.Spec.Containers { for j := range pod.Spec.Containers[i].Ports { port := pod.Spec.Containers[i].Ports[j] portString += fmt.Sprintf("%d/%s,", port.HostPort, port.Protocol) } } portString = strings.TrimSuffix(portString, ",") } else { podIP = pod.Status.PodIP matches := portMapping.FindStringSubmatch(pod.Status.Message) if len(matches) > 1 { portString = matches[1] } } var ports []string for _, p := range strings.Split(portString, ",") { ports = append(ports, strings.TrimSuffix(p, "/TCP")) } req, limit, _ := kube.GetSinglePodTotalRequestsAndLimits(pod) return page.Pod{ Namespace: pod.Namespace, Name: pod.Name, Images: populatePodImages(pod.Spec.Containers), TotalContainers: totalContainers, ReadyContainers: readyContainers, Status: reason, Restarts: restarts, Age: kube.TranslateTimestamp(pod.CreationTimestamp), ContainerAge: kube.TranslateTimestamp(containerBirth), ContainerBirth: containerBirth.Time, HostNetwork: pod.Spec.HostNetwork, HostIP: pod.Spec.NodeName, PodIP: podIP, Ports: ports, Requests: kube.TranslateResourseList(req), Limits: kube.TranslateResourseList(limit), } }
func describeNode(c *gin.Context) { nodename := c.Param("no") node, err := kubeclient.Get().Nodes().Get(nodename) if err != nil { c.HTML(http.StatusInternalServerError, "error", gin.H{"error": err.Error()}) return } d := page.NodeDetail{ Name: node.Name, Labels: node.Labels, CreationTimestamp: node.CreationTimestamp.Time.Format(time.RFC1123Z), Conditions: node.Status.Conditions, Capacity: kube.TranslateResourseList(node.Status.Capacity), SystemInfo: node.Status.NodeInfo, } allPods, err := kubeclient.GetAllPods() if err != nil { c.HTML(http.StatusInternalServerError, "error", gin.H{"error": err.Error()}) return } d.Pods = kube.FilterNodePods(allPods, node) d.TerminatedPods, d.NonTerminatedPods = kube.FilterTerminatedPods(d.Pods) d.NonTerminatedPodsResources = computePodsResources(d.NonTerminatedPods, node) d.TerminatedPodsResources = computePodsResources(d.TerminatedPods, node) d.AllocatedResources, err = computeNodeResources(d.NonTerminatedPods, node) if err != nil { c.HTML(http.StatusInternalServerError, "error", gin.H{"error": err.Error()}) return } var pods []page.Pod for _, pod := range d.Pods { pods = append(pods, genOnePod(pod)) } var nodeEvents []page.Event var nodeEventList *api.EventList if ref, err := api.GetReference(node); err != nil { glog.Errorf("Unable to construct reference to '%#v': %v", node, err) } else { ref.UID = types.UID(ref.Name) if nodeEventList, err = kubeclient.Get().Events("").Search(ref); err != nil { glog.Errorf("Unable to search events for '%#v': %v", node, err) } } if nodeEventList != nil { nodeEvents = genEvents(nodeEventList) } var events []page.Event var eventList *api.EventList if eventList, err = kubeclient.Get().Events("").List(labels.Everything(), fields.Everything()); err != nil { glog.Errorf("Unable to search events for '%#v': %v", node, err) } if eventList != nil { events = genEvents(&api.EventList{Items: kube.FilterEventsFromNode(eventList.Items, node)}) } c.HTML(http.StatusOK, "nodeDetail", gin.H{ "title": nodename, "node": d, "pods": pods, "events": events, "nodeEvents": nodeEvents, }) }