-
Notifications
You must be signed in to change notification settings - Fork 5.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
Proposal for meta-generator #1315
Conversation
4eeb69b
to
c63aeeb
Compare
14520b0
to
612e516
Compare
kubegen --apis-dir notpkg/apis --apis-dir pkg/notapis | ||
``` | ||
|
||
- run all code generators against discovered APIs |
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.
discovered api mean types.go
exists?
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.
No, I don't think it should since folks may want to break up a monolithic types.go file. I was thinking purely based off directory structure, and then the presence of +genclient
provide both as positional arguments. | ||
|
||
```sh | ||
kubegen apps apps/v1 apps/v1beta1 extensions extensions/v1beta1 |
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.
do you have to pass internal and external groups? Will conversions be created if you only pass the external groups? What about clientsets and informers?
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.
groups are always internal, external requires a version.
PTAL |
12c5fef
to
1e2780b
Compare
1e2780b
to
911955f
Compare
cc @kubernetes/sig-apps-api-reviews @kubernetes/sig-apps-feature-requests |
Mind taking a look at this? |
@BenTheElder @ixdy please take a look at bazel pieces. |
@thockin No, the goal is not to move the existing generators to a single binary. Existing Makefiles and build systems will continue to function without change.
The goal is to provided a simplified interface for running code generators so that folks building extensions don't need to spend hours reading about each of our code generators and writing and maintaining dozens of lines of bespoke Makefile logic. |
I see. Devil's advocate: If we linked all our generators into a single binary and made it single-pass we could:
A big part of the perf hit is parsing ~ the whole codebase multiple times. |
This is worth a prototype. This was not in our focus at all, but if your claims holds, it would be a great improvement. |
@thockin I like the idea. Though it wasn't the original focus, any area where we can simultaneously reduce both development complexity and build times seems like a good place to focus our efforts. I suggest we prototype performance optimizations after completing the MVP described in this proposal. I am guessing that doing so will require some restructuring of the code generator libraries to inject singleton instances of dependencies. |
The MVP exists with the shell scripts already. We need to prototype a binary which can launch the other generators. Command line is actually secondary for that. |
What is still required to get consensus on this?
Do you mean compiling them into a single binary is secondary? |
There is work to be done to make the generators work inside one binary (some preparations for that already merged, so it shouldn't be too hard). But to evaluate whether Tim's use-case has any chance to work out performance-wise (it would be fantastic for our tooling complexity), the actual command line is secondary. But: if the use-case "generate for the whole kube/kube repo" is feasible, it might have bigger influence on our generator command line: we have more than one clientset in the repo, i.e. we would need a way to specify that on a kubegen commandline, while sharing the gengo Universe (i.e. to avoid re-parsing for every clientset). |
Even if we reduced the Makefile to a single target that figured out what needed to be generated-for, it would be a HUGE reduction in complexity. |
Thanks @thockin and @sttts for the feedback. Your comments have been insightful and will help come up with an implementation that will result in better future iterations N+. Now that this proposal has been open for discussion for nearly 3 weeks without any comments suggesting significant changes in design or goals. Can we call this lazy consensus and assume that we will address additional things we discover as we implement V0 and then iterate? Is there anything we need to resolve that we can't iterate on after this is merged?
I suggest we worry about performance optimizations after we have a working implementation of the desired user experience.
We will want to get here eventually, but I would prefer launch something meeting the use case to reduce complexity for extensions (since they extension authors will not have already built out complex Makefiles that meet their needs). It sounds like there is enough complexity re multi-clientsets that we don't want to block starting development on issues related to this. |
I have no further opinion on this PR as-is :) |
It makes a big difference in scope and the command line interface. I don't think it's a good idea to leave this question open if we don't have a plan how to extend the tool towards that use-case. I am fine with starting small, but let's flash out a sketch how this "multi clientset" use-case can look like. Until that I am against calling the proposal ready. |
I don't have a great grasp of the details around multi-clientset. Can you elaborate? How does it change the interface for the command? What additional information is missing that will need to be present? |
Now the command does one clientset, i.e. all given API groups are put into one clientset. For the kubernetes/kubernetes use-case we need multiple sets of API groups and API directories. I could imagine this: kubegen \
internal --api-dir k8s.io/api --api-dir --target pkg/client pkg/apis apps/v1 apps/v1beta1 core/v1 \
versioned --api-dir k8s.io/api --target k8s.io/client-go/kubernetes apps/v1 core/v1 \
... This would also include that we detect overlapping directories for deepcopy, conversions, etc. (all those file which are created inside the api dirs) and avoid double-generation. |
I want to see a very minimal proof-of-concept of the multi-clientset idea to proof that the speed increase of not-reparsing 25 times pays out enough. If it does, it's awesome for Kubernetes itself. If not, we don't need that additional complexity in the CLI implementation. |
The multi-clientset as shown definitely muddies up the interface and seems like it is more complicated and harder to build consensus around. It is also trying to solve a different problem - speeding up Kubernetes builds vs improving development velocity by reducing complexity. I am worried that focussing on performance optimizations will keep us from being able to move forward on the original stated goal - make running code generators for extensions accessible to non-kubernetes-veterans. While I would love to reduce complexity in the main repo and support multi-clientsets, I don't have the domain expertise to drive such a thing. Why don't we agree that multi-client set is out of scope for v1 and revisit in the future. |
If our command line is extensible towards a multi-client use-case, I am fine with that plan. But I would like to keep that door open. IMO, using a multi-subcommand syntax the command line is not that bad. The question is whether the CLI library that we will use supports this. |
I think we have enough agreement on the details to green light development. We can leave the door open to adapting this proposal based on feedback given during development.
Lets just use one that does. (e.g. cobra)
Sure. As long as trying to do this doesn't block making progress on the stated goals and keep us from making any improvements. |
@pwittrock and I talked on slack of how to go forward with this. There was some misunderstanding about who does what and how the bigger use-case of multi-clientsets fits into the design proposal and its implementation plan. As far as I see, there are the following work items:
My plan is to do the most complicated one of (2), namely client-gen as a blueprint for the others ASAP, possibly this or early next week. I would be happy if @pwittrock or his colleagues can support with refactoring the other generators' When client-gen's Step 4 does not depend on (3) to be finished. For (1), here is an extension from the previous sketch that should unblock (4):
In other words: we define a separator
This way we can implement the single-clientset use-case soon'ish, with a feasible extension to multi-clientset later, without too much ugliness in the command line. Potentially, we will add more sub-commands to kubegen, especially we know that we need |
SGTM |
```py | ||
http_archive( | ||
name = "io_k8s_rules_go", | ||
url = "https://github.com/kubernetes/bazelbuild/releases/download/v1.8.0/rules_go-1.8.0.tar.gz", |
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.
is this a new repo? or is it a clone of something?
### Running the Bazel target | ||
|
||
```sh | ||
bazel run //:kubegen |
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.
having a separate bazel run
command means that you can't just do bazel build
and have it do the right thing.
for MVP this is fine, but you can certainly get more benefits by turning this into something more like a genrule
.
There are 2 methods for running kubegen | ||
|
||
- Directly through the kubegen command line by downloading the binary and running it from the project root | ||
- Through Bazel by adding rules to `WORKSPACE` and `BUILD.gazel` |
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.
typo: gazel
should be bazel
?
bazel run //:kubegen | ||
``` | ||
|
||
### Bazel options |
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.
by "options" I'm assuming you mean attributes of the kubegen
rule?
### Running the Bazel target | ||
|
||
```sh | ||
bazel run //:kubegen |
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.
one other thing that might be worth noting is that calling bazel run kubegen
may need to be followed by bazel run gazelle
or whatever, since source files may change.
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Stale issues rot after 30d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Rotten issues close after 30d of inactivity. Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
No description provided.