-
Notifications
You must be signed in to change notification settings - Fork 378
Versioned proto and golang package structure #195
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
Versioned proto and golang package structure #195
Conversation
Maybe I’m confused, but why submit your own PR instead of supplying feedback to the one I already submitted? |
I wrote my changes before seeing yours. It was less effort for me to simply
push an alternate PR for the code I had already written vs. rewrite my PR
as a list of suggestions. Feel free to incorporate changes from this PR to
maintain authorship.
…On Fri, Feb 16, 2018 at 9:01 AM, Schley Andrew Kutz < ***@***.***> wrote:
Maybe I’m confused, but why submit your own PR instead of supplying
feedback to the one I already submitted?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#195 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACPVLCuNEmOcMtdfd_1uNvrpgjg8Gw4tks5tVYpAgaJpZM4SIP5D>
.
|
Hi @jdef, Let's just go with yours :) |
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.
I am a bit troubled by the interaction between this change and the GetSupportedVersions
RPC. To me it seems very awkward to have to call v1.GetSupportedVersions to find out whether or not v1 is supported.
I imagine normally if you are going to have some mechanism to fetch the supported versions, you would put that RPC outside of the versioned namespace and make some guarantee that it won't change, but I think in our case, we have loaded enough other calls into the Identity service that just leaving it out of versioning is not practical.
So...do we still actually need the GetSupportedVersions call if we make each major version into its own package? If so, can we clarify the interaction?
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.
Hi @jdef,
As I addressed in #194, I am not sure that placing the generated language bindings in a versioned package path is the best solution.
Maintaining all previous versions at the HEAD of the repository would result in a convoluted generation process as well as questions about whether lib/go/csi/v2
is v2.0
, v2.1.5
, v2.3
, etc. One might assert that the Git tag could be used to access the specific version, but if that's the case I see no value in providing a versioned path structure.
People that wish to access older versions of the specification could do so by using git or GitHub's UI to fetch a specific tag or commit and manually copying the protobuf or language binding locally.
Additionally, I'm not sure that the following options are necessary:
option go_package = "csi";
option java_package="csi";
option csharp_namespace="csi";
It's not difficult to import a package with an alias in Go, Java, or C#, so I'm not sure it's necessary to bother worrying about stripping the version from the package of the language bindings.
Thanks for doing this!
csi.proto
Outdated
package csi; | ||
package csi.v1; | ||
|
||
option go_package = "csi"; |
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.
Hi @jdef,
Please consider adding the following after option go_package
:
option java_package="csi";
option csharp_namespace="csi";
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.
As mentioned later in this thread, I think this only makes sense to do once we're generating bindings within the spec repo for these langs, otherwise it may be difficult to predict the full impact of changes on bindings generated from the spec.
lib/go/Makefile
Outdated
@@ -76,10 +76,11 @@ export PATH := $(shell pwd):$(PATH) | |||
######################################################################## | |||
## BUILD ## | |||
######################################################################## | |||
CSI_GO := csi/csi.pb.go | |||
CSI_A := csi.a | |||
CSI_PROTO := ../../csi.proto |
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.
Hi @jdef,
If the language binding's path/package structure is going to be versioned then shouldn't csi.proto
as well?
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.
I believe this is necessary for C++ to version the .proto
file.
Hi @julian-hj, You make a good point regarding the |
AFAIK the intent is that GetSupportedVersions SHALL NOT ever change in a way that's breaking/incompatible with prior or future versions of the spec. This allows a CO to query any plugin for its supported versions, regardless of the spec version that the plugin has implemented. If needed, we can break out GetSupportedVersions into a separate service but I'm not convinced that we're there yet, and I don't see the harm in leaving it where it is for the moment. That said, other message types are certainly expected to break across major spec revisions and namespacing the messages by major version gives us the freedom to both eliminate deprecated/obsolete things as well as restructure the RPCs to better fit the needs of the time.
I decided to place the generated bindings in a versioned package path because it allows CO and SP implementations to easily support multiple variants of CSI at the same time. Relying upon ONLY GH-versioning/repo-tagging for this leads to wacky solutions that don't necessarily scale well over time. Currently thinking about the best way to version the |
Maybe I am missing something, but to me, we lose the benefit of not changing GetSupportedVersions once we put it into a versioned namespace. Say theoretically, we have a Plugin that supports V2, and a CO that can consume either V1 or V2. The CO can't just call GetSupportedVersions anymore to find out which version of the client to use. It instead has to try to invoke "/csi.v1.Identity/GetSupportedVersions", and when that fails, it has to try to use the V2 service version. So most of the version support information will be determined by the success or failure of the RPC. I suppose a plugin author could choose to implement multiple identity service versions, just to be callable from incompatible COs, but I doubt any plugin author would bother. Does this make sense, or am I working from wrong assumptions? |
If GetSupportedVersions is wire compatible for prior and future versions of
the spec, what stops a v1 GetSupportedVersions call from working against a
server that was implemented against a v2 spec?
…On Wed, Feb 21, 2018 at 1:15 PM, Julian Hjortshoj ***@***.***> wrote:
Maybe I am missing something, but to me, we lose the benefit of not
changing GetSupportedVersions once we put it into a versioned namespace.
Say theoretically, we have a Plugin that supports V2, and a CO that can
consume either V1 or V2. The CO can't just call GetSupportedVersions
anymore to find out which version of the client to use. It instead has to
try to invoke "/csi.v1.Identity/GetSupportedVersions", and when that
fails, it has to try to use the V2 service version. So *most* of the
version support information will be determined by the success or failure of
the RPC.
I suppose a plugin author could choose to implement multiple identity
service versions, just to be callable from incompatible COs, but I doubt
any plugin author would bother.
Does this make sense, or am I working from wrong assumptions?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#195 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACPVLLhPQBkaodRXoI8kbVg0W7QaoSyCks5tXF0rgaJpZM4SIP5D>
.
|
@jdef Isn't the whole point of namespacing that we will create a separate set of RPCs? My read is that it wouldn't work because it is a different RPC. See the following diff in the grpc client code: |
Couldn't we leave |
I believe that since That said, I do have questions about this:
In order for this to work HEAD needs to be to maintain all previous versions of the generated bindings in separate folders. What is the plan for managing that? Would HEAD generate to Also should the current version be v1 or v02? |
* Versioned service presents RPC to discover CSI version. - GetSupportedVersions is now an unversioned RPC of Versioned. - Version is now an unversioned message. * Identity is no longer responsible for version negotiation. * Versioned is a mandatory service, like Identity.
I think you're right @julian-hj - it looks like gRPC IDL service names incorporate the protobuf package name: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#appendix-a---grpc-for-protobuf ... so perhaps it makes sense to extract
Current thinking is that HEAD would maintain (somewhere) a copy of the prior, backward-incompatible specs and would be able to generate all versions of all prior specs every time you run That said, if we want this mechanism to be more granular, as suggested by @akutz (for example, to support breaking spec variants prior to releasing v1) then we should attempt to solve this sooner than later. |
I added the option for Go package generation because we include Go bindings in this repo. C++ doesn't have an option like this, instead the C++ namespace is derived from the protobuf package name. No other languages have build files in this repo. Does it make sense to include protoc options for langs that we don't have a way to test/build in CI? |
We could but that kind of defeats the purpose of |
The new |
I would prefer to not take version negotiation out of the spec, otherwise this will be adding to what the SP needs to figure out for each CO. |
Having a SP expose a single version per endpoint does simplify things, but it also limits SP flexibility. |
I wasn't suggesting removal of version negotiation entirely. I was merely questioning whether or not GetSupportedVersions offers the CO any useful insights about version support that it cannot get by just calling Probe() with the version it will actually use. From the SP side, I don't think removing GetSupportedVersions() would really change anything except to reduce the number of RPCs (and now services) they have to implement by 1. Anyway, I hope we can all discuss it in a few minutes. |
message GetSupportedVersionsResponse { | ||
// All the CSI versions that the Plugin supports. This field is | ||
// REQUIRED. | ||
repeated Version supported_versions = 1; |
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.
Since we're changing this, we've found that we need to know what the min and max supported version so that this can be negotiated.
Resolved by #204 |
GetSupportedVersions
RPC moves fromIdentity
to a newVersioned
gRPC serviceVersioned
service and related proto messages. SHOULD never change across CSI revisions. MUST never change in ways that break backward/forward across any releases of CSIcsi/v1
subdirectorycsi
package prefix by defaultalternative to #194