Skip to content

✨ v3: rewrite to work the same as kubernetes code-generator #107

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

Open
wants to merge 24 commits into
base: kcp-1.32.3
Choose a base branch
from

Conversation

xrstf
Copy link
Contributor

@xrstf xrstf commented Apr 29, 2025

Summary

This represents a major overhaul of the entire kcp code-generator. So much so that I think this warrants a jump to v3.

The main idea here is to align ourselves with the architecture and ways of thinking of the Kubernetes code-generator. Up until now our own code-generator was arguably simpler, but also more limited, making it harder to adopt new upstream changes.

Overview

From 10,000ft this PR

  • copies Kubernetes' client-gen, informer-gen and lister-gen 1:1 into this repository,
  • renames them to cluster-... to make the distinction from upstream clear and to allow users to download all generators (kube and kcp) into the same directory, if they wanted to,
  • painstakenly goes through all templates and adjusts them to follow the Kubernetes 1.32-style (i.e. use of generics) for all cluster code,
  • provides a new cluster_codegen.sh, our new equivalent of Kube's kube_codegen.sh,
  • refactors our own internal code generation to also use Kube's kube_codegen.sh.

Things of Note

Package naming

It turned out that kcp and the code-generator's examples use a fundamentally different directory structure (see the related commit in this PR). I can see value in both styles and I think we should support both.

For this reason I decided to take out some of the implicit Kubernetes logic ("magic" some might call it) and instead allow the user full control over the packages and directories. This means instead of --listers-name which might be appended to some other package name, users simply provide the full package and directory names for where they want the listers to be generated. There is still some defaulting, but only in the cluster_codegen.sh. If users choose to use the generator binaries manually, they would have to provide more explicit packages and directories.

Package Aliases

One downside of Kube's approach to generating code is that package aliases are mostly automatically generated, which yields ... sometimes unintuitive results. It would be possible to generate more "human-friendly" aliases, but since they are only of use and note within the generated code itself, I chose to accept my fate and the many super ugly aliases.

Fun fact: Upstream tries to get rid of hardcoded imports in the generator as much as possible, yet I would have tried the exact opposite and generate even more hardcoded imports. I think this stems from the fundamentally different view on code-generation: upstream seeing it as creating an AST and then rendering it as Go, I would have seen it more as "a Go file with placeholders". Again, I think both are valid, but since upstream so much favors dynamic imports, I also used them in many places, leading to even more ugly aliases 😁

Blind Spots

There is a good chance that there might exist some combination of API types and generator flags that produce incomplete output. I have mostly focussed on getting the examples and kcp to work, but if someone manages to introduce internal versions into CRDs, they might be SOL because the code-generator cannot handle these at the moment.

Protobuf

I kept out the prefersProtobuf part for now and am planning to introduce that in a standalone PR, purely in an attempt to keep this PR smaller.

Upgrading

I would strongly recommend users upgrading to v3 to use the cluster_codegen.sh from now on, just like upstream recommends kube_codegen.sh.

Interfaces and structs stay compatible and the package structure is too, so code using the generated code should not require adjustments.

Related issue(s)

Fixes #18

Release Notes

ACTION REQUIRED: kcp code-generator v3 overhauls the command line to be more in line with Kubernetes upstream; users are encouraged to use the new `cluster_codegen.sh` (similar to `kube_codegen.sh` from Kubernetes) from now on.

@kcp-ci-bot kcp-ci-bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2025
@kcp-ci-bot
Copy link
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@kcp-ci-bot kcp-ci-bot added dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 29, 2025
@xrstf xrstf force-pushed the rewrite-to-upstream branch from aa56fdf to 0663593 Compare April 30, 2025 07:48
@kcp-ci-bot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@kcp-ci-bot kcp-ci-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 30, 2025
@xrstf xrstf changed the base branch from kcp-1.31.6 to kcp-1.32.3 May 9, 2025 14:47
@xrstf xrstf removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 9, 2025
@kcp-ci-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from xrstf. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@xrstf
Copy link
Contributor Author

xrstf commented May 12, 2025

/test all

xrstf added 18 commits May 12, 2025 19:15
This

* makes the generated-by comment clearer to distinguish from k8s' tools
* allows our binaries to co-exist in the same directory as the k8s binaries

On-behalf-of: @SAP [email protected]
kcp uses an entirely different concept of placing the packages. Whereas the examples in this repo
follow a

/ <singlecluster>          <-- all single-cluster code
/ <base outputdir>
+-- clientset/versioned/   <-- cluster-aware clientset
+-- informers/
+-- listers/

structure, but in kcp it's

/ <singlecluster>
+-- clientset/
|   +-- versioned/     <-- single-cluster clientset
|        +-- cluster/  <-- cluster-ware clientset
+-- listers
+-- informers

Placing the cluster clientset right into the singlecluster clientset, but keeping the listers and
informers standalone (since there are no single-cluster listers and informers in the kcp SDK).

Making both structures possible would either require a bunch of magic, or some explicit, IMHO easier
to understand CLI flags to control exactly what you want to have happen. I have sacrified to a degree
the concept of "naming" a clientset and the "versioned" subdirectory, also because in kcp the
cluster-aware clientset doesn't itself contain a clientset/versioned/ subdirectory.

On-behalf-of: @SAP [email protected]
xrstf added 2 commits May 12, 2025 19:15
It seems even though we did generate the applyconfigurations package already, we never told the
kube-client-gen about it and so it never generated the ...WithApply variant with Apply and ApplyStatus
functions. That's what is causing this diff to be larger than expected.

On-behalf-of: @SAP [email protected]
@xrstf xrstf force-pushed the rewrite-to-upstream branch from 99b3bd9 to c9daefe Compare May 12, 2025 17:15
@xrstf
Copy link
Contributor Author

xrstf commented May 12, 2025

/test all

@xrstf xrstf force-pushed the rewrite-to-upstream branch from c9daefe to 3e1589b Compare May 12, 2025 17:19
Since most of the new code is copied straight from Kubernetes, I felt uncomfortable to relicense it
as Copyright KCP, so instead I chose to apply a dual-copyright. Ideally the KCP one should have been
after the Kubernetes line, but that is not possible with verify_boilerplate.py.

Since the examples are kcp-only, they got their own boilerplates. It felt weird to have the
generated code be dual-copyrighted.

On-behalf-of: @SAP [email protected]
@xrstf xrstf force-pushed the rewrite-to-upstream branch from 8586dc2 to a20e483 Compare May 12, 2025 18:13
@xrstf
Copy link
Contributor Author

xrstf commented May 12, 2025

/test all

disabling prealloc linter because its documentation states:

> IMPORTANT: we don't recommend using this linter before doing performance profiling.
> For most programs usage of prealloc will be a premature optimization.

On-behalf-of: @SAP [email protected]
@xrstf
Copy link
Contributor Author

xrstf commented May 12, 2025

/test all

@xrstf xrstf marked this pull request as ready for review May 12, 2025 18:43
@kcp-ci-bot kcp-ci-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 12, 2025
@xrstf xrstf requested review from mjudeikis and gman0 May 12, 2025 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cleanup generator code
2 participants