Skip to content

Commit

Permalink
Merge pull request #1913 from xyz2277/karmada-zyx-11
Browse files Browse the repository at this point in the history
sync status of pod
  • Loading branch information
karmada-bot authored Jun 13, 2022
2 parents 1ae36f7 + 7383526 commit 9a0ccad
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/userguide/customizing-resource-interpreter.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Supported resources:
- Job(batch/v1)
- DaemonSet(apps/v1)
- StatefulSet(apps/v1)
- Pod(v1)

### InterpretStatus

Expand Down
51 changes: 51 additions & 0 deletions pkg/resourceinterpreter/defaultinterpreter/aggregatestatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func getAllDefaultAggregateStatusInterpreter() map[schema.GroupVersionKind]aggre
s[batchv1.SchemeGroupVersion.WithKind(util.JobKind)] = aggregateJobStatus
s[appsv1.SchemeGroupVersion.WithKind(util.DaemonSetKind)] = aggregateDaemonSetStatus
s[appsv1.SchemeGroupVersion.WithKind(util.StatefulSetKind)] = aggregateStatefulSetStatus
s[corev1.SchemeGroupVersion.WithKind(util.PodKind)] = aggregatePodStatus
return s
}

Expand Down Expand Up @@ -269,3 +270,53 @@ func aggregateStatefulSetStatus(object *unstructured.Unstructured, aggregatedSta

return helper.ToUnstructured(statefulSet)
}

func aggregatePodStatus(object *unstructured.Unstructured, aggregatedStatusItems []workv1alpha2.AggregatedStatusItem) (*unstructured.Unstructured, error) {
pod, err := helper.ConvertToPod(object)
if err != nil {
return nil, err
}

newStatus := &corev1.PodStatus{}
newStatus.ContainerStatuses = make([]corev1.ContainerStatus, 0)
runningFlag := true
for _, item := range aggregatedStatusItems {
if item.Status == nil {
runningFlag = false
continue
}

temp := &corev1.PodStatus{}
if err = json.Unmarshal(item.Status.Raw, temp); err != nil {
return nil, err
}

if temp.Phase != corev1.PodRunning {
runningFlag = false
}

for _, containerStatus := range temp.ContainerStatuses {
tempStatus := corev1.ContainerStatus{
Ready: containerStatus.Ready,
State: containerStatus.State,
}
newStatus.ContainerStatuses = append(newStatus.ContainerStatuses, tempStatus)
}
klog.V(3).Infof("Grab pod(%s/%s) status from cluster(%s), phase: %s", pod.Namespace,
pod.Name, item.ClusterName, temp.Phase)
}

if runningFlag {
newStatus.Phase = corev1.PodRunning
} else {
newStatus.Phase = corev1.PodPending
}

if reflect.DeepEqual(pod.Status, *newStatus) {
klog.V(3).Infof("ignore update pod(%s/%s) status as up to date", pod.Namespace, pod.Name)
return object, nil
}

pod.Status = *newStatus
return helper.ToUnstructured(pod)
}
195 changes: 195 additions & 0 deletions pkg/resourceinterpreter/defaultinterpreter/aggregatestatus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package defaultinterpreter

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -346,3 +347,197 @@ func cleanUnstructuredJobConditionTime(object *unstructured.Unstructured) *unstr
ret, _ := helper.ToUnstructured(job)
return ret
}

