Skip to content

Conversation

joamaki
Copy link
Contributor

@joamaki joamaki commented May 8, 2025

This implements a new testing.ObjectTracker on top of StateDB that fixes the long-standing pain point with the k8s fake client, namely that its Watch implementation does not support multiple watchers and it will miss events that happen between List and Watch. This new implementation understands ResourceVersion and allows starting to watch from older versions without missing events.

This will also help doing more complicated integration tests where we would e.g. run the agent and the operator hives in the same process with a single fake client & tracker and we would be able to have both watching the same resources.

An extra bonus is that we now have debug logging for every k8s action that is done:

logger.go:256: time=2025-05-08T18:35:43.964+02:00 level=DEBUG source=/home/jussi/go/src/github.com/cilium/cilium/pkg/k8s/client/object_tracker.go:324 msg=Get module=k8s-fake-client clientset=* gvr="cilium.io/v2, Resource=ciliumloadbalancerippools" k8sNamespace="" name=pool-a resourceVersion=9
logger.go:256: time=2025-05-08T18:35:43.964+02:00 level=DEBUG source=/home/jussi/go/src/github.com/cilium/cilium/pkg/k8s/client/object_tracker.go:436 msg=Update module=k8s-fake-client clientset=* obj="&{TypeMeta:{Kind: APIVersion:} ObjectMeta:{Name:pool-a GenerateName: Namespace: SelfLink: UID: ResourceVersion:9 Generation:0 CreationTimestamp:0001-01-01 00:00:00 +0000 UTC DeletionTimestamp:<nil> DeletionGracePeriodSeconds:<nil> Labels:map[] Annotations:map[] OwnerReferences:[] Finalizers:[] ManagedFields:[]} Spec:{ServiceSelector:nil AllowFirstLastIPs: Blocks:[{Cidr:10.0.0.0/24 Start: Stop:}] Disabled:false} Status:{Conditions:[{Type:cilium.io/PoolConflict Status:False ObservedGeneration:0 LastTransitionTime:2025-05-08 18:35:43 +0200 CEST Reason:resolved Message:} {Type:cilium.io/IPsTotal Status:Unknown ObservedGeneration:0 LastTransitionTime:2025-05-08 18:35:43 +0200 CEST Reason:noreason Message:256} {Type:cilium.io/IPsAvailable Status:Unknown ObservedGeneration:0 LastTransitionTime:2025-05-08 18:35:43 +0200 CEST Reason:noreason Message:255}]}}" resourceVersion=9
etc.

@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from a4ee357 to 39d8681 Compare May 8, 2025 16:29
@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label May 8, 2025
@joamaki joamaki added the release-note/misc This PR makes changes that have no direct user impact. label May 8, 2025
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label May 8, 2025
@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from 39d8681 to 297ee87 Compare May 8, 2025 16:33
Copy link
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

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

nice! I've added a comment re a deadlock that I think should happen, but maybe I misunderstood something.

One more place to clean up might be the controlplane tests, where there's the whole infra for waiting for the watch to be established. Otherwise I can do that in a separate PR.

@joamaki
Copy link
Contributor Author

joamaki commented May 20, 2025

nice! I've added a comment re a deadlock that I think should happen, but maybe I misunderstood something.

One more place to clean up might be the controlplane tests, where there's the whole infra for waiting for the watch to be established. Otherwise I can do that in a separate PR.

I'm planning to remove test/controlplane completely soon so probably not worth it.

@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch 2 times, most recently from 70f37e5 to ddc224a Compare May 20, 2025 14:07
@joamaki joamaki marked this pull request as ready for review May 21, 2025 08:38
@joamaki joamaki requested review from a team as code owners May 21, 2025 08:38
Copy link
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

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

LGTM modulo one missed db/initialized

Copy link
Contributor

@tommyp1ckles tommyp1ckles left a comment

Choose a reason for hiding this comment

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

Looks good, just some small things here and there..

@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from ddc224a to 8a10a10 Compare May 27, 2025 12:04
@joamaki joamaki requested a review from a team as a code owner May 27, 2025 12:07
@maintainer-s-little-helper

This comment was marked as outdated.

@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-sign-off The author needs to add signoff to their commits before merge. label May 27, 2025
@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from af7c346 to 9967569 Compare May 27, 2025 12:07
@maintainer-s-little-helper

This comment was marked as outdated.

@joamaki joamaki removed the dont-merge/needs-sign-off The author needs to add signoff to their commits before merge. label May 27, 2025
@joamaki
Copy link
Contributor Author

joamaki commented May 27, 2025

/test

@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from 9967569 to 9b38ae1 Compare May 27, 2025 15:01
Copy link
Contributor

@marseel marseel left a comment

Choose a reason for hiding this comment

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

nice, thanks!

joamaki added 7 commits May 29, 2025 10:41
The default testing.ObjectTracker that comes with client-go does
not properly implement the Watch() method:

  1) Does not support watching from a specific ResourceVersion
  2) Does not support multiple concurrent Watch() calls
  3) Does not support FieldSelector

This has been an ongoing pain as all the testing code needs to
make sure the implementation does not call Watch() too early.
This has required either populating the ObjectTracker before
starting the implementation or synchronizing with the implementation
to add objects only after Watch() has been called (e.g. db/initialized
or k8s/wait-watchers).

This commit implements a StateDB based ObjectTracker that properly
implements Watch() and FieldSelector.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
With the new fake client object tracker we no longer need to synchronize
with the reflectors before adding objects, so we can remove db/initialized.

Interestingly enough this change triggered the goleak to hit the workqueue
goroutine leak from Resource[T]. We don't have a way for waiting for that
background goroutine to exit so we'll just need to ignore it the same way
pkg/k8s/resource/resource_test.go does.

Fix the node name in hostport.txtar now that FieldSelector is implemented.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
No need to wait for watchers anymore so remove db/initialized calls
from tests.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
Now that we're using our own object tracker the Tracker() method cannot be used
as that returns the wrong object tracker. It anyway makes more sense to go via the
typed API.

Fix the Resource[T] tests to not use Tracker() and also not to use ResourceVersion
as that's now correctly populated by the object tracker.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
With the proper object tracker we no longer need this.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
Since we're using Tracker() method in bunch of tests make it point
to our ObjectTracker. Unfortunately there's no clean way to do this
so I need to just play tricks with unsafe.Pointer. At least the result
can be validated.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
As db/initialized is not necessary anymore just for waiting for reflector/informer
to sync, remove remaining uses of it.

Fix the remaining field selector issues.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki joamaki force-pushed the pr/joamaki/statedb-object-tracker branch from 9b38ae1 to d523bb3 Compare May 29, 2025 08:43
@joamaki
Copy link
Contributor Author

joamaki commented May 29, 2025

/test

@joamaki joamaki enabled auto-merge May 29, 2025 13:01
@joamaki joamaki added this pull request to the merge queue May 29, 2025
@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label May 29, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 29, 2025
@joamaki joamaki added this pull request to the merge queue May 29, 2025
Merged via the queue into cilium:main with commit d07f6cc May 29, 2025
67 checks passed
@joamaki joamaki deleted the pr/joamaki/statedb-object-tracker branch May 29, 2025 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/misc This PR makes changes that have no direct user impact.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants