Extend apinet-nic-plugin to watch and cleanup NICs#715
Conversation
Signed-off-by: Lukas Frank <lukas.frank@sap.com>
c0947f6 to
b043eff
Compare
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughEvent-driven NIC lifecycle: plugin Init now accepts a context and supports event handler registration. APINet switched from polling to informer-driven watcher that notifies handlers on NIC status changes. Machine controller subscribes to NIC events and requeues machines; Apply/Delete semantics adjusted to surface not-ready state. Changes
Sequence Diagram(s)sequenceDiagram
participant MC as Machine Controller
participant Plugin as APINet Plugin
participant Watcher as Informer Watcher
participant API as API Server
participant Handler as Event Handler
MC->>Plugin: Init(ctx, host)
Plugin->>Watcher: start(ctx)
Watcher->>API: List NICs for node (initial cache)
API-->>Watcher: return NIC list
API->>Watcher: NIC update/delete event
Watcher->>Plugin: notify on Status.State change or delete (machine-id present)
Plugin->>Handler: call HandleNICEvent(machineID)
Handler->>MC: HandleNICEventFunc(machineID)
MC->>MC: queue.Add(machineID) (requeue machine)
MC->>Plugin: Apply(host, nicSpec)
alt host device absent
Plugin-->>MC: ErrNotReady
MC->>MC: defer attach (no mount)
else host device present
Plugin-->>MC: return mounted NIC
end
MC->>Plugin: Delete(nic)
Plugin->>API: delete NIC (tolerate NotFound)
Plugin->>Watcher: watcher will emit delete -> Handler -> MC requeue
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/plugins/networkinterface/apinet/apinet.go`:
- Around line 384-401: The handleNICDelete function currently returns early if
obj is not an *apinetv1alpha1.NetworkInterface, which skips handling tombstones;
update handleNICDelete to detect and unwrap toolscache.DeletedFinalStateUnknown
(the tombstone wrapper), extract the inner Obj, cast that to
*apinetv1alpha1.NetworkInterface and proceed exactly as for a normal delete
(checking nic.Spec.NodeRef.Name vs p.nodeName, reading labelMachineID, logging
and calling p.notifyEventHandlers(machineID)); keep existing early returns for
missing labels or wrong node but ensure tombstone-unwrapped NICs are handled the
same as direct NIC delete events.
- Around line 77-87: The watcher is started in Init() via go p.runWatcher(ctx)
which returns immediately and can allow informer cache sync to trigger
enqueueNICMachines() before MachineReconciler.Start() has registered handlers
(AddEventHandler), and handleNICDelete() currently asserts deleted objects to
*NetworkInterface without handling cache.DeletedFinalStateUnknown tombstones.
Fix by making Init() block until the watcher is fully started and its informer
caches have synced (or return an error on sync failure) before returning so
MachineReconciler.Start() can register handlers first; alternatively register
event handlers prior to starting the informer in runWatcher. Also harden
handleNICDelete() to accept cache.DeletedFinalStateUnknown by type-switching the
object, extracting the contained object and then asserting to *NetworkInterface
(or handling missing/invalid types) so deletion tombstones do not cause panics
and deletion recovery runs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9bb520dd-2cc2-4acd-8c07-d641c4f8657e
📒 Files selected for processing (9)
cmd/libvirt-provider/app/app.gointernal/controllers/controllers_suite_test.gointernal/controllers/machine_controller.gointernal/controllers/machine_controller_nics.gointernal/networkinterfaceplugin/apinet.gointernal/plugins/networkinterface/apinet/apinet.gointernal/plugins/networkinterface/isolated/isolated.gointernal/plugins/networkinterface/plugins.gointernal/plugins/networkinterface/providernetwork/providernetwork.go
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
internal/plugins/networkinterface/apinet/apinet.go (1)
79-89:⚠️ Potential issue | 🟠 MajorMake watcher startup synchronous.
Init()still returns immediately aftergo p.runWatcher(ctx). That means watcher creation/cache-sync failures are only logged, and the bootstrapenqueueNICMachines()pass can still run before any handler is registered, dropping the initial requeues this recovery path depends on. Please makeInit()wait for watcher readiness/failure, or guarantee handlers are registered before the watcher starts.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/plugins/networkinterface/apinet/apinet.go` around lines 79 - 89, The Init method returns immediately after launching runWatcher in a goroutine, causing handler registration and cache sync races; change Init (in function Init of type Plugin) to wait for watcher startup success or failure before returning by either (a) registering handlers (the handlers that enqueueNICMachines) on p.apinetClient prior to starting the watcher and then calling runWatcher synchronously so Init blocks until readiness/failure, or (b) modify runWatcher to signal readiness/failure via a channel or error return and have Init start it and wait on that signal (or error) before returning; ensure you reference p.runWatcher, p.apinetClient and the handler registration that enqueues NIC machines so the initial enqueueNICMachines pass cannot run before the watcher is ready.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/plugins/networkinterface/apinet/apinet.go`:
- Around line 98-104: RemoveEventHandler must not compare
providernetworkinterface.EventHandler interface values directly (comparing h ==
handler can panic for concrete types like EventHandlerFuncs that contain func
fields). Change the registration API so AddEventHandler (or wherever handlers
are registered) returns a removal token/unsubscribe function or a numeric ID,
store handlers in p.eventHandlers keyed by that token/ID (or wrap entries in a
struct with id and handler), and implement RemoveEventHandler to accept that
token/ID (or call the returned unsubscribe) and remove the matching entry from
p.eventHandlers instead of doing interface equality; update references to
RemoveEventHandler and the event registration path accordingly (look for
Plugin.RemoveEventHandler, p.eventHandlers and
providernetworkinterface.EventHandler/ EventHandlerFuncs).
---
Duplicate comments:
In `@internal/plugins/networkinterface/apinet/apinet.go`:
- Around line 79-89: The Init method returns immediately after launching
runWatcher in a goroutine, causing handler registration and cache sync races;
change Init (in function Init of type Plugin) to wait for watcher startup
success or failure before returning by either (a) registering handlers (the
handlers that enqueueNICMachines) on p.apinetClient prior to starting the
watcher and then calling runWatcher synchronously so Init blocks until
readiness/failure, or (b) modify runWatcher to signal readiness/failure via a
channel or error return and have Init start it and wait on that signal (or
error) before returning; ensure you reference p.runWatcher, p.apinetClient and
the handler registration that enqueues NIC machines so the initial
enqueueNICMachines pass cannot run before the watcher is ready.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b0fc0083-ab36-4d66-855e-28cad99bd125
📒 Files selected for processing (2)
internal/controllers/machine_controller_nics.gointernal/plugins/networkinterface/apinet/apinet.go
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/controllers/machine_controller_nics.go
Signed-off-by: Lukas Frank <lukas.frank@sap.com>
Signed-off-by: Lukas Frank <lukas.frank@sap.com>
Proposed Changes
apinet-nic-pluginto watch and cleanup NICsNICis manually deleted, it will be recreated by controllerFixes #714 #590
Summary by CodeRabbit
New Features
Refactor