func TestAggregatePodStatus(t *testing.T) {
startedTrue := true
timeNow := time.Now()

containerStatuses1 := []corev1.ContainerStatus{
{
ContainerID: "containerd://6cee0afa333472f672341352e0d",
Image: "nginx:latest",
ImageID: "docker.io/library/import-2022-06-05@sha256:dfb593",
Name: "busybox-2",
Ready: true,
RestartCount: 0,
Started: &startedTrue,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
{
ContainerID: "containerd://b373fb05ebf57020573cdf4a4518a3b2a8",
Image: "nginx:latest",
ImageID: "docker.io/library/import-2022-06-05@sha256:a29d07a75",
Name: "busybox-2",
Ready: true,
RestartCount: 0,
Started: &startedTrue,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
}

newContainerStatuses1 := []corev1.ContainerStatus{
{
Ready: true,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
{
Ready: true,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
}

curObj, _ := helper.ToUnstructured(&corev1.Pod{})
newObj, _ := helper.ToUnstructured(&corev1.Pod{Status: corev1.PodStatus{
ContainerStatuses: newContainerStatuses1,
Phase: corev1.PodRunning,
}})

statusMap1 := map[string]interface{}{
"containerStatuses": []corev1.ContainerStatus{containerStatuses1[0]},
"phase": corev1.PodRunning,
}
raw1, _ := helper.BuildStatusRawExtension(statusMap1)
statusMap2 := map[string]interface{}{
"containerStatuses": []corev1.ContainerStatus{containerStatuses1[1]},
"phase": corev1.PodRunning,
}
raw2, _ := helper.BuildStatusRawExtension(statusMap2)
aggregatedStatusItems1 := []workv1alpha2.AggregatedStatusItem{
{ClusterName: "member1", Status: raw1, Applied: true},
{ClusterName: "member2", Status: raw2, Applied: true},
}

containerStatuses2 := []corev1.ContainerStatus{
{
ContainerID: "containerd://6cee0afa333472f672341352e0d",
Image: "nginx:latest",
ImageID: "docker.io/library/import-2022-06-05@sha256:dfb593",
Name: "busybox-2",
Ready: true,
RestartCount: 0,
Started: &startedTrue,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
{
ContainerID: "containerd://b373fb05ebf57020573cdf4a4518a3b2a8",
Image: "nginx:latest",
ImageID: "docker.io/library/import-2022-06-05@sha256:a29d07a75",
Name: "busybox-2",
Ready: false,
RestartCount: 0,
Started: &startedTrue,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
}

statusMap3 := map[string]interface{}{
"containerStatuses": []corev1.ContainerStatus{containerStatuses2[0]},
"phase": corev1.PodRunning,
}
raw3, _ := helper.BuildStatusRawExtension(statusMap3)
statusMap4 := map[string]interface{}{
"containerStatuses": []corev1.ContainerStatus{containerStatuses2[1]},
"phase": corev1.PodPending,
}
raw4, _ := helper.BuildStatusRawExtension(statusMap4)
aggregatedStatusItems2 := []workv1alpha2.AggregatedStatusItem{
{ClusterName: "member1", Status: raw3, Applied: true},
{ClusterName: "member2", Status: raw4, Applied: true},
}

newContainerStatuses2 := []corev1.ContainerStatus{
{
Ready: true,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
{
Ready: false,
State: corev1.ContainerState{
Running: &corev1.ContainerStateRunning{
StartedAt: metav1.Time{
Time: timeNow,
},
},
},
},
}

newPodFailed := &corev1.Pod{Status: corev1.PodStatus{
ContainerStatuses: newContainerStatuses2,
Phase: corev1.PodPending,
}}
newObjFailed, _ := helper.ToUnstructured(newPodFailed)

tests := []struct {
name string
curObj *unstructured.Unstructured
aggregatedStatusItems []workv1alpha2.AggregatedStatusItem
expectedObj *unstructured.Unstructured
}{
{
name: "update pod status",
curObj: curObj,
aggregatedStatusItems: aggregatedStatusItems1,
expectedObj: newObj,
},
{
name: "ignore update pod status as up to date",
curObj: newObj,
aggregatedStatusItems: aggregatedStatusItems1,
expectedObj: newObj,
},
{
name: "update pod status as one Pod failed",
curObj: newObj,
aggregatedStatusItems: aggregatedStatusItems2,
expectedObj: newObjFailed,
},
}

for _, tt := range tests {
actualObj, _ := aggregatePodStatus(tt.curObj, tt.aggregatedStatusItems)
assert.Equal(t, tt.expectedObj, actualObj)
}
}

0 comments on commit 9a0ccad

Please sign in to comment.