Skip to content

Commit 1981a89

Browse files
Fix: Ensure prompt initial DHCP cache sync on agent startup
This commit addresses a potential delay in the agent's DHCP lease cache synchronization upon startup or leader election. Previously, the cache might only populate after an explicit update to the watched IPPool CR. Changes: - Added an `AddFunc` to the IPPool informer in the agent's event handler (`pkg/agent/ippool/event.go`). This ensures that IPPools listed during the informer's initial LIST operation are queued for processing. - Modified the agent's local IPPool controller (`pkg/agent/ippool/controller.go`) to handle these "ADD" events identically to "UPDATE" events. This involves calling the `Update` method to populate the DHCPAllocator's cache and then signaling on the `initialSyncDone` channel. These changes ensure that the agent primes its lease cache as soon as the IPPool information is available from the informer, allowing the DHCP server to start with accurate lease data more promptly.
1 parent f3f6668 commit 1981a89

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

pkg/agent/ippool/controller.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,29 @@ func (c *Controller) sync(event Event) (err error) {
8585
}
8686

8787
switch event.action {
88-
case UPDATE:
88+
case ADD, UPDATE: // Handle ADD and UPDATE identically for cache priming
8989
ipPool, ok := obj.(*networkv1.IPPool)
9090
if !ok {
91-
logrus.Error("(controller.sync) failed to assert obj during UPDATE")
91+
logrus.Errorf("(controller.sync) failed to assert obj during %s event for key %s", event.action, event.key)
92+
return nil // Don't requeue if type assertion fails
9293
}
93-
logrus.Infof("(controller.sync) UPDATE %s/%s", ipPool.Namespace, ipPool.Name)
94+
logrus.Infof("(controller.sync) %s %s/%s", event.action, ipPool.Namespace, ipPool.Name)
9495
if err := c.Update(ipPool); err != nil {
95-
logrus.Errorf("(controller.sync) failed to update DHCP lease store for IPPool %s/%s: %s", ipPool.Namespace, ipPool.Name, err.Error())
96+
logrus.Errorf("(controller.sync) failed to update DHCP lease store for IPPool %s/%s during %s event: %s", ipPool.Namespace, ipPool.Name, event.action, err.Error())
9697
return err // Return error to requeue
9798
}
9899
// If update was successful, this is a good place to signal initial sync
100+
// This will be called for the first ADD or UPDATE event that successfully processes.
99101
c.initialSyncOnce.Do(func() {
100-
logrus.Infof("Initial sync completed for IPPool %s/%s, signaling DHCP server.", ipPool.Namespace, ipPool.Name)
102+
logrus.Infof("Initial sync processing completed for IPPool %s/%s (triggered by %s event), signaling DHCP server.", ipPool.Namespace, ipPool.Name, event.action)
101103
close(c.initialSyncDone)
102104
})
105+
// Potentially handle DELETE if needed in the future
106+
// case DELETE:
107+
// logrus.Infof("(controller.sync) DELETE %s", event.key)
108+
// // Perform cleanup if necessary, e.g., clearing leases from dhcpAllocator
109+
// // if this agent is supposed to stop serving this pool.
110+
// // However, for a single watched IPPool, deletion might mean the agent has no work.
103111
}
104112

105113
return

pkg/agent/ippool/event.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,34 @@ func (e *EventHandler) EventListener(ctx context.Context) {
105105
queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
106106

107107
indexer, informer := cache.NewIndexerInformer(watcher, &networkv1.IPPool{}, 0, cache.ResourceEventHandlerFuncs{
108+
AddFunc: func(obj interface{}) {
109+
key, err := cache.MetaNamespaceKeyFunc(obj)
110+
if err == nil {
111+
ipPool := obj.(*networkv1.IPPool)
112+
queue.Add(Event{
113+
key: key,
114+
action: ADD, // Use ADD action
115+
poolName: ipPool.ObjectMeta.Name,
116+
poolNetworkName: ipPool.Spec.NetworkName,
117+
})
118+
logrus.Debugf("(eventhandler.EventListener) AddFunc: Queued ADD event for IPPool %s", key)
119+
}
120+
},
108121
UpdateFunc: func(old interface{}, new interface{}) {
109122
key, err := cache.MetaNamespaceKeyFunc(new)
110123
if err == nil {
124+
ipPool := new.(*networkv1.IPPool)
111125
queue.Add(Event{
112126
key: key,
113127
action: UPDATE,
114-
poolName: new.(*networkv1.IPPool).ObjectMeta.Name,
115-
poolNetworkName: new.(*networkv1.IPPool).Spec.NetworkName,
128+
poolName: ipPool.ObjectMeta.Name,
129+
poolNetworkName: ipPool.Spec.NetworkName,
116130
})
131+
logrus.Debugf("(eventhandler.EventListener) UpdateFunc: Queued UPDATE event for IPPool %s", key)
117132
}
118133
},
134+
// Consider adding DeleteFunc if agent needs to react to IPPool deletion,
135+
// though for a single watched IPPool, this might mean the agent stops.
119136
}, cache.Indexers{})
120137

121138
controller := NewController(queue, indexer, informer, e.poolRef, e.dhcpAllocator, e.poolCache, e.InitialSyncDone, &e.initialSyncOnce)

0 commit comments

Comments
 (0)