@@ -6,22 +6,26 @@ import (
66 "time"
77
88 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
9- flaggerv1beta1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1 "
10- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1 "
11- "k8s.io/apimachinery/pkg/fields "
9+ flaggerscheme "github.com/fluxcd/flagger/pkg/client/clientset/versioned/scheme "
10+ "github.com/samber/lo "
11+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured "
1212 "k8s.io/apimachinery/pkg/runtime"
1313 "k8s.io/apimachinery/pkg/runtime/schema"
14- "k8s.io/apimachinery/pkg/watch"
1514 "k8s.io/client-go/dynamic"
1615 "k8s.io/client-go/kubernetes"
16+ "k8s.io/client-go/kubernetes/scheme"
1717 "k8s.io/client-go/tools/cache"
18- watchtools "k8s.io/client-go/tools/watch"
1918
20- "github.com/werf/kubedog/pkg/kube "
19+ "github.com/werf/kubedog/pkg/informer "
2120 "github.com/werf/kubedog/pkg/tracker"
2221 "github.com/werf/kubedog/pkg/tracker/debug"
22+ "github.com/werf/kubedog/pkg/trackers/dyntracker/util"
2323)
2424
25+ func init () {
26+ flaggerscheme .AddToScheme (scheme .Scheme )
27+ }
28+
2529type FailedReport struct {
2630 FailedReason string
2731 CanaryStatus CanaryStatus
@@ -54,14 +58,15 @@ type Tracker struct {
5458 dynamicClient dynamic.Interface
5559}
5660
57- func NewTracker (name , namespace string , kube kubernetes.Interface , dynamicClient dynamic.Interface , opts tracker.Options ) * Tracker {
61+ func NewTracker (name , namespace string , kube kubernetes.Interface , dynamicClient dynamic.Interface , informerFactory * util. Concurrent [ * informer. InformerFactory ], opts tracker.Options ) * Tracker {
5862 return & Tracker {
5963 Tracker : tracker.Tracker {
6064 Kube : kube ,
6165 Namespace : namespace ,
6266 FullResourceName : fmt .Sprintf ("canary/%s" , name ),
6367 ResourceName : name ,
6468 LogsFromTime : opts .LogsFromTime ,
69+ InformerFactory : informerFactory ,
6570 },
6671
6772 Added : make (chan CanaryStatus , 1 ),
@@ -84,10 +89,12 @@ func NewTracker(name, namespace string, kube kubernetes.Interface, dynamicClient
8489}
8590
8691func (canary * Tracker ) Track (ctx context.Context ) error {
87- err := canary .runInformer (ctx )
92+ canaryInformerCleanupFn , err := canary .runInformer (ctx )
8893 if err != nil {
8994 return err
9095 }
96+ defer canaryInformerCleanupFn ()
97+
9198 for {
9299 select {
93100 case object := <- canary .objectAdded :
@@ -123,85 +130,67 @@ func (canary *Tracker) Track(ctx context.Context) error {
123130 }
124131}
125132
126- func (canary * Tracker ) runInformer (ctx context.Context ) error {
127- tweakListOptions := func (options metav1.ListOptions ) metav1.ListOptions {
128- options .FieldSelector = fields .OneTermEqualSelector ("metadata.name" , canary .ResourceName ).String ()
129- return options
130- }
131-
132- var lw * cache.ListWatch
133- if canary .dynamicClient != nil {
134- lw = & cache.ListWatch {
135- ListFunc : func (options metav1.ListOptions ) (runtime.Object , error ) {
136- return canary .dynamicClient .Resource (schema.GroupVersionResource {
137- Group : "flagger.app" ,
138- Version : "v1beta1" ,
139- Resource : "canaries" ,
140- }).Namespace (canary .Namespace ).List (ctx , tweakListOptions (options ))
141- },
142- WatchFunc : func (options metav1.ListOptions ) (watch.Interface , error ) {
143- return canary .dynamicClient .Resource (schema.GroupVersionResource {
144- Group : "flagger.app" ,
145- Version : "v1beta1" ,
146- Resource : "canaries" ,
147- }).Namespace (canary .Namespace ).Watch (ctx , tweakListOptions (options ))
148- },
149- }
150- } else {
151- config , err := kube .GetKubeConfig (kube.KubeConfigOptions {})
133+ func (canary * Tracker ) runInformer (ctx context.Context ) (cleanupFn func (), err error ) {
134+ var inform * util.Concurrent [* informer.Informer ]
135+ if err := canary .InformerFactory .RWTransactionErr (func (factory * informer.InformerFactory ) error {
136+ inform , err = factory .ForNamespace (schema.GroupVersionResource {
137+ Group : "flagger.app" ,
138+ Version : "v1beta1" ,
139+ Resource : "canaries" ,
140+ }, canary .Namespace )
152141 if err != nil {
153- fmt .Print ( err )
142+ return fmt .Errorf ( "get informer from factory: %w" , err )
154143 }
155144
156- flagger , err := flaggerv1beta1 . NewForConfig ( config . Config )
157- if err != nil {
158- fmt . Print ( err )
159- }
145+ return nil
146+ }); err != nil {
147+ return nil , err
148+ }
160149
161- lw = & cache.ListWatch {
162- ListFunc : func (options metav1.ListOptions ) (runtime.Object , error ) {
163- return flagger .Canaries (canary .Namespace ).List (ctx , tweakListOptions (options ))
164- },
165- WatchFunc : func (options metav1.ListOptions ) (watch.Interface , error ) {
166- return flagger .Canaries (canary .Namespace ).Watch (ctx , tweakListOptions (options ))
150+ if err := inform .RWTransactionErr (func (inf * informer.Informer ) error {
151+ handler , err := inf .AddEventHandler (
152+ cache.FilteringResourceEventHandler {
153+ FilterFunc : func (obj interface {}) bool {
154+ canaryObj := & v1beta1.Canary {}
155+ lo .Must0 (runtime .DefaultUnstructuredConverter .FromUnstructured (obj .(* unstructured.Unstructured ).Object , canaryObj ))
156+ return canaryObj .Name == canary .ResourceName &&
157+ canaryObj .Namespace == canary .Namespace
158+ },
159+ Handler : cache.ResourceEventHandlerFuncs {
160+ AddFunc : func (obj interface {}) {
161+ canaryObj := & v1beta1.Canary {}
162+ lo .Must0 (runtime .DefaultUnstructuredConverter .FromUnstructured (obj .(* unstructured.Unstructured ).Object , canaryObj ))
163+ canary .objectAdded <- canaryObj
164+ },
165+ UpdateFunc : func (oldObj , newObj interface {}) {
166+ canaryObj := & v1beta1.Canary {}
167+ lo .Must0 (runtime .DefaultUnstructuredConverter .FromUnstructured (newObj .(* unstructured.Unstructured ).Object , canaryObj ))
168+ canary .objectModified <- canaryObj
169+ },
170+ DeleteFunc : func (obj interface {}) {
171+ canaryObj := & v1beta1.Canary {}
172+ lo .Must0 (runtime .DefaultUnstructuredConverter .FromUnstructured (obj .(* unstructured.Unstructured ).Object , canaryObj ))
173+ canary .objectDeleted <- canaryObj
174+ },
175+ },
167176 },
177+ )
178+ if err != nil {
179+ return fmt .Errorf ("add event handler: %w" , err )
168180 }
169- }
170-
171- go func () {
172- _ , err := watchtools .UntilWithSync (ctx , lw , & v1beta1.Canary {}, nil , func (e watch.Event ) (bool , error ) {
173- if debug .Debug () {
174- fmt .Printf ("Canary `%s` informer event: %#v\n " , canary .ResourceName , e .Type )
175- }
176-
177- var object * v1beta1.Canary
178-
179- if e .Type != watch .Error {
180- var ok bool
181- object , ok = e .Object .(* v1beta1.Canary )
182- if ! ok {
183- return true , fmt .Errorf ("expected %s to be a *v1beta1.Canary, got %T" , canary .ResourceName , e .Object )
184- }
185- }
186181
187- switch e .Type {
188- case watch .Added :
189- canary .objectAdded <- object
190- case watch .Modified :
191- canary .objectModified <- object
192- case watch .Deleted :
193- canary .objectDeleted <- object
194- }
182+ cleanupFn = func () {
183+ inf .RemoveEventHandler (handler )
184+ }
195185
196- return false , nil
197- })
186+ inf .Run ()
198187
199- if err != tracker . AdaptInformerError ( err ) {
200- canary . errors <- fmt . Errorf ( "canary informer error: %w" , err )
201- }
202- }()
188+ return nil
189+ }); err != nil {
190+ return nil , err
191+ }
203192
204- return nil
193+ return cleanupFn , nil
205194}
206195
207196func (canary * Tracker ) handleCanaryState (ctx context.Context , object * v1beta1.Canary ) error {
0 commit comments