-
Notifications
You must be signed in to change notification settings - Fork 41
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
Support different Kubernetes versions #3
Comments
Thanks for the copy. I don't know that I've thought enough about this have a strong opinion yet, but some combinations appeal more than others at the moment. What I find most tempting is a slight variation of your options: If you organized source in separate directories AND used cargo features to conditionally compile a particular version directory, then you could publish a single Downsides of that approach: still lots of duplicated code checked in, and cargo doesn't really have a way to enforce mutually exclusive features (other than, compile errors for name collisions). Would there be a default version bumped with every k8s release? That would be a semver breaking change almost every 3-4 months. I think this approach would work best if NOT specifying a default feature version and only removing old versions when you have sufficient cause for a semver breaking change or letting old versions live for many months as If you don't take a feature-flagged approach like that, I'd probably tend toward a branch-per-version (no preference on how to version the generator) and still publishing a single crate approach despite needing the clear warning for "not following semver". I think you could get by with promoting wildcard constraints like I struggle with the separate crate for every version. I see the semver advantage, and ~4 crates per year probably isn't too bad, but would you also name squat every possible |
Actually you don't want mutually exclusive features, because you do want to be able to support more than one target Kubernetes version in the same deps tree. Eg the user's application wants to use a Kubernetes 1.10 feature so it enables the You could have features support this scenario by having the Eg 1.10 added pub struct ConfigMap {
#[serde(rename = "apiVersion")]
#[serde(skip_serializing_if = "Option::is_none")]
pub api_version: Option<String>,
#[cfg(feature = "v1_10")]
#[serde(rename = "binaryData")]
#[serde(skip_serializing_if = "Option::is_none")]
pub binary_data: Option<::std::collections::BTreeMap<String, ::ByteString>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<::std::collections::BTreeMap<String, String>>,
} But even this has a problem. The operators crate that only enables the let cm = ConfigMap { api_version, data }; and now it doesn't compile because the compiler complains it doesn't initialize the It also has the problem of being impossibly complex to codegen automatically, especially given diffs like this between - pub subsets: Vec<::api::core::v1::EndpointSubset>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub subsets: Option<Vec<::api::core::v1::EndpointSubset>>, which would need to emitted like #[cfg(all(feature = "v1_7", not(any(feature = "v1_10"))))]
pub subsets: Vec<::api::core::v1::EndpointSubset>,
#[cfg(feature = "v1_10")]
#[serde(skip_serializing_if = "Option::is_none")]
pub subsets: Option<Vec<::api::core::v1::EndpointSubset>>, and would still break when 1.11 got released. So I don't think features can be made to work with this.
The kind of semver-breaking change I'm worried about is one that's unavoidably pushed down from upstream because it isn't a breaking change for them. That's why I used the example of changing the root namespace. Today the code generator strips the I can also imagine upstream changing the spec file in ways that doesn't affect the JSON serialization but does affect the Rust representation, eg by renaming a definition name, or adding or removing type aliases. So if such a backward-incompatible change can sneak into a
I wouldn't reserve them up-front, but yes, having to make four new subdirectories / branches + crates per year is definitely something I'm not enthused about. |
Great point I completely overlooked! I assume this is about allowing you to switch target k8s version at runtime. I struggled thinking through how I'd actually use this. Parsing a But I'm not yet fully persuaded that I'd use multi-target versioning it in kubeclient. I might even point to the fact that there doesn't seem to be a guarantee that any particular version of kubectl works with a different version of the API (I've been burned trying to use kubectl 1.9 on a 1.5 cluster). Still, I am intrigued by the idea that kubeclient could support multiple versions chosen at runtime, so definitely something here for me to keep chewing on.
I don't think you'd want to codegen it the way you described even if you could. Using your That said, you could simply version module namespaces. Separate crate per k8s version Separate module per k8s version
Yeah, I couldn't think of a concrete example. I feel like the example you gave could be worked around to avoid a breaking change until the next minor release, but it might be harder to maintain and there may be some other upstream changes that are harder to work around. Anyhow, it seems like this idea has less traction anyway. I find myself drawn to a single crate solution using modules to namespace different k8s API versions.. |
No, the situation is like the example I gave after that sentence. If a crate works with k8s version X or higher, it'll enable only that version's feature in its
You are always able to use an older API client with a newer apiserver, per their backwards-compatibility design. Fields added to existing objects are always optional for input (
That's a good idea. The modules should probably still be behind version-specific feature-gates so that the crate finishes compiling before the heat death of the universe. Let me think about this. |
@anowell You probably want to pin kubeclient-rs's dep of this repo to the previous commit (475b5b2) instead of master if you're not going to implement your own version-based features yet. |
Thx. I'll try to pin that soon, and then start working with your versions - hopefully in a couple weeks when I get past some work deadlines. |
I don't think there's a need to specialize on patch versions (1.7.2 vs 1.7.3), so just separate minor versions will be good enough (1.7.x vs 1.8.x).
Options for source organization:
Separate git branches for every version, including the code generator code.
Separate git branches for every version, and a separate branch for just the code generator code.
Separate directories in the same branch.
Options for publishing:
Multiple releases of a single crate -
k8s-openapi@1.7.*
,k8s-openapi@1.8.*
=
constraints with a specific patch version in their Cargo.toml.Separate crate for every version -
k8s-openapi-1-7@*
,k8s-openapi-1-8@*
👍 Access to a full crate versions allows semver-major changes, like changing the root namespace.
👍 For websites like crates.io or docs.rs that always default to showing the latest version, this makes it clear that older Kubernetes versions are supported.
👎 Lots of crate names.
cc @anowell
The text was updated successfully, but these errors were encountered: