This commit is contained in:
曾庆国 2019-08-24 19:02:56 +08:00
commit 3cad75b5b0
7 changed files with 224 additions and 8 deletions

View File

@ -39,7 +39,9 @@ func (r *RuntimeServer) GetPodDetail(ctx context.Context, req *pb.GetPodDetailRe
// describe pod
podDetail = &pb.PodDetail{}
podDetail.Name = pod.Name
podDetail.StartTime = pod.Status.StartTime.Time.Format(time.RFC3339)
if pod.Status.StartTime != nil {
podDetail.StartTime = pod.Status.StartTime.Time.Format(time.RFC3339)
}
podDetail.InitContainers = make([]*pb.PodContainer, len(pod.Spec.InitContainers))
podDetail.Containers = make([]*pb.PodContainer, len(pod.Spec.Containers))
podDetail.Status = &pb.PodStatus{}
@ -58,7 +60,7 @@ func (r *RuntimeServer) GetPodDetail(ctx context.Context, req *pb.GetPodDetailRe
podDetail.Events = append(podDetail.Events, events...)
}
if len(pod.Spec.InitContainers) == 0 {
if len(pod.Spec.InitContainers) != 0 {
describeContainers(pod.Spec.InitContainers, pod.Status.InitContainerStatuses, &podDetail.InitContainers)
}
describeContainers(pod.Spec.Containers, pod.Status.ContainerStatuses, &podDetail.Containers)
@ -126,8 +128,7 @@ func describeContainers(containers []corev1.Container, containerStatuses []corev
statuses[status.Name] = status
}
var pcs []*pb.PodContainer
for _, container := range containers {
for idx, container := range containers {
status, ok := statuses[container.Name]
pc := &pb.PodContainer{
Image: container.Image,
@ -136,9 +137,9 @@ func describeContainers(containers []corev1.Container, containerStatuses []corev
describeContainerState(status, pc)
}
describeContainerResource(container, pc)
pcs = append(pcs, pc)
pcs := *podContainers
pcs[idx] = pc
}
*podContainers = pcs
}
func describeContainerState(status corev1.ContainerStatus, podContainer *pb.PodContainer) {

View File

@ -35,6 +35,7 @@ import (
"github.com/goodrain/rainbond/worker/appm/thirdparty/discovery"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/goodrain/rainbond/worker/server/pb"
wutil "github.com/goodrain/rainbond/worker/util"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
corev1 "k8s.io/api/core/v1"
@ -157,9 +158,11 @@ func (r *RuntimeServer) GetAppPods(ctx context.Context, re *pb.ServiceRequest) (
sapod := &pb.ServiceAppPod{
PodIp: pod.Status.PodIP,
PodName: pod.Name,
PodStatus: string(pod.Status.Phase),
Containers: containers,
}
podStatus := &pb.PodStatus{}
wutil.DescribePodStatus(pod, podStatus)
sapod.PodStatus = podStatus.Type.String()
if app.DistinguishPod(pod) {
newpods = append(newpods, sapod)
} else {

View File

@ -2,6 +2,7 @@ package util
import (
"fmt"
"sort"
"github.com/goodrain/rainbond/worker/server/pb"
corev1 "k8s.io/api/core/v1"
@ -18,6 +19,7 @@ var podStatusTbl = map[string]pb.PodStatus_Type{
string(corev1.PodScheduled): pb.PodStatus_SCHEDULING,
}
// DescribePodStatus -
func DescribePodStatus(pod *corev1.Pod, podStatus *pb.PodStatus) {
if pod.DeletionTimestamp != nil {
podStatus.Type = pb.PodStatus_TEMINATING
@ -34,7 +36,7 @@ func DescribePodStatus(pod *corev1.Pod, podStatus *pb.PodStatus) {
} else {
// schedule, ready, init
podStatus.Type = pb.PodStatus_RUNNING
// TODO: sort important.
sort.Sort(SortableConditionType(pod.Status.Conditions))
for _, condition := range pod.Status.Conditions {
if condition.Status == corev1.ConditionTrue {
continue
@ -47,3 +49,24 @@ func DescribePodStatus(pod *corev1.Pod, podStatus *pb.PodStatus) {
}
podStatus.TypeStr = podStatus.Type.String()
}
// SortableConditionType implements sort.Interface for []PodCondition based on
// the Type field.
type SortableConditionType []corev1.PodCondition
var podConditionTbl = map[corev1.PodConditionType]int{
corev1.PodScheduled: 0,
corev1.PodInitialized: 1,
corev1.PodReady: 2,
}
func (s SortableConditionType) Len() int {
return len(s)
}
func (s SortableConditionType) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableConditionType) Less(i, j int) bool {
return podConditionTbl[s[i].Type] > podConditionTbl[s[j].Type]
}

39
worker/util/pod_test.go Normal file
View File

@ -0,0 +1,39 @@
package util
import (
"encoding/json"
"io/ioutil"
"testing"
"github.com/goodrain/rainbond/worker/server/pb"
corev1 "k8s.io/api/core/v1"
)
func TestDescribePodStatus(t *testing.T) {
tests := []struct {
filename string
expstatus pb.PodStatus_Type
}{
{filename: "testdata/insufficient-memory.json", expstatus: pb.PodStatus_SCHEDULING},
{filename: "testdata/abnormal.json", expstatus: pb.PodStatus_ABNORMAL},
{filename: "testdata/initiating.json", expstatus: pb.PodStatus_INITIATING},
}
for idx := range tests {
tc := tests[idx]
jsonfile, err := ioutil.ReadFile(tc.filename)
if err != nil {
t.Errorf("failed to read file '%s': %v", tc.filename, err)
}
var pod corev1.Pod
if err := json.Unmarshal(jsonfile, &pod); err != nil {
t.Fatalf("file: %s; failed to unmarshalling json: %v", tc.filename, err)
}
podStatus := &pb.PodStatus{}
DescribePodStatus(&pod, podStatus)
if podStatus.Type != tc.expstatus {
t.Errorf("Expected %s for pod status type, but returned %s", tc.expstatus.String(), podStatus.Type.String())
}
}
}

55
worker/util/testdata/abnormal.json vendored Normal file
View File

@ -0,0 +1,55 @@
{
"apiVersion": "v1",
"kind": "Pod",
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T11:04:08Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T13:07:21Z",
"message": "containers with unready status: [fe7b4268912c884718620f7a6a7e4f47]",
"reason": "ContainersNotReady",
"status": "False",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T11:04:08Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "docker://10e359afca9fd975d800af0abfa989607309b8f239ff432db3cf48b65c8f0259",
"image": "nginx:latest",
"imageID": "docker-pullable://nginx@sha256:53ddb41e46de3d63376579acf46f9a41a8d7de33645db47a486de9769201fec9",
"lastState": {
"terminated": {
"containerID": "docker://10e359afca9fd975d800af0abfa989607309b8f239ff432db3cf48b65c8f0259",
"exitCode": 0,
"finishedAt": "2019-08-23T13:07:20Z",
"reason": "Completed",
"startedAt": "2019-08-23T13:07:15Z"
}
},
"name": "fe7b4268912c884718620f7a6a7e4f47",
"ready": false,
"restartCount": 1,
"state": {
"waiting": {
"message": "Back-off 20s restarting failed container=fe7b4268912c884718620f7a6a7e4f47 pod=fe7b4268912c884718620f7a6a7e4f47-deployment-5bfcf6d5c9-rwzhb_6e22adb70c114b1d9a46d17d8146ba37(baaa186f-c595-11e9-a0de-468210d133b9)",
"reason": "CrashLoopBackOff"
}
}
}
],
"phase": "Running",
"startTime": "2019-08-23T11:04:08Z"
}
}

77
worker/util/testdata/initiating.json vendored Normal file
View File

@ -0,0 +1,77 @@
{
"apiVersion": "v1",
"kind": "Pod",
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T13:24:22Z",
"message": "containers with incomplete status: [probe-mesh-c562a912c4bd7e335853]",
"reason": "ContainersNotInitialized",
"status": "False",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T13:24:22Z",
"message": "containers with unready status: [921c102de870c562a912c4bd7e335853 default-tcpmesh-c562a912c4bd7e335853]",
"reason": "ContainersNotReady",
"status": "False",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T13:24:22Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"image": "goodrain.me/nginx:20190823212118",
"imageID": "",
"lastState": {},
"name": "921c102de870c562a912c4bd7e335853",
"ready": false,
"restartCount": 0,
"state": {
"waiting": {
"reason": "PodInitializing"
}
}
},
{
"image": "goodrain.me/rbd-mesh-data-panel",
"imageID": "",
"lastState": {},
"name": "default-tcpmesh-c562a912c4bd7e335853",
"ready": false,
"restartCount": 0,
"state": {
"waiting": {
"reason": "PodInitializing"
}
}
}
],
"initContainerStatuses": [
{
"containerID": "docker://aa61eb6a60ea01ffebdef1a0377b55988cce04e38f833d41dc04f48307c70357",
"image": "goodrain.me/rbd-init-probe:latest",
"imageID": "docker-pullable://goodrain.me/rbd-init-probe@sha256:797658b83de62c22578670d50c7e4cd8758ee0826d23eb9b6cec334eaf7fd48e",
"lastState": {},
"name": "probe-mesh-c562a912c4bd7e335853",
"ready": false,
"restartCount": 0,
"state": {
"running": {
"startedAt": "2019-08-23T13:24:23Z"
}
}
}
],
"phase": "Pending",
"qosClass": "Burstable",
"startTime": "2019-08-23T13:24:22Z"
}
}

View File

@ -0,0 +1,18 @@
{
"apiVersion": "v1",
"kind": "Pod",
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2019-08-23T10:44:34Z",
"message": "0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory.",
"reason": "Unschedulable",
"status": "False",
"type": "PodScheduled"
}
],
"phase": "Pending",
"qosClass": "Burstable"
}
}