-
Notifications
You must be signed in to change notification settings - Fork 95
Confusing error message from volume.create when datastore is not writ… #718
Confusing error message from volume.create when datastore is not writ… #718
Conversation
…able - Addressed Mark's comments
@pdhamdhere : Can you verify this. All comments have been addressed. |
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 code seems to print the error message even if the RunCommand is successfull. Please take a look. Also - please mention how you tested it and cut--n-paste log fragment resulting from testing
else: | ||
logging.warning("Failed to initialize volume path %s", path) | ||
errMsg = "Failed to initialize volume path {0}".format(path) | ||
#creation of dockvols directory failed. |
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.
There is no need to duplicate the message. You can simply use
errMsg = "Failed to initialize volume path {0}".format(path)
logging.warning(errMsg)
logging.warning("Failed to create %s", path) | ||
return None | ||
logging.warning("Failed to initialize volume path %s", path) | ||
errMsg = "Failed to initialize volume path {0}".format(path) |
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.
There is no need to duplicate the message. You can simply use
errMsg = "Failed to initialize volume path {0}".format(path)
logging.warning(errMsg)
nit: Besides, I recall seeing the same message a few lines ago, You may want to reuse the format string (you can define it once in the beginning of the function)
errMsg = "{0} creation failed - Permission denied on {1}".format(DOCK_VOLS_DIR, datastore) | ||
else: | ||
logging.warning("Failed to initialize volume path %s", path) | ||
errMsg = "Failed to initialize volume path {0}".format(path) |
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.
won't it hit the 'else' clause and print this error message even when RunCommand was successful ? I think you need to have
elif rc == 0:
pass
somewhere
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.
Sorry, I missed out on this. Only tested wrong scenarios.
logging.warning("Failed to create %s", dock_vol_path) | ||
return None | ||
errMsg = None | ||
if rc == ERR_OSFS_MKDIR_READONLY: |
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.
Rather than special casing error codes, why not use existing library function to translate error code to string? I am not a python expert but tried following and seems to be fine;
os.strerror(13)
'Permission denied'
os.strerror(30)
'Read-only file system'
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.
good point. It also removes the need to have special case per failure
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.
Great point. Modified the code according to your suggestion. Using this, no special checks are required for error codes.
In the below example nfsstore-baominw1 is a read-only nfs datastore mounted on ESX host, so creation failed.
In the below example nfsstore-brandonn is a nfs datastore with no access permissions, so creation failed.
In the below example nfsstore-bdontu2 is a nfs datastore with full access, so it created successfully.
On ESX host, I can see the VMDK created.
|
if not os.path.isdir(dock_vol_path): | ||
# The osfs tools are usable for DOCK_VOLS_DIR on all datastores | ||
cmd = "{0} {1}".format(OSFS_MKDIR_CMD, dock_vol_path) | ||
rc, out = RunCommand(cmd) |
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.
Why did you delete this code? This need to exist. See #687
OSFS_MKDIR_CMD is used to create dock_vol_path and MKDIR_CMD is used to create Tenant folder.
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 didn't delete any code. It achieves the same functionality as before. I just remodified the code so that it looks simpler now.
if not os.path.isdir(dock_vol_path): | ||
# The osfs tools are usable for DOCK_VOLS_DIR on all datastores | ||
cmd = "{0} {1}".format(OSFS_MKDIR_CMD, dock_vol_path) | ||
rc, out = RunCommand(cmd) |
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 didn't delete any code. It achieves the same functionality as before. I just remodified the code so that it looks simpler now.
if rc != 0: | ||
logging.warning("Failed to create %s", path) | ||
return None | ||
rc, out = RunCommand(cmd) |
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.
If it is a dockvols creation, it sets the command to OSFS_MKDIR_CMD and if it is tenant creation, it sets the command to MKDIR_CMD. Once it exits the if condition, it will take the command and execute it.
My previous review, doesn't create execute OSFS command to execute dockvols directory. It uses mkdir instead. Fixed the code to make sure dockvols is created using OSFS and tenant directory is created using mkdir. Test steps: First created a tenant using admin CLI [root@promc-2n-dhcp105-41:/usr/lib/vmware/vmdkops/bin] ./vmdkops_admin.py tenant access add --name T11 --datastore nfsstore-final --rights create,delete,mou On docker host, executed the following command It created the volume successfully. Verifying the logs I was able to confirm that first it created dockvols using OSFS command and created a tenant using mkdir command. |
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 change needed below.
cmd = "{0} {1}".format(MKDIR_CMD, path) | ||
rc, out = RunCommand(cmd) | ||
if rc != 0: | ||
logging.warning("Failed to create %s", path) | ||
return None | ||
errMsg = "Failed to initialize volume path {0}".format(path) |
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.
Why not include error string here?
errMsg = "Failed to initialize volume path {0} : {1}".format(path, os.strerror(rc))
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 problem is mkdir is that it returns either 0 or 1. 0 on success and 1 on failure for any reason.
Inorder to simulate this condition, where it fails on creating a tenant and is successful on dockvol creation. I have changed the access permissions on dockvol.
For example, when I printed the rc, out values to log
[photon-new-1-type@nfsstore-thanks] [DEBUG ] ****rc: 1, out: mkdir: can't create directory '/vmfs/volumes/nfsstore-thanks/dockvols/T12': Permission denied
Here, it clearly shows the error statement but return code is 1 which stands for "Operation not permitted".
os.strerror(1)
'Operation not permitted'
For that reason, I just settled with a normal message without the reason.
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.
Why not then log "out" which already has error string?
Previously specific error message was not displayed on failure of tenant creation. This commit will fix it. Test steps:
root@photon-a4ZgLxlWh [ ~ ]# docker volume create -d=vmdk --name=vol1@nfsstore-new This is similar to one in https://github.com/vmware/docker-volume-vsphere/blob/master/esx_service/vmdk_ops.py#L175 where the whole error message is displayed. So followed the same style. I can also rip out the just the error reason. for example in mkdir: can't create directory '/vmfs/volumes/nfsstore-new/dockvols/T15': Permission denied, I can just print the error reason - Permission denied by using code out.split(':')[-1] but sometimes it might lead to index out of range errors when error reason is not specified. So went ahead with printing the whole error message which can be easy understood by the user. |
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
Handled both scenarios as outlined below:
datastore is not writable
permission denied to create dockvols directory in datastore.
This is extension to #705 and is part of fix for #568. Addressed Mark's comments over here.
+CC @pdhamdhere @msterin
osfs-mkdir -n returns different error codes when it is not able to create the dockvols directory in /vmfs/volumes/. It returns error codes 30 and 13 for scenarios 1 and 2 described above. These error codes are used to give a proper errorMsg to the user.