diff --git a/controllers/apps/operations/rebuild_instance.go b/controllers/apps/operations/rebuild_instance.go index 1f6b5f66714..abd04a0e18f 100644 --- a/controllers/apps/operations/rebuild_instance.go +++ b/controllers/apps/operations/rebuild_instance.go @@ -101,6 +101,24 @@ func (r rebuildInstanceOpsHandler) Action(reqCtx intctrlutil.RequestCtx, cli cli appsv1alpha1.AbnormalClusterCompPhase, appsv1alpha1.UpdatingClusterCompPhase}, compStatus.Phase) { return intctrlutil.NewFatalError(fmt.Sprintf(`the phase of component "%s" can not be %s`, v.ComponentName, compStatus.Phase)) } + comp := opsRes.Cluster.Spec.GetComponentByName(v.ComponentName) + synthesizedComp, err := component.BuildSynthesizedComponentWrapper(reqCtx, cli, opsRes.Cluster, comp) + if err != nil { + return err + } + for _, podName := range v.InstanceNames { + targetPod := &corev1.Pod{} + if err = cli.Get(reqCtx.Ctx, client.ObjectKey{Name: podName, Namespace: opsRes.Cluster.Namespace}, targetPod); err != nil { + return err + } + isAvailable, err := r.instanceIsAvailable(synthesizedComp, targetPod) + if err != nil { + return err + } + if isAvailable { + return intctrlutil.NewFatalError(fmt.Sprintf(`instance "%s" is availabled, can not rebuild it`, podName)) + } + } } return nil } diff --git a/controllers/apps/operations/rebuild_instance_test.go b/controllers/apps/operations/rebuild_instance_test.go index 4acd0fbd7a5..1a4552ea24f 100644 --- a/controllers/apps/operations/rebuild_instance_test.go +++ b/controllers/apps/operations/rebuild_instance_test.go @@ -164,7 +164,17 @@ var _ = Describe("OpsUtil functions", func() { opsRes.Cluster.Status.Components[consensusComp] = compStatus })).Should(Succeed()) - By("expect for opsRequest phase is Running") + By("expect for opsRequest phase is Failed due to the pod is Available") + _, _ = GetOpsManager().Do(reqCtx, k8sClient, opsRes) + Expect(opsRes.OpsRequest.Status.Phase).Should(Equal(appsv1alpha1.OpsFailedPhase)) + + By("fake pod is unavailable") + opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsCreatingPhase + for _, podName := range opsRes.OpsRequest.Spec.RebuildFrom[0].InstanceNames { + Expect(testapps.GetAndChangeObjStatus(&testCtx, client.ObjectKey{Name: podName, Namespace: opsRes.OpsRequest.Namespace}, func(pod *corev1.Pod) { + pod.Status.Conditions = nil + })()).Should(Succeed()) + } _, _ = GetOpsManager().Do(reqCtx, k8sClient, opsRes) Expect(opsRes.OpsRequest.Status.Phase).Should(Equal(appsv1alpha1.OpsCreatingPhase)) })