@@ -30,6 +30,7 @@ import (
3030 "k8s.io/apimachinery/pkg/types"
3131 kerrors "k8s.io/apimachinery/pkg/util/errors"
3232 "k8s.io/client-go/tools/record"
33+ "k8s.io/klog/v2"
3334 "k8s.io/utils/ptr"
3435 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3536 ipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
@@ -42,7 +43,9 @@ import (
4243 "sigs.k8s.io/controller-runtime/pkg/client"
4344 "sigs.k8s.io/controller-runtime/pkg/controller"
4445 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
46+ "sigs.k8s.io/controller-runtime/pkg/event"
4547 "sigs.k8s.io/controller-runtime/pkg/handler"
48+ "sigs.k8s.io/controller-runtime/pkg/predicate"
4649 "sigs.k8s.io/controller-runtime/pkg/reconcile"
4750
4851 orcv1alpha1 "github.com/k-orc/openstack-resource-controller/api/v1alpha1"
@@ -285,9 +288,16 @@ func objToDependencyLabel(obj client.Object, scheme *runtime.Scheme) (string, er
285288 return "orc-dependency-" + prefixType + "/" + obj .GetName (), nil
286289}
287290
291+ func IsServerTerminalError (server * infrav1alpha1.OpenStackServer ) bool {
292+ if server .Status .InstanceState != nil && * server .Status .InstanceState == infrav1 .InstanceStateError {
293+ return true
294+ }
295+ return false
296+ }
297+
288298func (r * OpenStackServerReconciler ) reconcileNormal (ctx context.Context , scope * scope.WithLogger , openStackServer * infrav1alpha1.OpenStackServer ) (_ ctrl.Result , reterr error ) {
289299 // If the OpenStackServer is in an error state, return early.
290- if openStackServer . Status . InstanceState != nil && * openStackServer . Status . InstanceState == infrav1 . InstanceStateError {
300+ if IsServerTerminalError ( openStackServer ) {
291301 scope .Logger ().Info ("Not reconciling server in error state. See openStackServer.status or previously logged error for details" )
292302 return ctrl.Result {}, nil
293303 }
@@ -708,3 +718,56 @@ func (r *OpenStackServerReconciler) reconcileDeleteFloatingAddressFromPool(scope
708718 controllerutil .RemoveFinalizer (claim , infrav1 .IPClaimMachineFinalizer )
709719 return r .Client .Update (context .Background (), claim )
710720}
721+
722+ // OpenStackServerReconcileComplete returns a predicate that determines if a OpenStackServer has finished reconciling.
723+ func OpenStackServerReconcileComplete (log logr.Logger ) predicate.Funcs {
724+ log = log .WithValues ("predicate" , "OpenStackServerReconcileComplete" )
725+
726+ return predicate.Funcs {
727+ CreateFunc : func (e event.CreateEvent ) bool {
728+ log = log .WithValues ("eventType" , "create" )
729+
730+ server , ok := e .Object .(* infrav1alpha1.OpenStackServer )
731+ if ! ok {
732+ log .V (4 ).Info ("Expected OpenStackServer" , "type" , fmt .Sprintf ("%T" , e .Object ))
733+ return false
734+ }
735+ log = log .WithValues ("OpenStackServer" , klog .KObj (server ))
736+
737+ if server .Status .Ready || IsServerTerminalError (server ) {
738+ log .V (6 ).Info ("OpenStackServer finished reconciling, allowing further processing" )
739+ return true
740+ }
741+ log .V (6 ).Info ("OpenStackServer is still reconciling, blocking further processing" )
742+ return false
743+ },
744+ UpdateFunc : func (e event.UpdateEvent ) bool {
745+ log := log .WithValues ("eventType" , "update" )
746+
747+ oldServer , ok := e .ObjectOld .(* infrav1alpha1.OpenStackServer )
748+ if ! ok {
749+ log .V (4 ).Info ("Expected OpenStackServer" , "type" , fmt .Sprintf ("%T" , e .ObjectOld ))
750+ return false
751+ }
752+ log = log .WithValues ("OpenStackServer" , klog .KObj (oldServer ))
753+
754+ newServer , ok := e .ObjectNew .(* infrav1alpha1.OpenStackServer )
755+ if ! ok {
756+ log .V (4 ).Info ("Expected OpenStackServer (new)" , "type" , fmt .Sprintf ("%T" , e .ObjectNew ))
757+ return false
758+ }
759+
760+ oldFinished := oldServer .Status .Ready || IsServerTerminalError (oldServer )
761+ newFinished := newServer .Status .Ready || IsServerTerminalError (newServer )
762+ if ! oldFinished && newFinished {
763+ log .V (6 ).Info ("OpenStackServer finished reconciling, allowing further processing" )
764+ return true
765+ }
766+
767+ log .V (4 ).Info ("OpenStackServer is still reconciling, blocking further processing" )
768+ return false
769+ },
770+ DeleteFunc : func (event.DeleteEvent ) bool { return false },
771+ GenericFunc : func (event.GenericEvent ) bool { return false },
772+ }
773+ }
0 commit comments