-
Notifications
You must be signed in to change notification settings - Fork 88
Check vmciVersion between client and server. #1046
Conversation
I did the unit testing manually with managed plugin. Case1: set client VMCI version to "11" through environment variable when install the managed plugin
Case2: set client VMCI version in to "13" through environment variable when install the managed plugin
Case3: install managed plugin without setting environment variable
|
Please review it @msterin @shaominchen @shuklanirdesh82 |
esx_service/vmdk_ops.py
Outdated
@@ -104,6 +104,10 @@ | |||
MAX_SKIP_COUNT = 16 # max retries on VMCI Get Ops failures | |||
VMDK_ADAPTER_TYPE = 'busLogic' # default adapter type | |||
|
|||
#VMCI Version | |||
# !!! server side VMCI version, need to change according with client side version !!! | |||
VMCI_VERSION = "12" |
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.
minor: don't we need to set as 13
as we are approaching to 0.13 release?
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 does not really matter. To avoid confusion, I suggest naming it PROTOCOL_VERSION and assigning a value of 2 . It has nothing to do with release number
Also -please change comment to so something like Server side understand protocol version. If you are changing client/server protocol we use over VMCI, PLEASE DO NOT FORGET TO CHANGE IT FOR CLIENT in file <file name> !
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.
VMCI_VERSION is definitely confusing - we are not really dealing with different VMCI versions. PROTOCOL_VERSION is much better, but it's still a little bit confusing to me - what's exactly the "protocol"? When we say "If you are changing client/server protocol", we actually mean "If the version of your client plug-in doesn't match with the version of your server driver". So personally I feel we should not even use the term "protocol" here.
Since we are actually handling the version control between our client plugin and server driver, why can't we simply define a internal version number (name doesn't matter, just a property in build infrastructure), which should be compiled into client plugin as a constant, say CLIENT_VERSION, and into server driver as another constant, say SERVER_VERSION. When client sends requests to the server, the CLIENT_VERSION should be sent to the server over VMCI. And then server will compare the CLIENT_VERSION it receives with its own SERVER_VERSION, and decide if there's a version mismatch.
Comments?
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.
Done. Change the name to "PROTOCOL_VERSION".
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 don't see any feedback/response to my comments above :) @lipingxue @msterin
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.
Furthermore, I feel our client plugin and server driver are two independent components running in different user spaces. So it makes sense to maintain two separate version numbers. Also to improve the flexibility of inter-op, the version matching logic should consider backward compatibility, i.e. SERVER_VERSION should be compatible with lower CLIENT_VERSION. We may decide a version gap that we can support - let's say 3, then SERVER_VERSION 5 will work with CLIENT_VERSION 5, 4 and 3, but won't work with CLIENT_VERSION 2.
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.
@shaominchen - the only difference I see between the current code and your suggestion is that you want to rename the vmdk_ops.py:PROTOCOL_VERSION
to SERVER_PROTOCOL_VERSION
(note - it is NOT the version of server. It is the version of over-VMCI protocol the server expects) .
and to rename esx_vmdkcmd.go:protocolCurrentVersion
to clientProtocolVersion
.
Is it what you are saying ?
I agree, it makes the code easier to read and understand.
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'm fine with SERVER_PROTOCOL_VERSION and CLIENT_PROTOCOL_VERSION. The main point here is to distinguish the version numbers between client and server.
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.
OK. @lipingxue - please rename , unless you have some reasons not to (and then share them please )
plugin/config.json
Outdated
{ | ||
"name": "VMCI_VERSION", | ||
"description": "Request VMCI version", | ||
"value": "", |
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.
isn't it better to set default value for the version?
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.
actually - this one is ONLY for debugging and testing, so we can set it to something and make sure the versions mismatch handling is correct
@lipingxue -- please change name to something more obvious (that it's for test only) and add proper comment in description. Something like TEST_PROTOCOL_VERSION
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.
The client MUST have the version defined in the code. Please do not rely on the env variable for this
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.
Done. Change the name to "TEST_PROTOCOL_VERSION".
esx_service/vmdk_ops.py
Outdated
@@ -104,6 +104,10 @@ | |||
MAX_SKIP_COUNT = 16 # max retries on VMCI Get Ops failures | |||
VMDK_ADAPTER_TYPE = 'busLogic' # default adapter type | |||
|
|||
#VMCI Version | |||
# !!! server side VMCI version, need to change according with client side version !!! | |||
VMCI_VERSION = "12" |
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 does not really matter. To avoid confusion, I suggest naming it PROTOCOL_VERSION and assigning a value of 2 . It has nothing to do with release number
Also -please change comment to so something like Server side understand protocol version. If you are changing client/server protocol we use over VMCI, PLEASE DO NOT FORGET TO CHANGE IT FOR CLIENT in file <file name> !
esx_service/vmdk_ops.py
Outdated
version = req["version"] | ||
if version != VMCI_VERSION: | ||
if int(version) < int(VMCI_VERSION): | ||
reply_string = err("Client version ({0}) is lower than server version ({1}), please upgrade client.".format(version, VMCI_VERSION)) |
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.
Don't forget that it is the message the Docker user will see, so we need to be specific about where this message is coming from.
Something like "vSphere Docker Volume Service client version (1) is older than server version (2) , please update the client" and "vSphere Docker Volume Service client version (3) is newer than server version (2) , please update the server"
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.
Done.
esx_service/vmdk_ops.py
Outdated
if int(version) < int(VMCI_VERSION): | ||
reply_string = err("Client version ({0}) is lower than server version ({1}), please upgrade client.".format(version, VMCI_VERSION)) | ||
else: | ||
reply_string = err("Client version ({0}) is higher than server version ({1}), please upgrade server.".format(version, VMCI_VERSION)) |
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.
nit: if the order of {} is the same as the order of params, no need for numbers inside of {}
i.e. this would be also correct and more pythonish:
reply_string =
err("vSphere Docker Volume Service client version ({}) is newer than server version ({}) , please update the server".format(version, VMCI_VERSION))
plugin/config.json
Outdated
{ | ||
"name": "VMCI_VERSION", | ||
"description": "Request VMCI version", | ||
"value": "", |
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.
actually - this one is ONLY for debugging and testing, so we can set it to something and make sure the versions mismatch handling is correct
@lipingxue -- please change name to something more obvious (that it's for test only) and add proper comment in description. Something like TEST_PROTOCOL_VERSION
|
||
var versionEnv = os.Getenv("VMCI_VERSION") | ||
log.Debugf("Run get request: version=%s", versionEnv) | ||
// TODO: versionEnv need to read from enviroment variable when Nirdesh's Makefile is ready |
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.
please do not leave names in comments. It's better to open an issue and simply refer it.
plugin/config.json
Outdated
{ | ||
"name": "VMCI_VERSION", | ||
"description": "Request VMCI version", | ||
"value": "", |
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.
The client MUST have the version defined in the code. Please do not rely on the env variable for this
// TODO: versionEnv need to read from enviroment variable when Nirdesh's Makefile is ready | ||
// versionEnv = "13" | ||
var vmciVersion string | ||
if versionEnv == "" { |
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.
this should not be picked up from environment.
You should do something like
protocolVersion := os.Getenv("TEST_PROTOCOL_VERSION")
if protocolVersion == "" {
protocolVersion = <some hardcoded constant from const() section in the file>
}
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.
Done.
esx_service/vmdk_ops.py
Outdated
@@ -1469,6 +1473,15 @@ def execRequestThread(client_socket, cartel, request): | |||
reply_string = {u'Error': "Failed to parse json '%s'." % request} | |||
send_vmci_reply(client_socket, reply_string) | |||
else: | |||
logging.debug("execRequestThread: req=%s", req) | |||
version = req["version"] | |||
if version != VMCI_VERSION: |
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.
This is too strict expecting user to have exact same version of plugin and esx service.
I think we need "MIN_SUPPORTED_VERSION" and "MAX_SUPPORTED_VERSION" and need to maintain forward/backward compatibility for at lease 1 release. For e.g. for upcoming release, 0.13 Plugin should be compatible with 0.12 Server or vice-versa.
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.
currently protocol version IS NOT a release version and DOES NOT change with tagging or releases. It is a hardcoded (on both sides) version , and if it mismatches CURRENTLY we just decline. If/when we change the protocol and support mutli-protocol server , we will adjust accordingly
Check vmcVersion between client and server. Check vmciVersion between client and server. Add enviroment variable "VMCI_VERSION" in config.json file and some minor change. Change the default debug level back to "INFO". Small fix.
6a9207b
to
6a363fa
Compare
Address comments from Mark. Address comments from Mark. Remove unused code. One more fix.
6a363fa
to
b9ddce5
Compare
Comments have been addressed, please take a look again. @msterin @shaominchen @shuklanirdesh82 |
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.
Looks good. A couple of nits. One (remaining) question is - how it is going to behave if the curent code (with no version support) works vs. the new code (with version support). Will it fail - which is OK as long as it's clear what to do ?
plugin/config.json
Outdated
}] | ||
}, | ||
{ | ||
"name": "TEST_PROTOCOL_VERSION", |
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.
nit (since it's not for customers) Can we stick with VDVS_ as a prefix for all keys ?"
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.
Done.
maxRetryCount = 5 | ||
commBackendName string = "vsocket" | ||
maxRetryCount = 5 | ||
protocolCurrentVersion = "2" |
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.
Please add the comment similar to the one you've added on the server side
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.
Done.
) | ||
|
||
// A request to be passed to ESX service | ||
type requestToVmci struct { | ||
Ops string `json:"cmd"` | ||
Details VolumeInfo `json:"details"` | ||
Version string `json:"version"` |
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.
so will it break compat with existng version ? Do you think an optional "version" is better, and the lack of version indicates V1 ?
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.
Done.
esx_service/vmdk_ops.py
Outdated
#VMCI Version | ||
# !!! server side VMCI version, need to change according with client side version !!! | ||
VMCI_VERSION = "12" | ||
# Server side understand protocol version. If you are changing client/server protocol we use |
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.
Personally I still feel "changing client/server protocol we use over VMCI" is a little bit confusing. As I have already commented in my previous comments, I suggest to use CLIENT_VERSION in VM plugin, and SERVER_VERSION in ESX driver. Please see my previous comments for more detail.
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.
"VMCI_VERSION" has been changed to "PROTOCOL_VERSION". I think both the client and server side use the "PROTOCOL_VERSION" is clear enough.
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 actually with Sam here. Technically, there is no difference. Clarity-wise, with consts named properly (SERVER_PROTOCOL_VERSION and clientProtocolVersion) it is really much easier to understand
Added code to handle the case that client does not have version(v1 client), and do the test manually.
|
Address more comments from Mark. Small fix.
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 for addressing my comments.
A fresh nit (for the fresh code), but main request is to rename the vars per @shaominchen suggestion.
Other that that, LGTM
esx_service/vmdk_ops.py
Outdated
"please update the server.".format(version, PROTOCOL_VERSION)) | ||
send_vmci_reply(client_socket, reply_string) | ||
else: | ||
reply_string = err("vSphere Docker Volume Service client is too old, and cannot talk to server with version ({}), " |
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.
nit: can it be combined with line 1481 ?
Something lie "if verion not in req. or int(version) < int(clientVersion) { ... } else if ...
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.
The error message vSphere Docker Volume Service client version ({}) is older than server version ({})
need to fill the client version. If client is too old (V1 client), there is no version available. Should we show the client version as None or show different error message as I did in the current code?
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 think both approaches are fine (which is why it is a nit :-)).
My preference is to have the same message , and instead of "None" show ("1") since we start counting from 2 :-)
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.
ok, got it. Will address it.
maxRetryCount = 5 | ||
// Server side understand protocol version. If you are changing client/server protocol we use | ||
// over VMCI, PLEASE DO NOT FORGET TO CHANGE IT FOR SERVER in file <vmdk_ops.py> ! | ||
protocolCurrentVersion = "2" |
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 do agree with @shaominchen , calling clientProtocolVersion makes it much easier to comprehend
Address additional comments from Mark and Sam. Small fix.
@msterin @shaominchen I have address your comments, please take a look. |
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.
Looks good. Sorry, last comment related to rename - it has to be done for the 'version' var on the server as well. Just name it 'client_protocol_version'. A couple of small nits also in the comments
esx_service/vmdk_ops.py
Outdated
version = req["version"] if "version" in req else "1" | ||
logging.debug("execRequestThread: version=%s", version) | ||
if version != SERVER_PROTOCOL_VERSION: | ||
if not version or int(version) < int(SERVER_PROTOCOL_VERSION): |
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.
version is guaranted to be set in L1478, no need to do if 'not version' here. Should be simple
`if int(version) < int(SERVER_PROTOCOL_VERSION)
esx_service/vmdk_ops.py
Outdated
@@ -1469,6 +1473,19 @@ def execRequestThread(client_socket, cartel, request): | |||
reply_string = {u'Error': "Failed to parse json '%s'." % request} | |||
send_vmci_reply(client_socket, reply_string) | |||
else: | |||
logging.debug("execRequestThread: req=%s", req) | |||
# If req from client does not include version number, set the version to "1" by default | |||
version = req["version"] if "version" in req else "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.
just to make all consistent - can you rename 'version' -> 'client_protocol_version' ?
then the comparison would be 'if client_version < SERVER_PROTOCOL_VERSION'
esx_service/vmdk_ops.py
Outdated
logging.debug("execRequestThread: version=%s", version) | ||
if version != SERVER_PROTOCOL_VERSION: | ||
if not version or int(version) < int(SERVER_PROTOCOL_VERSION): | ||
reply_string = err("vSphere Docker Volume Service client version ({}) is older than server version ({}), " |
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.
Also, SERVER_PROTOCOL_VERSION is int() already, isn't it?
I suggest setting client_protocol_version (L 1478) to int as well
client_protocol_version = int(req["version"] if "version" in req else 1
and droping int() conversion in other places
Address the comments from Mark to rename the variable. Small fix.
d08be68
to
6eee4b9
Compare
@msterin I have renamed the variable. Please take another look :) |
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.
Nice and clean! Thanks for addressing the comments.
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.
LGTM!
CI is failing with errors unrelated to this PR.
Merging. |
This PR includes:
Fixed #318