diff --git a/go.mod b/go.mod index 221b549d9d..7c7d20a0d8 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/openshift/api v0.0.0-20211209135129-c58d9f695577 github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3 github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3 - github.com/openshift/library-go v0.0.0-20220117173518-ca57b619b5d6 + github.com/openshift/library-go v0.0.0-20220119134102-3236af51f6e1 github.com/spf13/cobra v1.2.1 github.com/stretchr/testify v1.7.0 go.etcd.io/etcd/client/v3 v3.5.0 diff --git a/go.sum b/go.sum index cd147dd4ad..26e4bdd953 100644 --- a/go.sum +++ b/go.sum @@ -512,8 +512,8 @@ github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3 h1:65 github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3 h1:SG1aqwleU6bGD0X4mhkTNupjVnByMYYuW4XbnCPavQU= github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3/go.mod h1:cwhyki5lqBmrT0m8Im+9I7PGFaraOzcYPtEz93RcsGY= -github.com/openshift/library-go v0.0.0-20220117173518-ca57b619b5d6 h1:HS6brMoum1oJyFriix+Ae3J2FfvK9u9TBqUu+JnG/pc= -github.com/openshift/library-go v0.0.0-20220117173518-ca57b619b5d6/go.mod h1:4UQ9snU1vg53fyTpHQw3vLPiAxI8ub5xrc+y8KPQQFs= +github.com/openshift/library-go v0.0.0-20220119134102-3236af51f6e1 h1:A1d2p0VBeQ1O0jyXIcDoFHkff6ijbQehve4U3fRx+vg= +github.com/openshift/library-go v0.0.0-20220119134102-3236af51f6e1/go.mod h1:6AmNM4N4nHftckybV/U7bQW+5AvK5TW81ndSI6KEidw= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index 5db1f8b060..a5596abab8 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -529,8 +529,6 @@ func prepareOauthAPIServerOperator(ctx context.Context, controllerContext *contr const apiServerConditionsPrefix = "APIServer" - infraLister := operatorCtx.operatorConfigInformer.Config().V1().Infrastructures().Lister() - apiServerControllers, err := apiservercontrollerset.NewAPIServerControllerSet( operatorCtx.operatorClient, eventRecorder, @@ -566,18 +564,28 @@ func prepareOauthAPIServerOperator(ctx context.Context, controllerContext *contr "oauth-apiserver/oauth-apiserver-pdb.yaml", }, ShouldCreateFn: func() bool { - isSno, err := guard.IsSNOCheckFnc(infraLister)() + isSNO, precheckSucceeded, err := guard.IsSNOCheckFnc(operatorCtx.operatorConfigInformer.Config().V1().Infrastructures())() if err != nil { + klog.Errorf("IsSNOCheckFnc failed: %v", err) + return false + } + if !precheckSucceeded { + klog.V(4).Infof("IsSNOCheckFnc precheck did not succeed, skipping") return false } - return !isSno + return !isSNO }, ShouldDeleteFn: func() bool { - isSno, err := guard.IsSNOCheckFnc(infraLister)() + isSNO, precheckSucceeded, err := guard.IsSNOCheckFnc(operatorCtx.operatorConfigInformer.Config().V1().Infrastructures())() if err != nil { + klog.Errorf("IsSNOCheckFnc failed: %v", err) + return false + } + if !precheckSucceeded { + klog.V(4).Infof("IsSNOCheckFnc precheck did not succeed, skipping") return false } - return isSno + return isSNO }, }, }, diff --git a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/guard/guard_controller.go b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/guard/guard_controller.go index 4ab81ee5eb..e38ba30f44 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/guard/guard_controller.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/guard/guard_controller.go @@ -8,6 +8,7 @@ import ( "strconv" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -22,7 +23,7 @@ import ( "k8s.io/klog/v2" configv1 "github.com/openshift/api/config/v1" - configv1listers "github.com/openshift/client-go/config/listers/config/v1" + configv1informers "github.com/openshift/client-go/config/informers/externalversions/config/v1" "github.com/openshift/library-go/pkg/controller/factory" "github.com/openshift/library-go/pkg/operator/events" "github.com/openshift/library-go/pkg/operator/resource/resourceapply" @@ -47,7 +48,7 @@ type GuardController struct { // installerPodImageFn returns the image name for the installer pod installerPodImageFn func() string - createConditionalFunc func() (bool, error) + createConditionalFunc func() (bool, bool, error) } func NewGuardController( @@ -62,7 +63,7 @@ func NewGuardController( podGetter corev1client.PodsGetter, pdbGetter policyclientv1.PodDisruptionBudgetsGetter, eventRecorder events.Recorder, - createConditionalFunc func() (bool, error), + createConditionalFunc func() (bool, bool, error), ) factory.Controller { c := &GuardController{ targetNamespace: targetNamespace, @@ -107,16 +108,30 @@ func nodeConditionFinder(status *corev1.NodeStatus, condType corev1.NodeConditio return nil } +func nodeHasUnschedulableTaint(node *corev1.Node) bool { + for _, taint := range node.Spec.Taints { + if taint.Effect == corev1.TaintEffectNoSchedule && taint.Key == corev1.TaintNodeUnschedulable { + return true + } + } + return false +} + func (c *GuardController) sync(ctx context.Context, syncCtx factory.SyncContext) error { klog.V(5).Info("Syncing guards") if c.createConditionalFunc == nil { - return fmt.Errorf("create conditional not set") + return fmt.Errorf("createConditionalFunc not set") } - shouldCreate, err := c.createConditionalFunc() + shouldCreate, precheckSucceeded, err := c.createConditionalFunc() if err != nil { - return fmt.Errorf("create conditional returns an error: %v", err) + return fmt.Errorf("createConditionalFunc returns an error: %v", err) + } + + if !precheckSucceeded { + klog.V(4).Infof("create conditional precheck did not succeed, skipping") + return nil } errs := []error{} @@ -181,25 +196,24 @@ func (c *GuardController) sync(ctx context.Context, syncCtx factory.SyncContext) pdb.Spec.MinAvailable = &minAvailable } - // List the pdb from the cache in case it exists and there's nothing to update - // so no Get request is executed. - pdbs, err := c.pdbLister.PodDisruptionBudgets(c.targetNamespace).List(labels.Everything()) - if err != nil { - klog.Errorf("Unable to list PodDisruptionBudgets: %v", err) - return err - } - - for _, pdbItem := range pdbs { - if pdbItem.Name == pdb.Name { - if pdbItem.Spec.MinAvailable != pdb.Spec.MinAvailable { - _, _, err = resourceapply.ApplyPodDisruptionBudget(ctx, c.pdbGetter, syncCtx.Recorder(), pdb) - if err != nil { - klog.Errorf("Unable to apply PodDisruptionBudget changes: %v", err) - return err - } + pdbObj, err := c.pdbLister.PodDisruptionBudgets(pdb.Namespace).Get(pdb.Name) + if err == nil { + if pdbObj.Spec.MinAvailable != pdb.Spec.MinAvailable { + _, _, err = resourceapply.ApplyPodDisruptionBudget(ctx, c.pdbGetter, syncCtx.Recorder(), pdb) + if err != nil { + klog.Errorf("Unable to apply PodDisruptionBudget changes: %v", err) + return fmt.Errorf("Unable to apply PodDisruptionBudget changes: %v", err) } - break } + } else if errors.IsNotFound(err) { + _, _, err = resourceapply.ApplyPodDisruptionBudget(ctx, c.pdbGetter, syncCtx.Recorder(), pdb) + if err != nil { + klog.Errorf("Unable to create PodDisruptionBudget: %v", err) + return fmt.Errorf("Unable to create PodDisruptionBudget: %v", err) + } + } else { + klog.Errorf("Unable to get PodDisruptionBudget: %v", err) + return err } operands := map[string]*corev1.Pod{} @@ -208,6 +222,12 @@ func (c *GuardController) sync(ctx context.Context, syncCtx factory.SyncContext) } for _, node := range nodes { + // Check whether the node is schedulable + if nodeHasUnschedulableTaint(node) { + klog.Infof("Node %v not schedulable, skipping reconciling the guard pod", node.Name) + continue + } + if _, exists := operands[node.Name]; !exists { // If the operand does not exist and the node is not ready, wait until the node becomes ready nodeReadyCondition := nodeConditionFinder(&node.Status, corev1.NodeReady) @@ -280,16 +300,24 @@ func (c *GuardController) sync(ctx context.Context, syncCtx factory.SyncContext) return utilerrors.NewAggregate(errs) } -func IsSNOCheckFnc(infraLister configv1listers.InfrastructureLister) func() (bool, error) { - return func() (bool, error) { - infraData, err := infraLister.Get("cluster") +// IsSNOCheckFnc creates a function that checks if the topology is SNO +// In case the err is nil, precheckSucceeded signifies whether the isSNO is valid. +// If precheckSucceeded is false, the isSNO return value does not reflect the cluster topology +// and defaults to the bool default value. +func IsSNOCheckFnc(infraInformer configv1informers.InfrastructureInformer) func() (isSNO, precheckSucceeded bool, err error) { + return func() (isSNO, precheckSucceeded bool, err error) { + if !infraInformer.Informer().HasSynced() { + // Do not return transient error + return false, false, nil + } + infraData, err := infraInformer.Lister().Get("cluster") if err != nil { - return false, fmt.Errorf("Unable to list infrastructures.config.openshift.io/cluster object, unable to determine topology mode") + return false, true, fmt.Errorf("Unable to list infrastructures.config.openshift.io/cluster object, unable to determine topology mode") } if infraData.Status.ControlPlaneTopology == "" { - return false, fmt.Errorf("ControlPlaneTopology was not set, unable to determine topology mode") + return false, true, fmt.Errorf("ControlPlaneTopology was not set, unable to determine topology mode") } - return infraData.Status.ControlPlaneTopology == configv1.SingleReplicaTopologyMode, nil + return infraData.Status.ControlPlaneTopology == configv1.SingleReplicaTopologyMode, true, nil } } diff --git a/vendor/modules.txt b/vendor/modules.txt index b577019c3e..74666347e0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -249,7 +249,7 @@ github.com/openshift/client-go/route/informers/externalversions/route/v1 github.com/openshift/client-go/route/listers/route/v1 github.com/openshift/client-go/user/clientset/versioned/scheme github.com/openshift/client-go/user/clientset/versioned/typed/user/v1 -# github.com/openshift/library-go v0.0.0-20220117173518-ca57b619b5d6 +# github.com/openshift/library-go v0.0.0-20220119134102-3236af51f6e1 ## explicit; go 1.17 github.com/openshift/library-go/pkg/apps/deployment github.com/openshift/library-go/pkg/assets