@@ -8,14 +8,13 @@ import (
8
8
"sync"
9
9
"time"
10
10
11
+ "github.com/kubescape/kapprofiler/pkg/watcher"
11
12
v1 "k8s.io/api/core/v1"
12
13
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
14
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14
15
"k8s.io/apimachinery/pkg/runtime"
15
16
"k8s.io/apimachinery/pkg/runtime/schema"
16
17
apitypes "k8s.io/apimachinery/pkg/types"
17
- "k8s.io/client-go/dynamic/dynamicinformer"
18
- "k8s.io/client-go/tools/cache"
19
18
)
20
19
21
20
type PodProfileFinalizerState struct {
@@ -34,33 +33,31 @@ func (cm *CollectorManager) StartFinalizerWatcher() {
34
33
cm .podFinalizerStateMutex = & sync.Mutex {}
35
34
// Initialize map
36
35
cm .podFinalizerState = make (map [string ]* PodProfileFinalizerState )
36
+ // Initialize watcher
37
+ cm .podFinalizerWatcher = watcher .NewWatcher (cm .dynamicClient , false )
37
38
38
- // Initialize factory and informer
39
- factory := dynamicinformer .NewFilteredDynamicSharedInformerFactory (cm .dynamicClient , 0 , metav1 .NamespaceAll , func (lo * metav1.ListOptions ) {
40
- lo .FieldSelector = "spec.nodeName=" + cm .config .NodeName
41
- })
42
- // Informer for Pods
43
- informer := factory .ForResource (schema.GroupVersionResource {
44
- Group : "" ,
45
- Version : "v1" ,
46
- Resource : "pods" ,
47
- }).Informer ()
48
-
49
- // Add event handlers to informer
50
- informer .AddEventHandler (cache.ResourceEventHandlerFuncs {
51
- AddFunc : func (obj interface {}) {
39
+ // Start watcher
40
+ err := cm .podFinalizerWatcher .Start (watcher.WatchNotifyFunctions {
41
+ AddFunc : func (obj * unstructured.Unstructured ) {
52
42
cm .handlePodAddEvent (obj )
53
43
},
54
- UpdateFunc : func (oldObj , newObj interface {} ) {
55
- cm .handlePodUpdateEvent (oldObj , newObj )
44
+ UpdateFunc : func (obj * unstructured. Unstructured ) {
45
+ cm .handlePodUpdateEvent (obj )
56
46
},
57
- DeleteFunc : func (obj interface {} ) {
47
+ DeleteFunc : func (obj * unstructured. Unstructured ) {
58
48
cm .handlePodDeleteEvent (obj )
59
49
},
60
- })
50
+ }, schema.GroupVersionResource {
51
+ Group : "" ,
52
+ Version : "v1" ,
53
+ Resource : "pods" ,
54
+ }, metav1.ListOptions {})
61
55
62
- // Run the informer
63
- go informer .Run (cm .podFinalizerControl )
56
+ if err != nil {
57
+ log .Printf ("Error starting watcher: %v" , err )
58
+ cm .podFinalizerWatcher = nil
59
+ return
60
+ }
64
61
}
65
62
66
63
func generateTableKey (obj metav1.Object ) string {
@@ -69,8 +66,6 @@ func generateTableKey(obj metav1.Object) string {
69
66
70
67
func (cm * CollectorManager ) handlePodAddEvent (obj interface {}) {
71
68
// Add pod to finalizer map
72
-
73
- // Convert object to Pod
74
69
pod , err := ConvertInterfaceToPod (obj )
75
70
if err != nil {
76
71
log .Printf ("the interface is not a Pod %v" , err )
@@ -103,59 +98,44 @@ func (cm *CollectorManager) handlePodAddEvent(obj interface{}) {
103
98
cm .startFinalizationTimer (pod )
104
99
}
105
100
}
106
-
107
101
}
108
102
109
- func (cm * CollectorManager ) handlePodUpdateEvent (oldObj , newObj interface {}) {
110
- // Need to access the status of the old and new pod to check if the pod became ready
111
-
103
+ func (cm * CollectorManager ) handlePodUpdateEvent (obj interface {}) {
112
104
// Convert interface to Pod object
113
- oldPod , err := ConvertInterfaceToPod (oldObj )
114
- if err != nil {
115
- log .Printf ("the interface is not a Pod %v" , err )
116
- return
117
- }
118
- newPod , err := ConvertInterfaceToPod (newObj )
105
+ pod , err := ConvertInterfaceToPod (obj )
119
106
if err != nil {
120
107
log .Printf ("the interface is not a Pod %v" , err )
121
108
return
122
109
}
123
110
124
111
// Check if recoding
125
112
cm .podFinalizerStateMutex .Lock ()
126
- finalizerState , ok := cm .podFinalizerState [generateTableKey (oldPod )]
113
+ finalizerState , ok := cm .podFinalizerState [generateTableKey (& pod . ObjectMeta )]
127
114
if ! ok || ! finalizerState .Recording {
128
115
// Discard
129
116
cm .podFinalizerStateMutex .Unlock ()
130
117
return
131
118
}
132
119
cm .podFinalizerStateMutex .Unlock ()
133
120
134
- // Check old pod status
135
- oldPodReady := false
136
- for _ , condition := range oldPod .Status .Conditions {
137
- if condition .Type == v1 .PodReady && condition .Status == v1 .ConditionTrue {
138
- oldPodReady = true
139
- }
140
- }
141
-
142
- newPodReady := false
143
- for _ , condition := range newPod .Status .Conditions {
121
+ // Check pod status
122
+ podReady := false
123
+ for _ , condition := range pod .Status .Conditions {
144
124
if condition .Type == v1 .PodReady && condition .Status == v1 .ConditionTrue {
145
- newPodReady = true
125
+ podReady = true
146
126
}
147
127
}
148
128
149
- if newPodReady && ! oldPodReady {
129
+ if podReady {
150
130
// Pod became ready, add finalizer
151
131
// Get mutex
152
132
cm .podFinalizerStateMutex .Lock ()
153
133
defer cm .podFinalizerStateMutex .Unlock ()
154
134
155
135
// Check if pod is in map
156
- podState , ok := cm .podFinalizerState [generateTableKey (newPod )]
136
+ podState , ok := cm .podFinalizerState [generateTableKey (& pod . ObjectMeta )]
157
137
if ! ok {
158
- log .Printf ("Pod %s in namespace %s not in finalizer map" , newPod .GetName (), newPod .GetNamespace ())
138
+ log .Printf ("Pod %s in namespace %s not in finalizer map" , pod .GetName (), pod .GetNamespace ())
159
139
return
160
140
}
161
141
@@ -166,16 +146,16 @@ func (cm *CollectorManager) handlePodUpdateEvent(oldObj, newObj interface{}) {
166
146
}
167
147
168
148
// Timer is not running, add finalizer
169
- podState .FinalizationTimer = cm .startFinalizationTimer (newPod )
170
- } else if ! newPodReady && oldPodReady {
171
- cm .stopTimer (& newPod .ObjectMeta )
149
+ podState .FinalizationTimer = cm .startFinalizationTimer (pod )
150
+ } else {
151
+ cm .stopTimer (& pod .ObjectMeta )
172
152
}
173
153
}
174
154
175
155
// Timer function
176
156
func (cm * CollectorManager ) startFinalizationTimer (pod * v1.Pod ) * time.Timer {
177
- jitter := time . Duration (rand .Intn (int (cm .config .FinalizeJitter ))) * time . Second
178
- finalizationTimer := time .NewTimer (time .Duration (cm .config .FinalizeTime + uint64 ( jitter ) ) * time .Second )
157
+ jitter := uint64 (rand .Intn (int (cm .config .FinalizeJitter )))
158
+ finalizationTimer := time .NewTimer (time .Duration (cm .config .FinalizeTime + jitter ) * time .Second )
179
159
180
160
// This goroutine waits for the timer to finish.
181
161
go func () {
@@ -303,7 +283,11 @@ func (cm *CollectorManager) MarkPodNotRecording(pod, namespace string) {
303
283
}
304
284
305
285
func (cm * CollectorManager ) StopFinalizerWatcher () {
306
- close (cm .podFinalizerControl )
286
+ if cm .podFinalizerWatcher != nil {
287
+ cm .podFinalizerWatcher .Stop ()
288
+ } else {
289
+ log .Printf ("Pod finalizer watcher not started" )
290
+ }
307
291
}
308
292
309
293
func ConvertInterfaceToPod (obj interface {}) (* v1.Pod , error ) {
0 commit comments