@@ -30,6 +30,7 @@ import (
3030 apierrors "k8s.io/apimachinery/pkg/api/errors"
3131 "k8s.io/apimachinery/pkg/api/meta"
3232 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33+ "k8s.io/apimachinery/pkg/runtime/schema"
3334 "k8s.io/client-go/tools/record"
3435 "sigs.k8s.io/controller-runtime/pkg/client"
3536
@@ -125,17 +126,24 @@ func switchoverPreCheck(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes
125126 if err != nil {
126127 return err
127128 }
128- instance , err := runtime . GetInstance ( synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .InstanceName )
129+ instance , err := getSwitchoverPodBackedInstance ( runtime , synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .InstanceName )
129130 if err != nil {
131+ if apierrors .IsNotFound (err ) {
132+ return intctrlutil .NewFatalError (fmt .Sprintf (`instance "%s" not found` , switchover .InstanceName ))
133+ }
130134 return err
131135 }
132136 roleName := instance .GetRole ()
133137 if roleName == "" {
134- return intctrlutil .NewFatalError ( fmt . Sprintf ( "pod %s cannot perform switchover because it does not have a role label" , switchover .InstanceName ) )
138+ return intctrlutil .NewErrorf ( intctrlutil . ErrorTypeNeedWaiting , "waiting for instance %s role label" , switchover .InstanceName )
135139 }
136140
137141 if switchover .CandidateName != "" {
138- if _ , err := runtime .GetInstance (synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .CandidateName ); err != nil {
142+ _ , err := getSwitchoverPodBackedInstance (runtime , synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .CandidateName )
143+ if err != nil {
144+ if apierrors .IsNotFound (err ) {
145+ return intctrlutil .NewFatalError (fmt .Sprintf (`candidate instance "%s" not found` , switchover .CandidateName ))
146+ }
139147 return err
140148 }
141149 }
@@ -232,13 +240,19 @@ func handleSwitchover(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *
232240 case opsv1alpha1 .ProcessingProgressStatus :
233241 targetRole := progressDetail .Group
234242 if switchover .CandidateName != "" {
235- candidateInstance , err := runtime .GetInstance (synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .CandidateName )
236- if err != nil {
243+ candidateInstance , err := getSwitchoverPodBackedInstance (runtime , synthesizedComp .Namespace , synthesizedComp .ClusterName , synthesizedComp .Name , switchover .CandidateName )
244+ switch {
245+ case err != nil && ! apierrors .IsNotFound (err ):
237246 return err
238- }
239- if targetRole == candidateInstance .GetRole () {
247+ case err != nil :
248+ progressDetail .Message = fmt .Sprintf (`component %s candidate instance "%s" not found` , compName , switchover .CandidateName )
249+ progressDetail .Status = opsv1alpha1 .FailedProgressStatus
250+ case targetRole == candidateInstance .GetRole ():
240251 progressDetail .Message = "do switchover succeed"
241252 progressDetail .Status = opsv1alpha1 .SucceedProgressStatus
253+ default :
254+ progressDetail .Message = fmt .Sprintf ("component %s is waiting for candidate pod %s role change, current role %q, expected role %q" ,
255+ compName , switchover .CandidateName , candidateInstance .GetRole (), targetRole )
242256 }
243257 } else {
244258 progressDetail .Message = "do switchover succeed"
@@ -249,6 +263,17 @@ func handleSwitchover(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *
249263 return nil
250264}
251265
266+ func getSwitchoverPodBackedInstance (runtime OpsRuntime , namespace , clusterName , compName , instanceName string ) (Instance , error ) {
267+ instance , err := runtime .GetInstance (namespace , clusterName , compName , instanceName )
268+ if err != nil {
269+ return nil , err
270+ }
271+ if ! instance .HasPod () {
272+ return nil , apierrors .NewNotFound (schema.GroupResource {Resource : "pods" }, instanceName )
273+ }
274+ return instance , nil
275+ }
276+
252277// setComponentSwitchoverProgressDetails sets component switchover progress details.
253278func setComponentSwitchoverProgressDetails (recorder record.EventRecorder ,
254279 opsRequest * opsv1alpha1.OpsRequest ,
@@ -348,6 +373,9 @@ func buildSynthesizedComp(ctx context.Context, cli client.Client, opsRes *OpsRes
348373func getShardingComponentObjectNameByInstance (ctx context.Context , cli client.Client , cluster * appsv1.Cluster , shardingName , instanceName string ) (string , error ) {
349374 pod := & corev1.Pod {}
350375 if err := cli .Get (ctx , client.ObjectKey {Namespace : cluster .Namespace , Name : instanceName }, pod ); err != nil {
376+ if apierrors .IsNotFound (err ) {
377+ return "" , intctrlutil .NewFatalError (fmt .Sprintf (`instance "%s" not found` , instanceName ))
378+ }
351379 return "" , err
352380 }
353381 if pod .Labels [constant .AppInstanceLabelKey ] != cluster .Name {
0 commit comments