@@ -18,13 +18,13 @@ package controllers
1818
1919import (
2020 "context"
21+ "fmt"
2122 "os"
2223 "strconv"
2324 "strings"
2425 "time"
2526
2627 mapiclientset "github.com/openshift/client-go/machine/clientset/versioned"
27- machineinformersv1beta1 "github.com/openshift/client-go/machine/informers/externalversions"
2828 "github.com/openshift/client-go/machine/listers/machine/v1beta1"
2929
3030 appwrapperClientSet "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/clientset/versioned"
@@ -33,10 +33,13 @@ import (
3333 appwrapperlisters "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/listers/controller/v1beta1"
3434
3535 arbinformersFactory "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions"
36+
37+ machineinformersv1beta1 "github.com/openshift/client-go/machine/informers/externalversions"
3638 apierrors "k8s.io/apimachinery/pkg/api/errors"
3739 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3840 "k8s.io/apimachinery/pkg/labels"
3941 "k8s.io/apimachinery/pkg/runtime"
42+ "k8s.io/client-go/informers"
4043 "k8s.io/client-go/kubernetes"
4144 "k8s.io/client-go/tools/cache"
4245 "k8s.io/klog"
@@ -51,15 +54,20 @@ type AppWrapperReconciler struct {
5154 Scheme * runtime.Scheme
5255 ConfigsNamespace string
5356 OcmSecretNamespace string
57+ KubeClient * kubernetes.Clientset
58+ InformerFactory informers.SharedInformerFactory
59+ StopCh chan struct {}
5460}
5561
5662var (
57- scaledAppwrapper []string
58- reuse = true
59- ocmClusterID string
60- ocmToken string
61- useMachineSets bool
62-
63+ scaledAppwrapper []string
64+ scalingType string
65+ reuse = true
66+ ocmClusterID string
67+ ocmToken string
68+ useMachineSets bool
69+ useMachinePool bool
70+ useNodePool bool
6371 maxScaleNodesAllowed int
6472 msLister v1beta1.MachineSetLister
6573 machineLister v1beta1.MachineLister
@@ -92,46 +100,75 @@ const (
92100//
93101// For more details, check Reconcile and its Result here:
94102// - https://pkg.go.dev/sigs.k8s.io/[email protected] /pkg/reconcile 103+
95104func (r * AppWrapperReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
96105
97106 _ = log .FromContext (ctx )
98107
99108 var appwrapper arbv1.AppWrapper
100109 if err := r .Get (ctx , req .NamespacedName , & appwrapper ); err != nil {
101110 if apierrors .IsNotFound (err ) {
102- //ignore not-found errors, since we can get them on delete requests.
111+ // ignore not-found errors, since we can get them on delete requests.
103112 return ctrl.Result {}, nil
104113 }
105114 klog .Error (err , "unable to fetch appwrapper" )
106115 }
107116
108- factory := machineinformersv1beta1 .NewSharedInformerFactoryWithOptions (machineClient , resyncPeriod ()(), machineinformersv1beta1 .WithNamespace ("" ))
109- informer := factory .Machine ().V1beta1 ().MachineSets ().Informer ()
110- msLister = factory .Machine ().V1beta1 ().MachineSets ().Lister ()
111- machineLister = factory .Machine ().V1beta1 ().Machines ().Lister ()
117+ // This block can be moved outside the if-else condition if both the node and machineset use cases require it
112118
113- // todo: Move the getOCMClusterID call out of reconcile loop.
114- // Only reason we are calling it here is that the client is not able to make
115- // calls until it is started, so SetupWithManager is not working.
116- if ! useMachineSets && ocmClusterID == "" {
117- getOCMClusterID (r )
119+ if ocmClusterID == "" {
120+ ocmManager , err := NewOCMManager ()
121+ if err != nil {
122+ klog .Error ("Failed to initialize OCMManager:" , err )
123+ return ctrl.Result {}, err
124+ }
125+ defer ocmManager .Close ()
126+
127+ err = ocmManager .getOCMClusterID (r )
128+ if err != nil {
129+ klog .Error ("Failed to get OCM Cluster ID:" , err )
130+ return ctrl.Result {}, err
131+ }
118132 }
119133
120- stopper := make (chan struct {})
121- defer close (stopper )
122- informer .AddEventHandler (cache.ResourceEventHandlerFuncs {
123- AddFunc : onAdd ,
124- UpdateFunc : onUpdate ,
125- DeleteFunc : onDelete ,
126- })
127- go informer .Run (stopper )
128- if ! cache .WaitForCacheSync (stopper , informer .HasSynced ) {
129- klog .Info ("Wait for cache to sync" )
134+ if ! useNodePool {
135+ factory := machineinformersv1beta1 .NewSharedInformerFactoryWithOptions (machineClient , resyncPeriod ()(), machineinformersv1beta1 .WithNamespace ("" ))
136+ informer := factory .Machine ().V1beta1 ().MachineSets ().Informer ()
137+ msLister = factory .Machine ().V1beta1 ().MachineSets ().Lister ()
138+ machineLister = factory .Machine ().V1beta1 ().Machines ().Lister ()
139+
140+ stopper := make (chan struct {})
141+ defer close (stopper )
142+ informer .AddEventHandler (cache.ResourceEventHandlerFuncs {
143+ AddFunc : onAdd ,
144+ UpdateFunc : onUpdate ,
145+ DeleteFunc : onDelete ,
146+ })
147+ go informer .Run (stopper )
148+ if ! cache .WaitForCacheSync (stopper , informer .HasSynced ) {
149+ klog .Info ("Wait for cache to sync" )
150+ }
151+ msInformerHasSynced = informer .HasSynced ()
152+
153+ } else {
154+ nodeInformer := r .InformerFactory .Core ().V1 ().Nodes ().Informer ()
155+ stopper := make (chan struct {})
156+ defer close (stopper )
157+ nodeInformer .AddEventHandler (cache.ResourceEventHandlerFuncs {
158+ AddFunc : onAdd ,
159+ UpdateFunc : onUpdate ,
160+ DeleteFunc : onDelete ,
161+ })
162+ go nodeInformer .Run (stopper )
163+ if ! cache .WaitForCacheSync (stopper , nodeInformer .HasSynced ) {
164+ klog .Info ("Failed to wait for node informer cache to sync" )
165+ return ctrl.Result {}, fmt .Errorf ("failed to wait for node informer cache to sync" )
166+ }
167+ //TODO: do we need dual sync??
168+ msInformerHasSynced = nodeInformer .HasSynced ()
130169 }
131- //TODO: do we need dual sync??
132- msInformerHasSynced = informer .HasSynced ()
170+
133171 addAppwrappersThatNeedScaling ()
134- <- stopper
135172 return ctrl.Result {}, nil
136173}
137174
@@ -166,13 +203,21 @@ func (r *AppWrapperReconciler) SetupWithManager(mgr ctrl.Manager) error {
166203 }
167204
168205 useMachineSets = true
206+ useMachinePool = false
207+ useNodePool = false
208+
169209 ocmSecretExists := ocmSecretExists (r .OcmSecretNamespace )
170210 if ocmSecretExists {
171- machinePoolsExists := machinePoolExists ()
172-
173- if machinePoolsExists {
211+ nodepoolexists := nodePoolExists ()
212+ machinepoolexists := machinePoolExists ()
213+ if nodepoolexists {
214+ useMachineSets = false
215+ useNodePool = true
216+ klog .Infof ("Using node pools %v" , nodepoolexists )
217+ } else if machinepoolexists {
174218 useMachineSets = false
175- klog .Infof ("Using machine pools %v" , machinePoolsExists )
219+ useMachinePool = true
220+ klog .Infof ("Setting useMachinePools to %v" , machinepoolexists )
176221 } else {
177222 klog .Infof ("Setting useMachineSets to %v" , useMachineSets )
178223 }
@@ -245,7 +290,7 @@ func onAdd(obj interface{}) {
245290 demandPerInstanceType := discoverInstanceTypes (aw )
246291
247292 if demandPerInstanceType != nil {
248- if (useMachineSets && canScaleMachineset (demandPerInstanceType )) || (! useMachineSets && canScaleMachinepool (demandPerInstanceType )) {
293+ if (useMachineSets && canScaleMachineset (demandPerInstanceType )) || (! useMachineSets && ( canScaleNodepool ( demandPerInstanceType ) || canScaleMachinepool (demandPerInstanceType ) )) {
249294 scaleUp (aw , demandPerInstanceType )
250295 } else {
251296 klog .Infof ("Cannot scale up replicas. The maximum allowed replicas is %v" , maxScaleNodesAllowed )
@@ -312,6 +357,10 @@ func canScaleMachinepool(demandPerInstanceType map[string]int) bool {
312357 return true
313358}
314359
360+ func canScaleNodepool (demandPerInstanceType map [string ]int ) bool {
361+ return true
362+ }
363+
315364func scaleUp (aw * arbv1.AppWrapper , demandMapPerInstanceType map [string ]int ) {
316365 if msInformerHasSynced {
317366 //Assumption is made that the cluster has machineset configure that AW needs
@@ -321,6 +370,8 @@ func scaleUp(aw *arbv1.AppWrapper, demandMapPerInstanceType map[string]int) {
321370
322371 if useMachineSets {
323372 scaleMachineSet (aw , userRequestedInstanceType , replicas )
373+ } else if useNodePool {
374+ scaleNodePool (aw , userRequestedInstanceType , replicas )
324375 } else {
325376 scaleMachinePool (aw , userRequestedInstanceType , replicas )
326377 }
@@ -401,6 +452,8 @@ func onDelete(obj interface{}) {
401452 klog .Infof ("Appwrapper deleted scale-down machineset: %s " , aw .Name )
402453 scaleDown (aw )
403454 }
455+ } else if useNodePool {
456+ deleteNodePool (aw )
404457 } else {
405458 deleteMachinePool (aw )
406459 }
0 commit comments