Skip to content

fix: remove deprecated managed annotation after MetalLB upgrade - #3076

Open
somaz94 wants to merge 2 commits into
metallb:mainfrom
somaz94:fix/strip-deprecated-managed-annotations
Open

somaz94 wants to merge 2 commits into
metallb:mainfrom
somaz94:fix/strip-deprecated-managed-annotations

Conversation

@somaz94

@somaz94 somaz94 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The controller writes the current metallb.io/ip-allocated-from-pool managed
annotation but never removes the deprecated metallb.universe.tf/ip-allocated-from-pool
one, so a service allocated by an older MetalLB version keeps both annotations
after an upgrade (#2642). This deletes the deprecated managed annotation in
convergeBalancer right after the current one is set.

Scope: only the controller-managed annotation is removed. User-set deprecated
annotations (address-pool, loadBalancerIPs, allow-shared-ip) are left untouched
since the controller does not own them.

Validation (local):

  • go test ./controller/... passes
  • new test TestControllerRemovesDeprecatedManagedAnnotation fails before the
    change (service keeps both annotations) and passes after
  • golangci-lint run ./controller/... reports 0 issues

Fixes #2642

Summary by CodeRabbit

  • Bug Fixes
    • Deprecated service annotations are now removed during reconciliation.
    • Stale allocation and address-pool annotations are cleared when service state changes or is reset.
    • Current annotation values are preserved when services continue using supported configuration.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where deprecated managed annotations could linger on services upgraded from older MetalLB versions. It updates convergeBalancer to delete the deprecated annotation and adds a corresponding unit test to verify this behavior. The feedback suggests also removing this deprecated annotation in clearServiceState to ensure it is properly cleaned up when a service is unassigned or cleared.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread controller/service.go
// Drop the deprecated managed annotation that may linger on services
// allocated by an older MetalLB version, so it does not coexist with the
// current one after an upgrade. See https://github.com/metallb/metallb/issues/2642.
delete(svc.Annotations, DeprecatedAnnotationIPAllocateFromPool)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While deleting the deprecated managed annotation DeprecatedAnnotationIPAllocateFromPool in convergeBalancer is correct, we should also ensure it is removed when the service state is cleared in clearServiceState (around line 251). If a service carrying the deprecated annotation is unassigned or cleared, clearServiceState currently only deletes the active AnnotationIPAllocateFromPool annotation, leaving the deprecated one behind. This would falsely indicate to users or external tools that the service is still allocated from a pool.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — this is already covered in the same commit. clearServiceState drops the deprecated annotation right after the active one:

func (c *controller) clearServiceState(key string, svc *v1.Service) {
	c.ips.Unassign(key)
	delete(svc.Annotations, AnnotationIPAllocateFromPool)
	// Also drop the deprecated managed annotation so an unassigned or cleared
	// service does not keep falsely advertising a pool allocation after an
	// upgrade.
	delete(svc.Annotations, DeprecatedAnnotationIPAllocateFromPool)
	svc.Status.LoadBalancer = v1.LoadBalancerStatus{}
}

There is a dedicated regression test for exactly this path too — TestControllerClearsDeprecatedManagedAnnotation in controller/controller_test.go, alongside TestControllerRemovesDeprecatedManagedAnnotation for the convergeBalancer path. Both pass.

I've also just rebased onto main to clear the stale static-security-analysis failure.

@somaz94
somaz94 force-pushed the fix/strip-deprecated-managed-annotations branch from 19c566e to e48b493 Compare June 22, 2026 05:07
@somaz94

somaz94 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

The static-security-analysis job is failing, but the failure is unrelated to this PR's diff. govulncheck panics before it produces any findings:

panic: ForEachElement called on type containing *types.TypeParam
  golang.org/x/tools@v0.46.0/internal/typesinternal/element.go:130
  golang.org/x/tools@v0.46.0/go/ssa/ssautil/visit.go:139
  golang.org/x/vuln@v1.4.0/internal/vulncheck/source.go:56

This is a known incompatibility between golang.org/x/tools v0.46.0 (pulled in by govulncheck@latestx/vuln v1.4.0) and the Go 1.25 generics handling in the SSA call-graph builder — the scanner crashes in its own internals and never reaches any metallb/ source. Pinning govulncheck to a Go 1.25-compatible release in the workflow would resolve the job. Happy to rebase once that's sorted. Let me know if there's anything I should adjust on the PR itself.

@somaz94
somaz94 marked this pull request as ready for review June 24, 2026 01:28
@somaz94
somaz94 requested review from fedepaol and oribon as code owners June 24, 2026 01:28
@somaz94
somaz94 force-pushed the fix/strip-deprecated-managed-annotations branch from e48b493 to 91e4dd8 Compare July 24, 2026 03:24
@somaz94

somaz94 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Could I ask for a re-run of the e2e (ipv6, native, helm) leg on run 30064147627? It is not a test failure — the kind cluster never came up:

ERROR: failed to create cluster: failed to pull image "kindest/node:v1.31.0@sha256:53df588e..."
Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded

The failing step is Deploy MetalLB, so zero specs ran (the follow-on chmod: cannot access /tmp/kind_logs failure is just the cascade). That is a Docker Hub registry timeout rather than anything in this diff, which is limited to two hunks in controller/service.go plus its test file.

Also, is static-security-analysis a required check here? It appears to be repo-wide rather than specific to this PR — main has been red on it consistently, the workflow installs the scanner unpinned (go install golang.org/x/vuln/cmd/govulncheck@latest), and all three reported vulns are in indirect dependencies that this PR does not touch (go.mod / go.sum are unchanged here).

For context on review state: the only review this PR ever received was from gemini-code-assist, and its one substantive point was factually incorrect — the clearServiceState deletion it asked for was already present in the same commit, with a dedicated regression test (TestControllerClearsDeprecatedManagedAnnotation). I replied on that thread with the code. So there is nothing outstanding on my side.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Signed-off-by: somaz <genius5711@gmail.com>
@somaz94
somaz94 force-pushed the fix/strip-deprecated-managed-annotations branch from 91e4dd8 to 4673254 Compare July 30, 2026 02:59
@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has been open 30 days
with no activity. This issue will be closed in 10 days unless you do one of the following:

  • respond or perform some activity on this PR
  • have one of these labels applied: hold

@somaz94

somaz94 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Still relevant — this fixes #2642 and the diff hasn't changed.

On the red e2e-use-operator: I don't think it comes from this PR. All four failures are ibgp-multi-hop ... BGP session not established timing out at 240s in e2etest/bgptests/validate.go, and the same failure shows up on branches that can't touch BGP — the dependabot bumps of golang/govulncheck-action (run 30780412731) and actions/stale (run 30780356804) both hit it on the same peer. This PR only adds two delete() calls for the deprecated annotation in controller/service.go and doesn't go near FRR or the speaker.

Could someone re-run that job or apply a hold label? Attempt 2 is already used up.

@somaz94

somaz94 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Updating my earlier note on the red checks, which is now out of date.

static-security-analysis no longer panics — govulncheck completes and exits 3 with three findings (GO-2026-6061 grpc, GO-2026-5970 x/text, GO-2026-5506 otel). All three are go.mod dependency versions, and this PR doesn't touch go.mod. The reported call sites are all under internal/k8s/, while this PR only changes controller/service.go and controller/controller_test.go.

The same job fails identically on main (the last four runs) and on other open PRs, including #3125. #3124 and #3111 look like the actual fixes.

e2e-use-operator is four BGP peering timeouts, which don't touch the annotation path this PR changes — happy to have it re-run if that helps.

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 0a713d44-e57d-4614-a4b8-23254116a823

📥 Commits

Reviewing files that changed from the base of the PR and between 1860578 and 0656091.

📒 Files selected for processing (2)
  • controller/controller_test.go
  • controller/service.go

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The controller now removes deprecated managed annotations when allocating or clearing service state. Tests record updated services and verify cleanup for LoadBalancer and non-LoadBalancer services.

Changes

Managed annotation cleanup

Layer / File(s) Summary
Controller annotation cleanup
controller/service.go
convergeBalancer and clearServiceState remove the deprecated managed annotation alongside the current annotation.
Reconciliation tests
controller/controller_test.go
The mock records updated services. Tests verify deprecated annotation removal during allocation and state clearing.

Priority: ⬇️ Low — Impact reflects low issue severity.

Estimated code review effort: 2 (Simple) | ~10 minutes

Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to 06560

Services upgraded from older MetalLB versions will have the deprecated managed IP-pool annotation removed while current allocation state is retained or cleared as appropriate. No current merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: removing the deprecated managed annotation after a MetalLB upgrade.
Description check ✅ Passed The description explains the bug, scope, fix, validation, and linked issue. It does not include the template's explicit bug-fix classification or release-note section, but it is otherwise complete.
Linked Issues check ✅ Passed The changes satisfy issue #2642 by removing the deprecated managed ip-allocated-from-pool annotation while retaining the current annotation. Regression tests cover the upgrade and service-state cleari…
Out of Scope Changes check ✅ Passed The code and tests remain within the scope of removing stale MetalLB-managed annotations and validating the related reconciliation behavior. No unrelated changes are identified.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@somaz94

somaz94 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@oribon this is the follow-up to #3079: it removes the deprecated managed annotation after an upgrade, so the state left by the old controller does not linger. When you have a moment, could you take a look? The CI matrix on this head is red, but it is red the same way on every PR this week, including the dependabot bumps, so I do not think it is this change. I will rebase to re-run it whenever you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deprecated MetalLB managed annotations not removed from service on upgrade

2 participants