-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert client.List to use functional options #106
Conversation
@pwittrock what's our policy on breaking backwards compat (or incrementing major versions)? This ends up with a much more ergonomic interface, and while I'm generally loathe to break the compatibility, I think it ends up being much less verbose, and follows the "you don't have to care about what you're not using" principle better. |
@grantr new interface is nice UX wise, but can't get break the backward compatibility. @DirectXMan12 We haven't defined the policy yet and have not been versioning the lib yet (so far, the unsaid rule is not to break the API :)). Are there any good library projects we can take inspiration from wrt versioning/backward-compatibility aspect ? |
I think the backward compatibility policy dovetails with the dependency versioning story from #111. How much is controller-runtime a standalone library versus a private dependency of kubebuilder? From my perspective (of course 😸) I'd like kubebuilder to be the semantically versioned umbrella, with each release pinning projects that use it to a specific revision of controller-runtime. Then controller-runtime can remain unversioned or have a different versioning scheme, with the freedom to move quickly knowing that kubebuilder users won't accidentally upgrade. When users install a new version of kubebuilder, an upgrade procedure can point out or automatically fix incompatibilities. Anyone using controller-runtime directly is on their own fixing breaking changes, which is probably what they expect from an unversioned library. Maybe a release notes file in the repo could have a list of breaking changes to guide them. In lieu of the above, what about this until the next major "release" (in the semantic versioning sense):
That gives users a way to proactively migrate, and a clean upgrade story for those who did ( |
@grantr I we're aiming to set up a version policy (semver) and have a story mostly ironed out for kubebuilder versioning, so we should be able to tag first semver release, and then hypothetically make a breaking change, and then do a new major version. @droot a lot of them that I know do one of a few things: a) add in alternate names, like suggested by @grantr. This tends to result in a confusing mess if those are left to languish for too long (or sometimes even if they're not), from what I've seen. Of course, we'll want to avoid breaking changes in general, but I think we'll have a short period where we'll want to make one or two and do a few version revs, simply due to the nature of actually getting user feedback (i.e. option b above). As for |
Goal is to have controller-runtime a standalone library following proper semver style versioning scheme so that Kubebuilder generated projects are reliably depend on it. As @DirectXMan12 pointed out, we will soon move to the new world to achieve that goal because we were figuring out the dependency story for kubebuilder generated projects. We sort of have a proposal which will work.
Instead of pinning to specific revision (I am assuming you referring to SHA), we can pin the controller-runtime to a minor version (0.1.x say) in Kubebuilder projects so that we don't have to do Kubebuilder release for every patch version on controller-runtime.
Sounds reasonable. @DirectXMan12 will respond to your post soon. |
@grantr we have sorted out the versioning story for controller-runtime/tools and Kubebuilder now uses versioned pkgs of |
looks like it just needs a rebase to fix merge conflicts |
👍 Hoping to get back to this tomorrow! |
Rebased. |
/lgtm |
There's an issue with the fake client and this new style. Currently the fake client's This PR removes the ability of the user to provide a Is there a way to infer the GVK of the resource wrapped by a List object? |
/hold |
Yeah, you should be able to do similar logic to what we actually do in the client -- the |
Huh? Can you just call |
Oh true, that is possible. In practice that would be required for every call to |
I updated the fake client to no longer need |
Rebased to squash the fixup commits. |
func (c *fakeClient) List(ctx context.Context, opts *client.ListOptions, list runtime.Object) error { | ||
gvk := opts.Raw.TypeMeta.GroupVersionKind() | ||
func (c *fakeClient) List(ctx context.Context, obj runtime.Object, opts ...client.ListOptionFunc) error { | ||
gvk, err := apiutil.GVKForObject(obj, scheme.Scheme) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be possible to set the scheme for the fake client, otherwise the fake client might not work for some user resources. We should use this scheme if none is explicitly set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, though the fake client already restricts itself to scheme.Scheme
in its constructor
tracker := testing.NewObjectTracker(scheme.Scheme, scheme.Codecs.UniversalDecoder()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, ok. Let's do that in a follow-up PR then. Can you file an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#137. The workaround for now is to add custom types to scheme.Scheme
in an init function in the test file. See https://github.com/knative/eventing/blob/e6fb7df8f1b83b6e78f6639f7f7461ee75a9b196/pkg/controller/feed/reconcile_test.go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
Oh right, Prow isn't used here so Locally I'm consistently getting a different error related to the event recorder:
|
@droot @pwittrock we should switch to prow when we get a chance. |
I restarted the test. Let's see if it works, and file a bug about the flakes. Don't want to have any of those. |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: DirectXMan12, grantr The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/hold cancel |
Replaces: List(ctx, ListOptions, list) with: List(ctx, list, ...option) This matches the upcoming functional options signature of client.Delete. To use the previous builder options, use the UseListOptions functional option: lo := &client.ListOptions{} client.List(ctx, list, client.UseListOptions( lo.InNamespace(ns).MatchingLabels(labels) ))
The fake client now uses similar GVK detection code as the other implementations and no longer relies on the Raw object having a TypeMeta.
Now that the fake client no longer needs Raw, these tests can use typed instead of untyped List objects.
57c4ead
to
bf0795d
Compare
Hopefully the final rebase! |
@DirectXMan12 need another lgtm after rebase, please :) |
/lgtm |
Had a offline discussion with @droot, we probably should have something like this to not break existing users.
|
Convert client.List to use functional options
Replaces: List(ctx, ListOptions, list) with: List(ctx, list, ...option) This matches the upcoming functional options signature of client.Delete. To use the previous builder options, use the UseListOptions functional option: lo := &client.ListOptions{} client.List(ctx, list, client.UseListOptions( lo.InNamespace(ns).MatchingLabels(labels) )) Ported kubernetes-sigs#106 PR
Replaces: List(ctx, ListOptions, list) with: List(ctx, list, ...option) This matches the upcoming functional options signature of client.Delete. To use the previous builder options, use the UseListOptions functional option: lo := &client.ListOptions{} client.List(ctx, list, client.UseListOptions( lo.InNamespace(ns).MatchingLabels(labels) )) Ported kubernetes-sigs#106 PR
Replaces: List(ctx, ListOptions, list) with: List(ctx, list, ...option) This matches the upcoming functional options signature of client.Delete. To use the previous builder options, use the UseListOptions functional option: lo := &client.ListOptions{} client.List(ctx, list, client.UseListOptions( lo.InNamespace(ns).MatchingLabels(labels) )) Ported kubernetes-sigs#106 PR
Replaces:
List(ctx, ListOptions, list)
with:
List(ctx, list, ...Option)
This matches the functional options signature of
client.Delete
in #94.A few examples (I tried formatting these as a table but it wasn't wide enough):
Select all:
Filter by namespace:
Filter by namespace and labels:
To assemble a
ListOptions
with the builder methods or some other strategy, use theUseListOptions
functional option: